当TCP连接终止时,如何通知任何一方

本文关键字:通知 任何一方 何通知 连接 TCP 终止 | 更新日期: 2023-09-27 18:16:41

假设我们有一个使用。net TcpListener的基本TCP服务器和一个使用。net TcpClient的基本TCP客户端。

有哪些类型的连接终止,它们应该如何被检查和处理?

。客户端优雅地终止连接。通知服务器。

B。客户端与网络物理断开连接。服务器是如何知道的?

C。客户端程序在没有正常断开连接的情况下关闭。服务器是如何知道的?

服务器

。服务器优雅地终止连接。通知客户端。

B。服务器与网络物理断开连接。客户是怎么知道的?

C。服务器程序在没有正常断开连接的情况下关闭。客户是怎么知道的?

当TCP连接终止时,如何通知任何一方

情况A和C通过TCP报文通信,报文头设置FIN标志。它是由操作系统中的TCP/IP堆栈发送的,所以应用程序是否异常退出无关紧要。C的子情况下,操作系统也失败了,而不是像B一样。

情况B,当你失去沟通能力时,情况就更复杂了。如果故障是本地的(例如从WiFi接入点断开),那么连接的本地端将立即发现网络状态的变化,并可以推断连接已断开(但如果不清理,连接可以在短期中断中存活)。

如果连接正在主动传输数据,则确认将超时并导致重新传输尝试。可能对重传尝试设置了限制,从而导致错误。

如果没有流量,那么很可能在很长一段时间(多天)内未被检测到连接丢失。由于这个原因,TCP连接通常被配置为发送心跳数据包,心跳数据包必须被确认,并以与正常数据相同的方式检测重传尝试的失败。

简短的回答是:双方都不知道对方何时断开连接。直到有什么事让你知道。TCP不是一个物理连接,因此它依赖于某种类型的信号来确定状态。通常是通过检查连接或从另一端接收一个优雅的断开消息。检查连接的方法有很多种(轮询、超时、捕捉套接字异常等)。这取决于你使用的框架和你的需求。

如果您有资源来轮询,那么您可以每隔x秒轮询一次并检查状态。等。

检查此扩展方法。

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

基本上,如果连接是打开的并且有数据,socket.Poll()返回true,如果没有连接,它将返回true。套接字。Available将返回正在发送的字节数。如果是0,&&. poll()为真,则连接有效关闭。如果您试图遵循true/false,它会变得混乱,但这将以相当好的准确性返回。