[英]Can an open socket be left for a long time without reading from it?
我正在打开服务器的套接字,然后休眠,可能要花很长时间(几天)。 该进程是单线程的,所以我没有专用于管理套接字的线程。 套接字应保持活动状态。 我假设服务器不发送任何需要客户端响应的消息。
问题是,是否可以安全地假设套接字将保持活动状态? Linux内核是否处理所需的TCP通信(例如,保持活动的数据包?),或者不时需要应用程序从套接字读取?
如果服务器向客户端发送一些消息怎么办? 我假设有一些此类数据的缓冲区。 它有多大,如何更改,如果装满了怎么办?
除了此处已说过的内容外,一段时间不活动后,防火墙和NAT可能会断开TCP连接。 TCP保持活动消息的频率可能不足以使TCP连接保持活动状态。 这就是为什么许多应用程序级协议都具有应用程序级保持活动消息的原因(例如,我通常将ssh客户端配置为每30分钟发送一次保持活动消息,因为我的办公室NAT在1小时后会断开TCP连接)。
换句话说,您的应用程序可能希望在可配置的时间内一次与其远程对等方交换一些消息。
或者,使用特定于平台的套接字选项来启用TCP保持活动消息( SO_KEEPALIVE
)并配置超时(在Linux上为TCP_KEEPIDLE
)。
除非在客户端或服务器上配置了TCP保持活动状态,否则连接将无限期保持打开状态,而无需执行任何操作。
但这只是理论,除非您使用保持活动机制,否则您将不能依靠它。
让我们看一下TCP如何工作以了解这一点:通常,TCP通信伙伴将发送FIN
包以通知另一只手它将关闭连接。 除非将发送/接收此类程序包,否则双方都同意连接已打开。
但是,如果远程主机由于停电而立即关闭怎么办? 还是因为管理员对端口进行了防火墙保护(在建立连接之后)?
在这种情况下,另一个连接伙伴将不会注意到该事实,并且读取操作将永远被阻止。
为了解决这个问题,引入了内核保持活动。 使用这种机制,内核以可配置的时间间隔和周期将保持活动包发送到远程端,期望使用ACK
。 如果没有收到任何ACK
,则内核会假定远程端不再可用,并从阻塞相关套接字上的读取系统调用中返回。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.