C# 中socket根据Receive判断 TcpClient关闭连接的处理
C# 中socket根據Receive判斷 TcpClient關閉連接的處理
程序腳手架
在C#中,開發網絡應用,.Net Framework提供了各種便利。
- TcpListener用于服務端的監聽服務。
- TcpClient 用于網絡客戶端的便利開發
服務端和客戶端網絡連接后,進行數據通信。
其中服務端的接收程序框架如下:
while (true) {try{byte[] buffer = new byte[1024];int count = socket.Receive(buffer);// ......// 對接收到數據進行處理}catch (SocketException ex){int err = ex.ErrorCode;string str = socket.RemoteEndPoint.ToString();logger.Warn(str + " socketErrorCode: "+ err+ " -- exception: " + ex.Message);// ... ... 處理}catch(ObjectDisposedException closedException){logger.Error(closedException);// ... ... 處理break;}catch (Exception ex){logger.Error(ex);// ... ... 處理} }如果通信完成,需要結束,進行連接關閉。這是如果TcpClient進行關閉操作
tcpClient.Close(); tcpClient.Dispose();問題
這里期望在客戶端主動關閉后,服務端的socket會得到異常,然后在異常中進行后續處理,比如關閉服務端的對應socket,釋放分配的數據緩沖器……。
但發現了一個問題,客戶端TcpClient關閉后,接收處理線程并沒有異常拋出。
Receive函數
在Socket類中,Receive函數是一個阻塞操作,沒有數據receive到,則會阻塞。在接收到數據后,函數返回。
函數的說明如下:
當然可以設置receive的socket的receive-timeout;這樣在timeout后,會有SocketExcept發生。但這個異常并不是客戶端主動關閉或者網絡中斷。
//// 摘要:// 獲取或設置一個值,指定的后的時間量同步 Overload:System.Net.Sockets.Socket.Receive 調用將會超時。//// 返回結果:// 超時值(以毫秒為單位)。 默認值為 0,表示超時期限無限。 指定-1 還指示超時期限無限。//// 異常:// T:System.Net.Sockets.SocketException:// 嘗試訪問套接字時出錯。//// T:System.ObjectDisposedException:// System.Net.Sockets.Socket 已關閉。//// T:System.ArgumentOutOfRangeException:// 設置操作為指定的值是小于-1。public int ReceiveTimeout { get; set; }但是如果連接的客戶端主動關閉后,Receive函數會理解返回,而且返回值為0;這時就表示客戶端主動關閉了。
如果此時服務端不關閉,則對應的網絡連接處于 FIN_WAIT_2,CLOSE_WAIT狀態,如圖。
此時,服務端執行相應的socket關閉操作,就可以正常關閉連接了,否則,會有socket殘余留下。正常關閉下的結果,如圖:
總結
以上是生活随笔為你收集整理的C# 中socket根据Receive判断 TcpClient关闭连接的处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 黑科技!苹果新专利公布:可实现用户界面注
- 下一篇: C# v7.0版本中的local fun