Clinet端不正常斷線時, Server端竟然不知道
生活随笔
收集整理的這篇文章主要介紹了
Clinet端不正常斷線時, Server端竟然不知道
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.?TcpClient.Connected:?屬性獲取截止到最后一次?I/O?操作時的?Client?套接字的連接狀態。
2.?TcpClient.Client.Connected:?屬性獲取截止到最后的?I/O?操作時?Socket?的連接狀態。Connected?屬性的值反映最近操作時的連接狀態。?如果您需要確定連接的當前狀態,請進行非阻止、零字節的?Send?調用。?如果該調用成功返回或引發?WAEWOULDBLOCK?錯誤代碼?(10035),則該套接字仍然處于連接狀態;否則,該套接字不再處于連接狀態。(MSDN上還有一段代碼)
3.?TcpClient.Available:?如果遠程主機處于關機狀態或關閉了連接,Available?可能會引發?SocketException。
4.?TcpClient.Client.Available:?如果遠程主機處于關機狀態或關閉了連接,則?Available?會引發?SocketException。
5.?Socket.Poll:??http://msdn.microsoft.com/zh-cn/library/vstudio/system.net.sockets.socket.poll(v=vs.100).aspx?(主要看Mode為SelectRead時Poll的返回值)
6.?有網友提供如下方法:
if?(s.Poll(-1,?SelectMode.SelectRead))
{
???int?nRead?=?s.Receive();
???if?(nRead?==?0)
???{
?????//socket連接已斷開
???}
} 接關閉軟件!?不能檢測出對方斷開連接(tcpClient.Close)!
2.?根據TcpClient.Client.Available后面的說明做驗證,發現當對方關閉了連接后獲取Available還是不回引發異常!
3.?經測試,上述網友提供的方法倒是可以檢測?物理網絡不通、對方關閉套接字?!但是網上有人說,即使網絡正常nRead也可能為0!這種情況我還沒有遇到過
不知道Client端已經不存在了, 笨笨的繼續傳遞資料給Client(是我笨吧…Orz) 當然會導致程式發生Exception………. Server真的會不知道嗎~~會他當然會知道 但是預設為兩小時後[1]~這早就發生Exception… 經過[1]中發現, 原來可以設定?Keep-Alive來保持Socket長連接, 並且偵測網路異常拋出Exception 當Client端發生不正常斷線時, Server端將會立刻知道~~~ Keep-Alive使用方法寫在Comment裡嚕~ 這裡紀錄一下
2.?TcpClient.Client.Connected:?屬性獲取截止到最后的?I/O?操作時?Socket?的連接狀態。Connected?屬性的值反映最近操作時的連接狀態。?如果您需要確定連接的當前狀態,請進行非阻止、零字節的?Send?調用。?如果該調用成功返回或引發?WAEWOULDBLOCK?錯誤代碼?(10035),則該套接字仍然處于連接狀態;否則,該套接字不再處于連接狀態。(MSDN上還有一段代碼)
3.?TcpClient.Available:?如果遠程主機處于關機狀態或關閉了連接,Available?可能會引發?SocketException。
4.?TcpClient.Client.Available:?如果遠程主機處于關機狀態或關閉了連接,則?Available?會引發?SocketException。
5.?Socket.Poll:??http://msdn.microsoft.com/zh-cn/library/vstudio/system.net.sockets.socket.poll(v=vs.100).aspx?(主要看Mode為SelectRead時Poll的返回值)
6.?有網友提供如下方法:
if?(s.Poll(-1,?SelectMode.SelectRead))
{
???int?nRead?=?s.Receive();
???if?(nRead?==?0)
???{
?????//socket連接已斷開
???}
} 接關閉軟件!?不能檢測出對方斷開連接(tcpClient.Close)!
2.?根據TcpClient.Client.Available后面的說明做驗證,發現當對方關閉了連接后獲取Available還是不回引發異常!
3.?經測試,上述網友提供的方法倒是可以檢測?物理網絡不通、對方關閉套接字?!但是網上有人說,即使網絡正常nRead也可能為0!這種情況我還沒有遇到過
不知道Client端已經不存在了, 笨笨的繼續傳遞資料給Client(是我笨吧…Orz) 當然會導致程式發生Exception………. Server真的會不知道嗎~~會他當然會知道 但是預設為兩小時後[1]~這早就發生Exception… 經過[1]中發現, 原來可以設定?Keep-Alive來保持Socket長連接, 並且偵測網路異常拋出Exception 當Client端發生不正常斷線時, Server端將會立刻知道~~~ Keep-Alive使用方法寫在Comment裡嚕~ 這裡紀錄一下
| ? | using?System.Net.Sockets; using?System.Net; public?class?ServerSocketObject { ????public??Socket ClientToServerSocket; ????private?Socket ListenSocket; ????private?IPEndPoint ServerIPEndPoint; ????public?ManualResetEvent BeginAccpetControl=new?ManualResetEvent(false); ????//========================== ????private?Boolean IsBeginAccept =?true?; ????public?List<byte> Reply_Message =?new?List<byte>(); ????public?ServerSocketObject() ????{ ????????string?LocalIP = Dns.GetHostByName(Dns.GetHostName()).AddressList[0].ToString(); ????????ServerIPEndPoint =?new?IPEndPoint(IPAddress.Parse(LocalIP), 2266); ????????ListenSocket =?new?Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); ????????ListenSocket.Bind(ServerIPEndPoint); ????????ListenSocket.Listen(1);??//ip pool 設為 1 ????????ListenSocket.IOControl(IOControlCode.KeepAliveValues, KeepAlive(1, 1000, 1000),?null);? ????????//將這個Socket使用<b style="background: rgb(255, 102, 255); color: rgb(0, 0, 0);">keep</b>-alive來保持長連線 ????????//KeepAlive函數參數說明: onOff:是否開啟<b style="background: rgb(255, 102, 255); color: rgb(0, 0, 0);">Keep</b>-Alive(開 1/ 關 0) , ????????//keepAliveTime:當開啟<b style="background: rgb(255, 102, 255); color: rgb(0, 0, 0);">keep</b>-Alive後經過多久時間(ms)開啟偵測 ????????//keepAliveInterval: 多久偵測一次(ms) ????} ????private?byte[] KeepAlive(int?onOff,?int?keepAliveTime,?int?keepAliveInterval) ????{ ????????byte[] buffer =?new?byte[12]; ????????BitConverter.GetBytes(onOff).CopyTo(buffer, 0); ????????BitConverter.GetBytes(keepAliveTime).CopyTo(buffer, 4); ????????BitConverter.GetBytes(keepAliveInterval).CopyTo(buffer, 8); ????????return?buffer; ????} ????public?void?BeginAccept() ????{ ????????while?(IsBeginAccept) ????????{ ????????????BeginAccpetControl.Reset(); ????????????ListenSocket.BeginAccept(new?AsyncCallback(BeginAcceptCallBack), ListenSocket); ????????????BeginAccpetControl.WaitOne();?//等待Clinet... ????????} ????????//=================== ????} ????private?void?BeginAcceptCallBack(IAsyncResult state) ????{ ????????Socket Listener = (Socket)state.AsyncState; ????????ClientToServerSocket = Listener.EndAccept(state);?//Client連線成功 ????????ClientToServerSocket.BeginReceive(buffer, 0, BufferSize, 0,?new?AsyncCallback(ReceivedCallBack), ClientToServerSocket);? ????????//連線成功後 開始接收Server所傳遞的資料 ????????BeginAccpetControl.Set(); ????} ????private?void?ReceivedCallBack(IAsyncResult ar) ????{ ????????Socket state = (Socket)ar.AsyncState; ????????if?(state.Connected ==?true) ????????{ ????????????try ????????????{ ????????????????int?bytesRead = state.EndReceive(ar); ????????????????if?(bytesRead > 0)?//當 bytesRead大於0時表示Server傳遞資料過來 等於0時代表Client"正常"斷線 ????????????????{ ????????????????????for?(int?num = 0; num < bytesRead; num++) ????????????????????{ ????????????????????????Reply_Message.Add(buffer[num]);?//收集資料 ????????????????????} ????????????????????state.BeginReceive(buffer, 0, BufferSize, 0,?new?AsyncCallback(ReceivedCallBack), ClientToServerSocket); ????????????????} ????????????????else ????????????????{ ????????????????????//處理Client端"正常"斷線的事件 ????????????????} ????????????} ????????????catch?(Exception ee) ????????????{ ????????????????//這裡就是當設定好<b style="background: rgb(255, 102, 255); color: rgb(0, 0, 0);">Keep</b>-alive後, 假設Clinet端發生"不正常斷線(網路異常)"時, 將會 ????????????????//跑進來這個Exception裡,再加以處理 ????????????????state.Shutdown(SocketShutdown.Both); ????????????????state.Close(); ????????????} ????????} ????????else ????????{ ????????????IsConntect =?false; ????????????state.Close(); ????????} ????} } |
總結
以上是生活随笔為你收集整理的Clinet端不正常斷線時, Server端竟然不知道的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Http Clinet使用
- 下一篇: debian 显示器使用自定义分辨率