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

时间:2012-07-29 19:50:47

标签: c# sockets tcp timeout disconnect

我有一个客户端服务器情况,客户端打开一个到服务器的TCP套接字,有时会传递很长一段时间,而不会在它们之间发送数据。我遇到了一个问题,服务器试图将数据发送到客户端,它似乎成功,但客户端从未收到它,几分钟后,客户端就会变得断开连接。

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

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

4 个答案:

答案 0 :(得分:9)

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

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

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

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

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

使用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);

问候。

答案 3 :(得分:-2)

TCP套接字根本不会自动关闭。但是,TCP 连接可以。但是,如果在同一台计算机中的对等体之间发生这种情况,则只要两个对等体都存在并且其套接字打开,就不应该断开连接。