打开的插座可以长时间放置而无需读取吗?

时间:2014-08-18 19:47:18

标签: linux sockets networking linux-kernel

我打开服务器的套接字然后睡觉,可能很长时间(几天)。这个过程是单线程的,所以我不能有专门用于管理套接字的线程。套接字应该保持活着。我假设服务器不发送任何需要客户端响应的消息。

问题是,假设套接字保持活着是否安全? Linux内核是否处理所需的TCP通信(例如,保持活动的数据包?)或是否正在从应用程序不时需要调用的套接字中读取?

如果服务器向客户端发送一些消息怎么办?我假设这些数据有一些缓冲区。它有多大,如何改变,如果它已满,会发生什么?

2 个答案:

答案 0 :(得分:4)

除了此处已经说过的内容之外,防火墙和NAT可能会在一段时间不活动后丢弃TCP连接。 TCP保持活动消息可能不足以使TCP连接保持活动状态。这就是为什么许多应用程序级协议具有应用程序级保持活动消息的原因(例如,我通常将我的ssh客户端配置为每30分钟发送一次保持活动消息,因为我的办公室NAT在1小时后丢弃TCP连接)。

换句话说,您的应用程序可能希望在可配置的时间内与远程对等方交换一些消息。

或者,使用特定于平台的套接字选项来启用TCP保持活动消息(SO_KEEPALIVE)并配置超时(Linux上为TCP_KEEPIDLE)。

答案 1 :(得分:1)

除非在客户端或服务器上配置了TCP keep-alives,否则连接将无限期保持打开状态,无需任何操作。

然而,这只是理论,除非你使用保持活动机制,否则你不能依赖于此。

让我们看一下TCP如何理解:通常TCP通信伙伴会发送一个FIN包来通知另一方面它将要关闭连接。除非发送/接收这样的包,否则双方都同意该连接是开放的。

但是,如果远程主机立即停机,让我们说是因为大停电了怎么办?或者因为管理员对端口进行防火墙处理(已经建立连接后)?

在这种情况下,其他连接伙伴不会注意到这一事实,并且读取操作将永远阻止。

为解决这个问题,引入了内核保持活动。使用这种机制,内核将可保存的包以可配置的间隔和周期发送到远程端,预计将通过ACK来回答。如果没有收到ACK,则内核假定远程端不再可用,并从相关套接字上的阻塞读取系统调用返回。