TCP 是面向连接的协议,所以使用 TCP 前必须先建立连接,而建立连接是通过三次握手来进行的。
天下没有不散的宴席,对于 TCP 连接也是这样, TCP 断开连接是通过四次挥手方式。
下面我们通过实操,来彻底理解三次握手和四次挥手。
winter
必须先提及几个基础概念:TCP四元组、TCP协议簇、TCP协议报文。
TCP协议簇
TCP四元组
TCP协议报文 = TCP首部 + TCP荷载。
我们通过 curl 112.47.52.137 的抓包记录来分析一下这个TCP报文。
完整报文如下:
下面挑选一些跟三次握手和四次挥手,紧密相关的组成字段来解析:
TCP序列号(Sequence Number)
定义:TCP会话的每一端都包含一个32位(bit)的序列号(可能是0和4,294,967,295之间的任意值),该序列号被用来跟踪该端发送的数据量,每一个包中都包含序列号,在接收端则通过确认号用来通知发送端数据成功接收。
作用:在建立连接时由计算机生成的随机数作为其初始值,通过 SYN 包传给接收端主机,每发送一次数据,就「累加」一次该「数据字节数」的大小。用来解决网络包乱序问题。
TCP确认号(Acknowledgment Number)
指下一次「期望」收到的数据的序列号,发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。用来解决丢包的问题。
TCP控制位
TCP在其协议头中使用大量的标志位或者说1位(bit)布尔域来控制连接状态,一个包中有可以设置多个标志位。
TCP控制位即TCP标志位,有6种标示:
SYN(synchronous建立联机)
ACK(acknowledgement 确认)
PSH(push传送)
FIN(finish结束)
RST(reset重置)
URG(urgent紧急)
上面6个控制位里,最常见的是四个标志位:
ACK:该位为 1 时,「确认应答」的字段变为有效,TCP 规定除了最初建立连接时的 SYN 包之外该位必须设置为 1 。
RST:该位为 1 时,表示 TCP 连接中出现异常必须强制断开连接。
SYN:该位为 1 时,表示希望建立连接,并在其「序列号」的字段进行序列号初始值的设定。
FIN:该位为 1 时,表示今后不会再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换 FIN 位为 1 的 TCP 段。
TCP三次连接
3次握手是指发送了3个报文段,TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接。红圈范围内就是3次握手的抓包记录,TCP三次握手完成之后,客户端才向服务端发起一次HTTP请求。
三次握手图例
第一次握手(客户端→服务端)
客户端发送序列号为Seq = c的SYN数据包给服务器。
分析:
说明客户端有正常发起请求的能力
第二次握手(服务端→客户端)
服务器接到该包后,响应(或返回)一个序列号为Seq = s,确认号为 Ack = c+1的SYN+ACK数据包给客户端。
分析:
说明服务端有正常接受请求的能力
说明服务端有正常发送请求的能力
第三次握手(客户端→服务端)
客户端收到服务器的响应后,就会回复一个序列号为Seq = c+1, 确认号为Ack = s+1的ACK数据包给服务器,三次握手完成。
分析:
说明客户端有正常接受响应的能力
总结
TCP 之所以需要 3 次握手,是因为 TCP 通讯双方都是全双工的,所以要经过 3 次交互才能确认双方的发送能力和接收能力,并且 TCP 握手必须是 3 次,如果是 2 次握手,不能证明服务器端的发送能力和客户端的接收能力;也不能是 4 次握手,因为 3 次已经能证明的事情,再交互握手 1 次完全没有必要。