【问题标题】:Socket remains connected after the remote computer closes it远程计算机关闭后套接字保持连接状态
【发布时间】:2016-02-16 21:15:17
【问题描述】:

我已经搜索过但没有解决我的问题。 我在本地主机上模拟 TCP 网络。服务器侦听端口,客户端连接到服务器。问题是当我通过客户端关闭套接字时,Socket.Connected 在服务器中仍然是 true。我需要知道客户端何时断开连接。

我想当我在客户端应用程序上调用Socket.Close 时,TCP FIN 数据包会发送到服务器,对吧?但好像没有。

你能给我一个解决方案吗?

附:我已经在关闭前调用了shutdown,但问题仍然存在。

【问题讨论】:

  • msdn.microsoft.com/en-us/library/wahsac9k%28v=vs.110%29.aspx 提到您应该在关闭之前调用 Shutdown()。
  • 这就是为什么您经常会发现格式为AreYouThere? - IAmHere 的数据包的原因,这些数据包没有做其他工作来检查通信是否仍然存在。另一种检测断开连接的方法是发送/接收期间的超时或异常。
  • @Sinatr 该模式因 Heartbleed 漏洞而出名。但我认为这对于崩溃很重要,kill -9 或者,好吧,关闭而不刷新。

标签: c# .net sockets tcp .net-4.5


【解决方案1】:

没有基于通知的方式来了解客户端是否已断开连接。这就是 tcp/ip 通信的本质。了解客户端是否已连接的常用方法是将数据写入客户端连接。如果出现错误,您可以猜测客户端已断开连接。您可以通过查找特定异常来简化启发式方法

【讨论】:

  • 嗯。我的印象是“没有基于通知的方式来知道客户端是否已断开连接”仅适用于崩溃等,但不适用于定期关闭(OP 正在尝试执行)。参照。 tcpipguide.com/free/t_TCPConnectionTermination-2.htm 用于一系列事件。在有序关闭中,“了解客户端是否断开连接的基于通知的方式”正在接收由关闭其连接的合作伙伴发送的 FIN。所以我必须假设出于某种原因,由于某种原因,没有执行常规的两侧关闭。
【解决方案2】:

虽然我没有使用 C# 进行套接字编程的实际经验,但 Socket.Close() 似乎不发送待处理数据,并且暗示不发送 FIN 数据包。 (在我看来这有点误导,因为Close 语义似乎与Stream.Close() 不同,后者调用Dispose(true),如果可能会尝试刷新。如果我错了,请纠正我。)

MSDN documentation 声明:

对于面向连接的协议,建议你调用 在调用 Close 方法之前关闭。这样可以确保所有数据 在关闭之前在连接的套接字上发送和接收。

如果您需要在没有先调用 Shutdown 的情况下调用 Close,您可以 确保排队等待传出传输的数据将由 将 DontLingerSocket 选项设置为 false 并指定非零 超时间隔。然后关闭将阻塞,直到发送此数据或 直到指定的超时到期。如果您将 DontLinger 设置为 false 并指定零超时间隔,关闭释放连接 并自动丢弃传出的排队数据。

【讨论】:

  • 哦 :-) 真可惜。我认为这很容易。
猜你喜欢
  • 1970-01-01
  • 2023-03-11
  • 2010-09-26
  • 1970-01-01
  • 2018-04-13
  • 1970-01-01
  • 2014-03-10
  • 1970-01-01
  • 2020-11-30
相关资源
最近更新 更多