3
votes

I write a comunication program with c/s mode in C# ,server and client program on different computer. Today after client progarm connected to server progarm ,then I pulled out cable from network adapter (after this , client and server program didn't do anything), stranger thing happened. I found out socket of server program still keep connected status. and I use command "netstat -a -n" to retrieve network information ,and get information like following :

TCP 192.168.1.2:3645 192.168.1.3:1863 ESTABLISHED

192.168.1.2 (Server IP Address) 192.168.1.3 (Client IP Address)

Do anyone know the reason ? how to solve this problem . I wanna how server program can receive the event and close the socket when network cable of client computer has been pulled out.

Please give me some advices or solutions.

Thanks

3
remember, socket.Connected (or IsConnected, I forget) will only tell you the socket status after the last command. So if your last command was successful, it will return true. If you then pull out the cable, it will continue to be true, until you try to use it and something fails.NibblyPig

3 Answers

5
votes

I think it can be solved by using TCP keepalive. refrencehttp://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html

after connecting , set socket keepalive property . msdn say this switch default status is off , if set keepalive to on , socket will check the network status automaticly , and first check time is 2 hours after last operation on socket. but the time can be adjsut to short . then after first check , socket will servral times. if connection is down or died, socket will throw exception .

C# Source:

    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);

I have checked. It's running ok.

3
votes

You can't. The only reliable way to check connected status is to send data over the wire, so: Deal with connection failures during send/receive, and, optionally, periodically check for connection status by some form of ping, if you want connection status during idle periods.

-1
votes

Im a bit unsure but if you try to read data from the socket after you pulled the cable it will tell you that its not connected any more..