У меня есть серверное приложение С# TCP. Я обнаруживаю отключение клиентов TCP, когда они отключаются от сервера, но как я могу обнаружить событие отключения кабеля? Когда я отключаю кабель Ethernet, я не могу обнаружить отключение.
Прослушивание события отключения кабеля Ethernet для приложения TCP-сервера
Ответы (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 */
}
Попробуйте событие NetworkAvailabilityChanged.
Я нашел этот метод здесь. Он проверяет различные состояния соединения и сигнализирует об отключении. Но не обнаруживает отсоединенный кабель. После дальнейших поисков и проб и ошибок я наконец решил это.
В качестве параметра 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; }
}
Эту проблему также можно решить, установив параметр сокета KeepAlive следующим образом:
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
socket.SetKeepAliveValues(new SocketExtensions.KeepAliveValues
{
Enabled = true,
KeepAliveTimeMilliseconds = 9000,
KeepAliveIntervalMilliseconds = 1000
});
Эти параметры можно настроить, чтобы установить, как часто будут выполняться проверки, чтобы убедиться, что соединение действительно. Отправка Tcp KeepAlive запустит сам сокет, чтобы обнаружить отключение сетевого кабеля.