4

我最近遇到了一个问题,即 TCP 服务器和客户端之间的中间链接已关闭。如果主服务器关闭,客户端需要连接到辅助服务器。当主服务器被买断时(例如 ..通过在终端上执行 ^C),TCP 关闭序列通过,客户端成功检测到断开的链接并尝试辅助服务器。但是,如果中间链接发生故障,客户端和服务器将不会意识到这一点。客户端可以检测到的唯一方法是它的 TCP 缓冲区何时被失败的“发送”操作填满。

作为对此的解决方案,使用了“TCP Keepalive”机制。这令人满意。

我的问题是“TCP Keepalive”是唯一的解决方案吗?

-帕布

4

5 回答 5

3

Keepalive 旨在处理所谓的半打开连接,当其中一方(通常是接收请求的服务器)不知道连接已断开时。客户端通常知道这一点,因为尝试向服务器发送请求会返回错误。

另一种选择是让监听器保持运行——当客户端检测到通信问题时,它只是尝试再次连接到服务器。服务器获取传入连接,检查是否来自相同的IP地址,如果是,则关闭打开的连接并建立新的连接。

但是如果客户端不知道连接断开并且服务器需要发送一些东西,那么服务器就没有办法重新建立连接,只能使用 TCP keepalive。

如果您不想使用keepalive,您可以使用应用程序级别的keepalive,例如发送应用程序特定的回显消息之类的东西。

于 2008-12-08T06:29:27.470 回答
3

我总是在应用程序级别处理这个问题,方法是扩展客户端和服务器之间通过 TCP 交谈的协议,使用“保持活动”-消息服务器和客户端每秒发送此消息,如果他们在 2 秒内没有得到“保持活动”-消息,连接可能已关闭。

TCP 的 Keep-Alive 机制很好,但很难使用,尤其是在不同平台上工作时。

于 2008-12-08T06:38:19.777 回答
3

Another solution is to use a heartbeat on a separate socket. That way you know almost immediately if the connection is down. This is useful when your primary connection is sending streaming data with no message boundaries.

于 2009-03-03T22:55:23.467 回答
1

您可以使用 TCP 的 Out-Of-Band 功能发明并实现您自己的 keep-alive,但我什至不会考虑这一点,除非您对已经为您构建的功能有一些重大问题。

于 2008-12-08T04:36:51.223 回答
1

Even without SO_KEEPALIVE set, if you try to send data along a dead tcp connection, it typically gets reset, or will eventually time out - either of these sends an error to the application eventually.

SO_KEEPALIVE means that this may be detected sooner on an otherwise idle connection. That's all.

于 2008-12-08T09:43:23.007 回答