Listening for an Ethernet Cable Unplugging Event for a TCP Server Application

余生长醉 提交于 2019-12-04 03:40:44

问题


I have a C# TCP server application. I detect disconnections of TCP clients when they disconnect from server but how can I detect a cable unplug event? When I unplug the ethernet cable I can't detect the disconnection.


回答1:


You might want to apply "pinging" functionality, that will fail if there is TCP connection lose. Use this code to add extension method to Socket:

using System.Net.Sockets;

namespace Server.Sockets {
    public static class SocketExtensions {
        public static bool IsConnected(this Socket socket) {
            try {
                return !(socket.Poll(1, SelectMode.SelectRead) && socket.Available == 0);
            } catch(SocketException) {
                return false;
            }
        }
    }
}

Method will return false if there is no connection available. It should work to check if there is or no connection even if you had no SocketExceptions on Reveice / Send methods. Bear in mind that if you had exception that had error message that is related to connection lose, then you don't need check for connection anymore.
This method is meant to be used when socket is looks like connected but might be not like in your case.

Usage:

if (!socket.IsConnected()) {
    /* socket is disconnected */
}



回答2:


Try the NetworkAvailabilityChanged event.




回答3:


I found this method here. It checks the different states of the connection and signals a disconnect. But does not detect an unplugged cable. After a further search and trial and error this is how I solved it finally.

As the Socket parameter I use on the server side the client socket from the accepted connection and on the client side the client that connected to the server.

public bool IsConnected(Socket socket)    
{
    try
    {
        // this checks whether the cable is still connected 
        // and the partner pc is reachable
        Ping p = new Ping();

        if (p.Send(this.PartnerName).Status != IPStatus.Success)
        {
            // you could also raise an event here to inform the user
            Debug.WriteLine("Cable disconnected!");
            return false;
        }

        // if the program on the other side went down at this point
        // the client or server will know after the failed ping 
        if (!socket.Connected)
        {
            return false;
        }

        // this part would check whether the socket is readable it reliably
        // detected if the client or server on the other connection site went offline
        // I used this part before I tried the Ping, now it becomes obsolete
        // return !(socket.Poll(1, SelectMode.SelectRead) && socket.Available == 0);

    }
    catch (SocketException) { return false; }
}



回答4:


This problem can also be resolved by setting the KeepAlive socket option like this:

   socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
   socket.SetKeepAliveValues(new SocketExtensions.KeepAliveValues
   {
       Enabled = true,
       KeepAliveTimeMilliseconds = 9000,
       KeepAliveIntervalMilliseconds = 1000
   });

These options can be tweaked to set how often checks are done to ensure the connection is valid. The sending of the Tcp KeepAlive will trigger the socket itself to detect the disconnect of the network cable.



来源:https://stackoverflow.com/questions/10298824/listening-for-an-ethernet-cable-unplugging-event-for-a-tcp-server-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!