如果没有数据发送,TCP套接字会在一段时间后自动关闭吗?
我有一个客户端服务器的情况,客户端打开一个TCP套接字到服务器,有时很长一段时间会通过它们之间没有数据发送。 我遇到了服务器试图向客户端发送数据的问题,它似乎成功了,但客户端永远不会收到它,几分钟后,客户端看起来就会断开连接。
我是否需要每隔一段时间发送一些保活包?
编辑 :要注意,这是与同行在同一台计算机上。 计算机位于NAT后面,用于转发用于此计算机的一系列端口。 与服务器连接的客户端通过DNS打开连接。 即它使用mydomain.net&端口连接。
在Windows上,没有数据发送的套接字是许多应用程序出现问题的主要原因,必须正确处理。
问题是,SO_KEEPALIVE的周期可以在整个系统范围内设置(否则,默认是无用的两个小时)或者使用后面的winsock API。
因此,许多应用程序确实偶尔发送一些偶尔的数据字节(为了不被对等方忽略),只是为了在未收到ACK(在所有由层完成的重传和确认超时)之后声明断开网络层。
回答你的问题:不,插座不会自动断开。
但是,你必须小心上述问题。 更复杂的是,测试这种行为非常困难。 例如,如果您正确设置所有内容并且希望正确检测断开连接,则无法断开物理层来对其进行测试。 这是因为NIC会检测到载波丢失,并且套接字层将发出信号来关闭所有依赖于它的应用套接字。 测试它的一个好方法是连接两台带有三条支路和两个交换机的计算机,断开中间支路,从而防止载波丢失,但仍会断开机器的连接。
使用Keep-alive选项( Linux下的SO_KEEPALIVE )更安全,以防止因不活动而断开连接,但这可能会生成一些额外的数据包。
这个示例代码在linux下执行它:
int val = 1;
....
// After creating the socket
if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *)&val, sizeof(val)))
fprintf(stderr, "setsockopt failure : %d", errno);
问候。
TCP有一个超时,但您可以调整它,请参阅Socket类的SendTimeout
和ReciveTimeout
,但我怀疑这不是您的问题。 NAT路由器在将TCP连接从其端口转发表中删除之前,也可能具有TCP连接的到期时间。 如果在路由器的超时时间内没有流量通过,它将阻塞所有传入流量(因为它从内存中清除了转发信息,因此它不知道将流量发送到哪台计算机),而且传出连接可能会有一个不同的源端口,因此服务器可能无法将其识别为相同的连接。
上一篇: Do TCP sockets automatically close after some time if no data is sent?