我做了一个实验:
服务器监听端口8804,接受客户端的连接,然后向客户端发送数据。我关闭了网络。
- 当我运行netstat -anotp | grep 8804时,它显示服务器和客户端上的连接都是"ESTABLISHED",但是没有数据传输。 一段时间后,服务器抛出错误:"Connection time out"
- netstat -anotp | grep 8804,发现客户端仍然是"ESTABLISHED"
:
1. 为什么在系统调用"write"时被阻塞的服务器抛出"Connection timeout"错误?为什么不是客户端?
2. 如何让客户端发现连接实际上已关闭。
3.当网络不工作时,为什么服务器和客户端状态都是"ESTABLISHED" ?
谢谢你的回答!
- 你的服务器正在等待它发送给客户端的单个数据段的TCP ack;但是,客户机不知道服务器的数据有多长。由于您关闭了网络,服务器不再从客户端获得ack。结果:服务器连接超时(见注1)
- 在套接字上使用TCP keepalive(见注释2)
- 您没有启用TCP keepalive。如果您正在使用python,您可以这样做(假设您的套接字命名为
s
):
# Do this before you accept() anything on the socket
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
编辑:
由于您使用的是C语言,因此需要一个指向Linux TCP keepalive方法的链接
- RFC 1122: Section 4.2.3.5"TCP连接失败"
- RFC 1122: Section 4.2.3.6 TCP Keepalives"