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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11712425/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 18:56:11  来源:igfitidea点击:

Do TCP sockets automatically close after some time if no data is sent?

c#socketstcptimeoutdisconnect

提问by Nick Banks

I have a client server situation where the client opens a TCP socket to the server, and sometimes long periods of time will pass with no data being sent between them. I have encountered an issue where the server tries to send data to the client, and it seems to be successful, but the client never receives it, and after a few minutes, it looks like the client then gets disconnected.

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

Do I need to send some kind of keep alive packet every once in a while?

我是否需要每隔一段时间发送某种保活数据包?

Edit: To note, this is with peers on the same computer. The computer is behind a NAT, that forwards a range of ports used to this computer. The client that connects with the server opens the connection via DNS. i.e. it uses the mydomain.net & port to connect.

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

采纳答案by Pavel Radzivilovsky

On Windows, sockets with no data sent are a big source for trouble in many applications and must be handled correctly.

在 Windows 上,没有发送数据的套接字是许多应用程序中的一大麻烦来源,必须正确处理。

The problem is, that SO_KEEPALIVE's period can be set system-wide (otherwise, a default is useless two hours) or with the later winsock API.

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

Therefore, many applications do send some occasional byte of data every now and then (to be disregarded by the peer) only to make the network layer declare disconnection after ACK is not received (after all due retransmissions done by the layer and ack timeout).

因此,许多应用程序偶尔会偶尔发送一些字节的数据(被对端忽略),只是为了让网络层在没有收到 ACK 后宣布断开连接(毕竟该层完成了应有的重传和 ack 超时)。

Answering your question: no, the sockets do not disconnect automatically.

回答您的问题:不,插座不会自动断开连接。

Yet, you must be careful with the above issue. What complicates it further is that testing this behavior is very hard. For example, if you set everything correctly and you expect to detect disconnection properly, you cannot test it by disconnecting the physical layer. This is because the NIC will sense the carrier loss and the socket layer will signal to close all application sockets that relied on it. A good way to test it is connect two computers with 3 legs and two switches in between, disconnecting the middle leg, thus preventing carrier loss but still physically disconnecting the machines.

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

回答by Scott Chamberlain

There is a timeout built in to TCP but you can adjust it, See SendTimeoutand ReciveTimeoutof the Socket class, but I have a suspiciouion that is not your problem. A NAT router may also have a expiration time for TCP connections before it removes it from it's port forwarding table. If no traffic passes within the time of that timeout on the router it will block all incoming traffic (as it cleared the forwarding information from it's memory so it does not know what computer to send the traffic to), also the outgoing connection will likely have a different source port so the server may not recognize it as the same connection.

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

回答by user207421

TCP sockets don't automatically close at all. However TCP connectionsdo. But if this is happening between peers in the same computer the connection should never be dropped as long as both peers exist and have their sockets open.

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

回答by TOC

It's more secure to use Keep-alive option (SO_KEEPALIVE under linux), to prevent disconnect due to inactivity, but this may generate some extra packets.

使用 Keep-alive 选项(Linux 下的 SO_KEEPALIVE)更安全,以防止由于不活动而断开连接,但这可能会产生一些额外的数据包。

This sample code do it under linux:

此示例代码在 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);

Regards.

问候。