Прослушивание события отключения кабеля Ethernet для приложения TCP-сервера

У меня есть серверное приложение С# TCP. Я обнаруживаю отключение клиентов TCP, когда они отключаются от сервера, но как я могу обнаружить событие отключения кабеля? Когда я отключаю кабель Ethernet, я не могу обнаружить отключение.


person sanchop22    schedule 24.04.2012    source источник


Ответы (4)


Возможно, вы захотите применить функцию «пингования», которая не сработает при потере TCP-соединения. Используйте этот код, чтобы добавить метод расширения в 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;
            }
        }
    }
}

Метод вернет false, если нет доступного соединения. Он должен работать, чтобы проверить, есть ли соединение или нет, даже если у вас не было исключений SocketException в методах Reveice/Send. Имейте в виду, что если у вас было исключение с сообщением об ошибке, связанным с потерей соединения, вам больше не нужно проверять соединение.
Этот метод предназначен для использования, когда сокет выглядит как подключенный, но может не быть как в вашем случае.

Применение:

if (!socket.IsConnected()) {
    /* socket is disconnected */
}
person moka    schedule 24.04.2012
comment
Нет, это не сработало. Я могу обнаружить событие отключения кабеля, но не могу обнаружить событие отключения клиента tcp. - person sanchop22; 24.04.2012

Попробуйте событие NetworkAvailabilityChanged.

person Eli Arbel    schedule 24.04.2012
comment
Это работало для отключения кабеля от сервера. Как я могу обнаружить отключение кабеля клиента? - person sanchop22; 24.04.2012
comment
@petre, ты не можешь. сервер не может знать, что физически происходит на клиенте. единственный способ - пропинговать его и посмотреть, отвечает ли он. или вы можете попробовать отправить сообщение от клиента, когда происходит событие CableUnplugged, чтобы сообщить об этом серверу ;-) - person Stefan Paul Noack; 24.04.2012

Я нашел этот метод здесь. Он проверяет различные состояния соединения и сигнализирует об отключении. Но не обнаруживает отсоединенный кабель. После дальнейших поисков и проб и ошибок я наконец решил это.

В качестве параметра Socket я использую на стороне сервера клиентский сокет из принятого соединения, а на стороне клиента клиент, который подключился к серверу.

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; }
}
person Mong Zhu    schedule 08.06.2016

Эту проблему также можно решить, установив параметр сокета KeepAlive следующим образом:

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

Эти параметры можно настроить, чтобы установить, как часто будут выполняться проверки, чтобы убедиться, что соединение действительно. Отправка Tcp KeepAlive запустит сам сокет, чтобы обнаружить отключение сетевого кабеля.

person Steve Wranovsky    schedule 08.05.2019