侦听 TCP 服务器应用程序的以太网电缆拔出事件

本文关键字:出事件 以太网 TCP 服务器 应用程序 侦听 | 更新日期: 2023-09-27 18:32:02

我有一个C# TCP服务器应用程序。当 TCP 客户端与服务器断开连接时,我检测到它们断开连接,但如何检测电缆拔出事件?当我拔下以太网电缆时,我无法检测到断开连接。

侦听 TCP 服务器应用程序的以太网电缆拔出事件

您可能希望应用"pinging"功能,如果TCP连接丢失,该功能将失败。使用此代码将扩展方法添加到套接字:

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。即使您在 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 将触发套接字本身以检测网线的连接。