.net - 在 .NET 中检测客户端断开连接的最佳实践?

标签 .net tcp sockets disconnect

我正在用 C# 开发一个服务器,它只能接受一个客户端,我需要知道这个客户端何时断开连接才能接受另一个连接请求。

我使用的是第一个 Socket,它持续监听 Socket.BeginAccept 的连接请求并接受或拒绝客户端。当客户端被接受时,Socket.EndAccept 返回的新套接字用于客户端和服务器之间的通信。然后,服务器使用 Socket.Begin/EndReceive 等待来自客户端的命令并发送响应。服务器使用类似 Telnet 的协议(protocol),这意味着每个命令和每一行响应都必须以 \r\n 结尾。

为了检测客户端是否已断开连接,我安装了一个计时器,它每 500 毫秒向客户端发送一条空消息(“\r\n”)。如果客户端断开连接,则 Socket 会抛出异常。此异常由关闭当前 session 并接受新连接的服务器捕获。这个解决方案是健壮的,但意味着网络上不需要的流量,并且必须由客户端正确处理,客户端必须在获得实际响应之前过滤虚拟消息。

我尝试发送一个空缓冲区 (Socket.Send(new byte[1], 0, 0)),但似乎在服务器方向上不起作用->客户。

另一种解决方案可能是处理 Socket.EndReceive 返回 0 字节的情况。它适用于在“空闲”时间发生的断开连接的情况。但是,如果客户端在消息传输过程中断开连接,服务器并不总能看到它并无限期地等待。

我已经看过几个关于这个问题的线程和问题,但我从未见过任何好的解决方案。

所以我的问题是:在 .Net 中检测断开连接的最佳方法是什么?

最佳答案

唯一的其他选择是,如果它是 TCP,则让 TCP 每隔一段时间发送一个 keep-alive,它仍在轮询,例如您现在正在做的事情,但在 TCP 层处理,因此您的协议(protocol)不会'不需要知道。

然而,没有办法绕过轮询,因为如果不向其他客户端发送内容并获得响应,您就无法知道它是否仍处于连接状态。

通过状态数据包检查(例如标准 NAPT)进行通信时,无论如何也可能需要保持事件状态,以避免远程服务器因不活动而丢弃 session 。

关于.net - 在 .NET 中检测客户端断开连接的最佳实践?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1367319/

相关文章:

ios - iOS/Objective-C 中的 TCP 客户端 - 检查开放端口

c++ - 使用接受的连接作为套接字 (cpp-netlib)

c# - 用于网络通信的良好 EOF 字节

javascript - 如何从 socket.io 发出的回调中获取回调,然后将其返回给父函数

java - Java中准确检测socket发送失败

java - 如何找出 Netty 5 UDP 中哪个地址导致异常?

c# - 使用 TPL 时不会引发异常

c# - 带有表达式树的复杂构建器方法

c# - 如何使查找数组中第 N 个最频繁元素的过程更加高效和紧凑?

asp.net - DropDownListFor 并将我的 lambda 与我的 ViewModel 相关联