0%

TCP-四次握手

释放连接之前,在进行数据传送,都处于ESTABLISHED状态,即已建立连接。
书上说数据传输结束之后,通信的双方都可以释放连接。
这里演示的是客户端A主动释放连接。

TCP传输连接管理 - 连接释放 - 四次握手

第一次握手

客户端A的应用程序先向其TCP发出释放报文段,并停止传输数据,主动关闭TCP连接。
A把释放报文段首部的 终止控制位FIN = 1,其序号 seq = u,u 等于已传送过来的数据的最后一个字节的序号加1。
此时,客户端A进入 FIN-WAIT-1状态。

第二次握手

服务器端B收到释放报文段后,发出确认,ACK=1,确认号是 ack = u+1,而这个确认报文段自己的序号是seq = v ,v等于B前面已经传送过的数据的最后一个字节的序号加 1 。
然后服务器B就进入到 CLOSE-WAIT状态,即等待关闭。
此时!!! 处于半关闭状态。
即:A已经没有数据发送到B,但是B如果有数据要发送给A的话,A仍然要接收。
也就是说,A到B这个方向的连接已经关闭,B到A这个方向的连接并没有关闭,可能还要持续一段时间。

第三次握手

客户端A收到服务器端B的确认后,进入FIN-WAIT-2状态,等待B发出的连接释放报文段。
如果B已经没有数据要发送给A了,那么B就会发出释放报文段: FIN = 1,ACK = 1,假定B的序号 seq = w。B还必须重复上次已发送的确认号 ack = u+1
这时,服务器B就进入 LAST-ACK状态了,即最后确认状态,等待A的确认。

第四次握手

客户端A收到服务器B发来的报文后,对此进行确认。在确认报文段,把 ACK = 1,序列号 seq = u+1,确认号 ack = w+1
然后进入到TIME-WAIT(时间等待)状态。
注意,四次握手之后,连接并没有马上被释放掉。必须经过时间等待计时器设置的时间2MSL后,客户端才进入CLOSED状态。
MSL叫做最长报文段寿命,建议设置为两分钟
设置两倍最长报文段寿命的目的是:
1.保证A发送的最后一个ACK报文段能够到达B。这个报文段可能会丢失,B收不到最后的确认,就会超时重传,然后A因为还没关闭,所以就能再次传送最后的ACK报文。
2.为了防止“已失效的请求连接报文段”出现在本次连接中,2MSL时间后,就可以是的本连接持续时间内所发生的所有报文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段。

为什么建立连接是三次握手,而关闭连接却是四次挥手呢?

这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方是否现在关闭发送数据通道,需要上层应用来决定,因此,己方ACK和FIN一般都会分开发送。