简体   繁体   English

可以将打开的插座放置很长时间而不读取它吗?

[英]Can an open socket be left for a long time without reading from it?

I'm opening a socket to a server and then sleeping, possibly for a very long time (days). 我正在打开服务器的套接字,然后休眠,可能要花很长时间(几天)。 The process is single-threaded so I can't have a thread dedicated to managing the socket. 该进程是单线程的,所以我没有专用于管理套接字的线程。 The socket should stay alive. 套接字应保持活动状态。 I'm assuming the server does not send any messages for which a client response is required. 我假设服务器不发送任何需要客户端响应的消息。

The question is, is it safe to assume the socket will stay alive? 问题是,是否可以安全地假设套接字将保持活动状态? Does the Linux kernel handle the needed TCP communication (eg keep-alive packets?) or is reading from the socket required to be called by an application from time to time? Linux内核是否处理所需的TCP通信(例如,保持活动的数据包?),或者不时需要应用程序从套接字读取?

What if the server sends some messages to the client? 如果服务器向客户端发送一些消息怎么办? I'm assuming there is some buffer for such data. 我假设有一些此类数据的缓冲区。 How big is it, how it can be changed, and what happens if it is full? 它有多大,如何更改,如果装满了怎么办?

In addition to what has already been said here, firewalls and NATs may drop TCP connections after a period of inactivity. 除了此处已说过的内容外,一段时间不活动后,防火墙和NAT可能会断开TCP连接。 TCP keep-alive messages may be not frequent enough to keep TCP connections alive. TCP保持活动消息的频率可能不足以使TCP连接保持活动状态。 This is why many application level protocols feature application level keep-alive messages (for example, I normally configure my ssh client to send keep-alive messages every 30 minutes because my office NAT drops TCP connections after 1 hour). 这就是为什么许多应用程序级协议都具有应用程序级保持活动消息的原因(例如,我通常将ssh客户端配置为每30分钟发送一次保持活动消息,因为我的办公室NAT在1小时后会断开TCP连接)。

In other words, your application may like to exchange some messages with its remote peer once in a configurable while. 换句话说,您的应用程序可能希望在可配置的时间内一次与其远程对等方交换一些消息。

Alternatively, use a platform-specific socket option to enable TCP keep-alive messages ( SO_KEEPALIVE ) and configure the timeout ( TCP_KEEPIDLE on Linux). 或者,使用特定于平台的套接字选项来启用TCP保持活动消息( SO_KEEPALIVE )并配置超时(在Linux上为TCP_KEEPIDLE )。

Unless TCP keep-alives have been configured on the client or the server, the connection will stay open infinitely with no action required. 除非在客户端或服务器上配置了TCP保持活动状态,否则连接将无限期保持打开状态,而无需执行任何操作。

However this is just the theory, unless you are using a keep alive mechanism, you can't rely on this. 但这只是理论,除非您使用保持活动机制,否则您将不能依靠它。

Lets look on how TCP works to understand that: Normally a TCP communication partner will send a FIN package to notify the other hand that it is about to close the connection. 让我们看一下TCP如何工作以了解这一点:通常,TCP通信伙伴将发送FIN包以通知另一只手它将关闭连接。 Unless such a package will getting sent/received, both partners agree about that the connection is open. 除非将发送/接收此类程序包,否则双方都同意连接已打开。

However, what if the remote host just went down immediately, let's say because of a blackout? 但是,如果远程主机由于停电而立即关闭怎么办? Or because an administrator firewalled the port (after the connection has been established already)? 还是因为管理员对端口进行了防火墙保护(在建立连接之后)?

In such cases the other connection partner would not getting noticed about that fact and a read operation would block forever. 在这种情况下,另一个连接伙伴将不会注意到该事实,并且读取操作将永远被阻止。

To solve this problem, kernel keep alives were introduced. 为了解决这个问题,引入了内核保持活动。 Using this mechanism, the kernel sends keep-alives packages in configurable intervals and periods to the remote end, which are expected to get answered with an ACK . 使用这种机制,内核以可配置的时间间隔和周期将保持活动包发送到远程端,期望使用ACK If no ACK will getting received, the kernel assumes the remote end to be not available anymore and returns from blocking read system calls on the related socket. 如果没有收到任何ACK ,则内核会假定远程端不再可用,并从阻塞相关套接字上的读取系统调用中返回。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM