如果没有数据发送,TCP套接字会在一段时间后自动关闭吗?

我有一个客户端服务器的情况,客户端打开到服务器的TCP套接字,有时很长一段时间将通过它们之间没有数据发送。 我遇到了一个问题,服务器试图将数据发送到客户端,它似乎成功,但客户端从未收到它,几分钟后,它看起来像客户端断开连接。

我是否需要每隔一段时间发送一些保持活动包?

编辑 :要注意,这是在同一台计算机上的同行。 计算机位于NAT后面,可以转发用于此计算机的一系列端口。 与服务器连接的客户端通过DNS打开连接。 即它使用mydomain.net和端口进行连接。

在Windows上,没有数据发送的套接字是许多应用程序中出现问题的重要原因,必须正确处理。

问题是,SO_KEEPALIVE的周期可以在系统范围内设置(否则,默认值是无用的两小时)或后面的winsock API。

因此,许多应用程序确实偶尔发送一些偶然的数据字节(被对等方忽略),只是为了在没有收到ACK之后使网络层声明断开连接(在由层和ack超时完成所有重复的重传之后)。

回答你的问题:不,套接字不会自动断开连接。

但是,你必须小心上述问题。 进一步复杂化的是,测试这种行为非常困难。 例如,如果正确设置所有内容并且您希望正确检测断开连接,则无法通过断开物理层来测试它。 这是因为NIC将检测到载波丢失,并且套接字层将发出信号以关闭所有依赖它的应用程序套接字。 测试它的一个好方法是连接两台计算机,其中三条腿和两个开关介于两者之间,断开中间支路,从而防止载波丢失但仍然在物理上断开机器。

TCP内置了超时但您可以调整它,请参阅Socket类的 SendTimeoutReciveTimeout ,但我怀疑这不是您的问题。 NAT路由器在将TCP连接从其端口转发表中删除之前,也可能具有TCP连接的到期时间。 如果路由器在超时时间内没有流量通过,它将阻止所有传入流量(因为它清除了内存中的转发信息,因此它不知道要将流量发送到哪台计算机),也可能有传出连接不同的源端口,因此服务器可能无法将其识别为同一连接。

使用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套接字根本不会自动关闭。 但TCP 连接确实如此。 但是,如果在同一台计算机中的对等体之间发生这种情况,则只要两个对等体都存在并且其套接字打开,就不应该断开连接。