【问题标题】:C - Detecting TCP socket broken connectionC - 检测 TCP 套接字断开的连接
【发布时间】:2020-07-04 13:52:30
【问题描述】:

我正在实现一个 tcp 服务器套接字。服务器与另一个设备中的客户端套接字通信。
问题是:如果连接突然断开(电缆被移除),recv() 函数没有返回。
我无法实现乒乓(心跳)机制,因为我不控制设备实现。
在网上搜索了一段时间后,我找到了这个教程:http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html
但是我不完全理解导师。如果我在 SO_KEEPALIVE、TCP_KEEPCNT、TCP_KEEPIDLE、TCP_KEEPINTVL 上调用 setsockopt(),导师说它将覆盖系统范围的变量(tcp_keepalive_time、tcp_keepalive_intvl、tcp_keepalive_probes)
它会影响其他线程/进程创建的其他套接字吗?

【问题讨论】:

  • setsockopt() 只影响你给它的套接字。所以不,在一个套接字上设置 keep-alive 值不会影响其他套接字或整个系统
  • 设置revc()的超时时间,查看文档
  • @Mannoj 您的链接没有任何相关性。如果您不这么认为,请解释。

标签: c++ c sockets network-programming


【解决方案1】:

TCP 没有提供很好的方法来检测未发送端的断开连接。如果设备使用的协议没有为服务器提供任何方法来检测断开的连接,则该协议已损坏。你所能做的就是实现接收超时,但这很糟糕。

协议是否有文档?它说要做什么?

【讨论】:

  • 协议定义了一条消息(KeepAlive 消息)。但在某些情况下,消息只是从设备发送的。通常,客户端连接到服务器后,服务器只是等待来自客户端的消息。我必须确定客户端是否仍然连接
  • @Joker 那么听起来你应该使用超时。
【解决方案2】:

TCP 保持活动功能确实允许您检测断开的连接。您需要为您的套接字显式启用它并更改默认值,以便它更早地检测到断开的连接,就像您的导师指示您的那样。

但我不完全理解导师。如果我在SO_KEEPALIVETCP_KEEPCNTTCP_KEEPIDLETCP_KEEPINTVL 上调用setsockopt(),导师说它将覆盖系统范围的变量(tcp_keepalive_time、tcp_keepalive_intvl、tcp_keepalive_probes) 它会影响另一个线程/进程创建的其他套接字吗?

不会,setsockopt 只会影响您作为参数传递给它的套接字。

【讨论】:

  • 请注意:我最近发现一些防火墙切断了连接,尽管设置了 tcp keep-alive 并且低于防火墙规则,所以它可能不是一个完整的解决方案...
  • @MarioTheSpoon TCP keep-alives 仍然检测到断开的连接。您正在谈论通过路由器保持连接打开的另一个问题。
  • 没错,只是想指出这一点,因为它毁了我的一位客户的一天(他错误地实施了重新连接,因为它永远不会发生):-)
  • @MarioTheSpoon 这不是第一次配置错误或不合规的网络硬件毁了某人的一天。这就是人们实现应用程序级心跳的原因 - 以解决此类硬件问题。
  • @MaximEgorushkin 我将您的答案标记为已接受。但还有一个问题:以前,如果我单独使用 recv(),当连接断开时,recv() 不会返回。但是当我用 SO_KEEPALIVE 设置sockopt() 时,recv() 在超时到期时返回。 recv() 对 SO_KEEPALIVE 有什么作用吗?
猜你喜欢
  • 2011-09-18
  • 2013-02-10
  • 2013-11-16
  • 2012-12-10
  • 1970-01-01
  • 2013-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多