传送TCP报文有三个阶段:连接建立、数据传送、连接释放。
(一)TCP 的连接建立
又叫三报文握手,因为TCP 建立连接的过程中,客户和服务器之间需要交换三个 TCP 报文段。
很多地方称之为“三次握手”,但其实是在一次握手过程中交换了三个报文,而并不是进行了三次握手。
下面介绍三报文握手的过程,其中用 A 表示TCP客户程序,B表示TCP服务器程序。
- 最开始,A、B:CLOSED(关闭)状态,A、B都创建传输控制块TCB。
- 第一个:A向B发送 连接请求报文段(同步位SYN=1,不能携带数据,初始序号 seq=x);
- A发送后:SYN-SENT(同步已发送)状态;B:LISTEN(收听)状态。
- 第二个:B向A发送 确认报文段(SYN=1,ACK=1,确认号ack=x+1,不能携带数据,初始序号 seq=y);
- B收到并发送后:SYN-RCVD(同步收到)状态。
- 第三个:A向B发送 确认报文段(ACK=1,ack=y+1,序号seq=x+1,携带数据消耗序号,不携带不消耗);
- A收到并发送后:ESTAB-LISHED(已建立连接)状态。
- B收到后:ESTAB-LISHED(已建立连接)状态。
为什么A最后还要发送一次确认?
主要是为了防止已失效的连接请求报文段(A向B发送的第一个报文段延误到连接释放以后的某个时间)突然又传送到了B,让B误以为A又发出了一次新的连接请求,因而产生错误。
(二)TCP的连接释放
又称为四报文握手,客户和服务器之间需要交换四个 TCP 报文段。
- 最开始,A、B:ESTAB-LISHED(已建立连接)状态。
- 第一个:A向B发送 连接释放报文段(终止控制位FIN=1,序号seq=u,u是A已传送的最后一个字节的序号 + 1);
- A发送后:FIN-WAIT-1(终止等待 1)状态。
- 第二个:B向A发送 确认报文段(ACK=1,确认号ack=u+1,seq=v,v是B已传送的最后一个字节的序号 + 1);
- B收到并发送后:CLOSE-WAIT(关闭等待)状态。此时还可以向A发送数据。
- A收到后:FIN-WAIT-2(终止等待 2)状态。
- 第三个:B向A发送 连接释放报文段(FIN=1,ACK=1,ack=u+1,seq=w,w为假定值);
- B发送后:LAST-ACK(最后确认)状态。
- 第四个:A向B发送 确认报文段(ACK=1,ack=w+1,seq=u+1);
- A收到并发送后:TIME-WAIT(时间等待)状态。
- A等待 2MSL(MSL叫最长报文段寿命)后:CLOSE(关闭)状态;B收到后:CLOSE(关闭)状态。
结束标志是:当A撤销相应的传输控制块TCB后,就结束了这次的TCP连接。
为什么A在 TIME-WAIT状态 必须等待 2MSL的时间?
- 为了保证 A发送的最后一个ACK报文段能够到达B;
- 防止上一节提到的 “已失效的连接请求报文段” 出现在本连接中。
参考:谢希仁 编著的《计算机网络(第7版)》