TCP终止连接时的几个状态

来源:互联网 发布:程序员用的最多的库 编辑:程序博客网 时间:2024/05/22 01:57

TCP终止连接需要4个分节,简称四次握手。

 

首先要明确的概念是:当一对TCP sockets建立了连接,客户和服务器是对等的,没有区别;

TCP连接是双工的,所以一条连接其实是“两条单向的连接”

 

连接的终止:

1. 主动方发出设置了FIN位的报文,表示主动终止从本地到远端的单向连接;

此时,主动方进入FIN_WAIT1状态,意思就是它在等待远端的FIN报文;

 

2. 远端收到FIN后,会立即发送ACK;主动方收到ACK后,进入FIN WAIT2状态,所以FIN-WAIT1状态持续的非常短;

此时远端进入CLOSE-WAIT状态,一条单向连接终止了,但另一条还没有,处于HALF-CLOSE连接状态;

 

3.当远端进行了必要的数据发送后,它发送FIN,表示从它出发的单向连接也要关闭;同时它进入LAST ACK状态;

 

4.主动方收到FIN后,回应一个ACK;远端就此进入CLOSED状态,连接关闭;

 

5.主动方进入TIME WAIT状态;确保最后一个ACK没有丢失,防止新连接占用刚刚关闭的主动方的地址端口,使得网络中流浪的老连接的分组被误认为新连接的分组。

 

补概念:

半开连接:一方已经关闭或异常终止连接,但另一方却不知道。比如某端突然断电了,另一端是无法感知的。

1,只要TCP的缓冲里还有未读取(read)数据,则调用close时会直接向对端发送RST。
2,shutdown与socket描述符没有关系,即使调用shutdown(fd, SHUT_RDWR)也不会关闭fd,最终还需close(fd)。
3,在已发送FIN包后write该socket描述符会引发EPIPE/SIGPIPE。

4,当有多个socket描述符指向同一socket对象时,调用close时首先会递减该对象的引用计数,计数为0时才会发送FIN包结束TCP连接。shutdown不同,只要以SHUT_WR/SHUT_RDWR方式调用即发送FIN包。
5,SO_LINGER与close,当SO_LINGER选项开启但超时值为0时,调用close直接发送RST(这样可以避免进入TIME_WAIT状态,但破坏了TCP协议的正常工作方式),SO_LINGER对shutdown无影响。
6,TCP连接上出现RST与随后可能的TIME_WAIT状态没有直接关系,主动发FIN包方必然会进入TIME_WAIT状态,除非不发送FIN而直接以发送RST结束连接

 

参考文献:

UNIX网络编程第一卷;

用TCP进行网际互联第一卷



附一条有用的TCPDUMP指令:

tcpdump -s0 -Xn -i any udp and ip[0x29:4]=831010004

抓udp包,且从第0x29字节开始的连续4字节值为831010004的包;