断开时有数据传输
在客户端拔掉网线后,服务端向客户端发送的数据报文会得不到任何的响应,在等待一定时长后,服务端就会触发超时重传机制,重传未得到确认的TCP报文段。 如果在服务器端重传报文段的过程中,客户端刚好把网线插回去了,由于拔掉网线并不会改变客户端的 TCP 连接状态,并且还是处于 ESTABLISHED 状态,所以这时客户端是可以正常接收服务端发来的数据报文段的,然后客户端就会回 ACK 确认报文段。 此时,客户端和服务端的 TCP 连接依然存在的,就感觉什么事情都没有发生。 但是,如果在服务器端重传报文的过程中,客户端一直没有将网线插回去,服务器端超时重传报文的次数达到一定阈值后(默认是15次),内核就会判定出该 TCP 连接有问题,然后通过 Socket 接口告诉应用程序该 TCP 连接出问题了,于是服务端的 TCP 连接就会断开。 而等客户端插回网线后,如果客户端向服务器端发送了数据,由于服务器端已经没有与客户端相同四元组的 TCP 连接了,因此服务器端内核就会回复 RST 报文段,客户端收到后就会释放该 TCP 连接。 此时,客户端和服务器端的 TCP 连接都已经断开了。
断开时无数据传输
针对拔掉网线后,没有数据传输的场景,还得看是否开启了 TCP keepalive 机制 (TCP 保活机制)。 如果没有开启 TCP keepalive 机制,在客户端拔掉网线后,并且双方都没有进行数据传输,那么客户端和服务端的 TCP 连接将会一直保持存在。 而如果开启了 TCP keepalive 机制,在客户端拔掉网线后,即使双方都没有进行数据传输,在持续一段时间后,TCP 就会发送探测报文段。
