首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用TCP套接字处理客户端断开连接的最佳方法

问使用TCP套接字处理客户端断开连接的最佳方法
EN

Stack Overflow用户
提问于 2014-01-05 10:50:47
回答 3查看 1.6K关注 0票数 0

我设法创建了基本的远程管理工具,它工作得很好,我在c++中使用了基本的tcp套接字和多线程。这就像90%完成了几个我可以用来远程使用的功能,但我的软件没有任何东西可以检测客户端断开,除了当客户端手动关闭时,客户端将发送断开消息到服务器,但当断开发生时,当用户拔出网络或其他什么,什么是最好的方法是处理它,我正在寻找一个专业的方法来做到这一点,比如如果客户端断开连接,服务器将立即检测到哪个客户端断开。

EN

回答 3

Stack Overflow用户

发布于 2014-01-05 12:28:24

空闲TCP连接不必为要维护的连接发送任何数据。您尝试检测的场景称为“半开”连接。在史蒂文斯那本书的7.5章中有一个选项图表(在我的第186页)。最终结果是:

  1. 如果您正在积极发送数据,则连接将在等待来自远程系统的ack时超时(超时取决于系统,但通常在分钟范围内)。
  2. 如果您启用了keep-alives (并且它们得到了正确的支持),则系统将在2小时不活动后超时。来自远程系统的无响应将导致超时
  3. 如果您未启用保持连接,并且您没有发送数据,则无法检测丢失的客户端。

这意味着,如果你想在断开连接时相对快速地关闭连接,你需要添加你自己的方式。我通常会强制一方发送某种心跳。

票数 3
EN

Stack Overflow用户

发布于 2014-01-05 13:12:24

就像@EJP所说的,没有办法立即检测到硬断开,因为本地计算机无法看到网络上发生了什么,它只能看到它的传出TCP数据包不再被ACK。它无法知道缺少lack是由于临时问题(例如路由器超载丢失了一些数据包,或者以太网电缆被拔出,然后很快又重新插入)还是更持久的问题(例如远程计算机崩溃、永久断电或与网络断开连接)。

您可以做的是确保您的本地应用程序始终定期通过TCP套接字发送数据--要么是实际数据,要么是如果您没有任何实际数据要发送,则发送一些客户端知道要忽略的虚拟字节。这些“心跳消息”可以每分钟发送一次,也可以每隔几秒钟发送一次,这取决于您愿意为此使用多少额外带宽。

定期发送TCP数据将强制本地计算机的TCP堆栈监视与发送的数据包对应的ACK;如果未收到预期的ACK,它将重新发送数据包,并在几轮重新发送后放弃并关闭TCP连接。大多数TCP堆栈在几分钟内没有收到ACK后就会放弃。

如果“几分钟”对您来说还不够快,那么您可以要求远程程序每隔几秒钟向您的程序发送某种类型的数据,如果您至少(这么多秒)没有从客户端接收到任何数据,则强制关闭TCP套接字。请注意,根据您设置为超时的秒数,这可能会导致“误报”,即您的程序强制关闭实际上仍然有效但暂时停滞的TCP连接;这对于您的应用程序来说可能是可接受的,也可能是不可接受的。

票数 2
EN

Stack Overflow用户

发布于 2014-01-05 11:24:33

除非客户端正确关闭连接,否则您无法立即检测到它。您必须使用读取超时,并对send()或recv()返回的所有其他错误做出正确反应,即关闭套接字。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20929453

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档