2011-01-11 46 views
1

我在C#,服務器和客戶端程序中使用c/s模式在不同計算機上編寫通信程序。今天客戶端progarm連接到服務器progarm後,然後我從網絡適配器(此後,客戶端和服務器程序沒有做任何事情)拉出電纜,發生了陌生的事情。我發現服務器程序的socket仍然保持連接狀態。我用命令 「netstat的-a -n」 來獲取網絡信息,並獲取信息,如下列:如何在網絡電纜從網絡適配器斷開連接時獲取套接字的狀態

TCP 192.168.1.2:3645 192.168.1.3:1863 ESTABLISHED

192.168.1.2(服務器IP址) 192.168.1.3(客戶端IP地址)

有人知道原因嗎?如何解決這個問題呢 。 我想如何服務器程序可以接收事件,並關閉客戶端計算機的網線已拔出插座。

請給我一些建議或解決方案。

感謝

+0

記住,socket.Connected(或IsConnected,我忘了)只會告訴你最後一個命令後的套接字狀態。所以如果你最後的命令成功了,它將返回true。如果你拔出電纜,它將繼續是真實的,直到你嘗試使用它,並有什麼失敗。 – NibblyPig 2011-01-11 16:01:45

回答

4

我認爲這可以通過使用TCP keepalive來解決。 refrence http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html

連接後,設置套接字keepalive屬性。 msdn說這個開關的默認狀態是關閉的,如果設置保持打開,套接字將自動檢查網絡狀態,並且首先檢查時間是在最後一次對套接字進行操作後2小時。但時間可以縮短。然後在第一次檢查後,套接字將會保留時間。如果連接斷開或者死亡, 套接字將拋出異常。

C#來源:

uint dummy = 0; 
    byte[] inOptionValues = new byte[Marshal.SizeOf(dummy) * 3]; 
    //set keepalive on 
    BitConverter.GetBytes((uint)1).CopyTo(inOptionValues, 0); 
    //interval time between last operation on socket and first checking. example:5000ms=5s 
    BitConverter.GetBytes((uint)5000).CopyTo(inOptionValues, Marshal.SizeOf(dummy)); 
    //after first checking, socket will check serval times by 1000ms. 
    BitConverter.GetBytes((uint)1000).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2); 

    Socket socket = __Client.Client; 
    socket.IOControl(IOControlCode.KeepAliveValues, inOptionValues, null); 

我已經檢查。它運行正常。

-1

我是個有點不確定,但如果您嘗試拉電纜後從套接字讀取數據時,它會告訴你,它沒有連接任何更多..

+0

非常感謝。但我想趕上這個例外。因爲程序業務是:服務器向客戶端發送命令,並且clinet接收命令並執行它然後發回結果。服務器接收程序是異步的,所以當我拔掉電纜時,服務器無法收到任何數據。 – user571102 2011-01-11 15:43:33

+0

沒有一些代碼我不能幫你..但你必須在聽數據,這應該去的時候,電纜拉... – Peter 2011-01-11 15:52:33

2

你不能。 檢查連接狀態的唯一可靠方法是通過線路發送數據,因此:處理髮送/接收期間的連接失敗,以及可選地,通過某種形式的ping定期檢查連接狀態,如果您希望在閒置時連接狀態週期。