网站主编 做啥,金蝶直播软件,全球十大建筑设计事务所,中国郴州TCP是面向连接的、可靠的、基于字节流的传输层通信协议。
TCP是面向连接的协议#xff0c;所以使用 TCP前必须先建立连接#xff0c;而建立连接是通过三次握手来进行的。
TCP包头结构
在讲解三次握手的过程之前#xff0c;我们先来看一下 TCP包的结构#xff1a; TCP包…TCP是面向连接的、可靠的、基于字节流的传输层通信协议。
TCP是面向连接的协议所以使用 TCP前必须先建立连接而建立连接是通过三次握手来进行的。
TCP包头结构
在讲解三次握手的过程之前我们先来看一下 TCP包的结构 TCP包头大小在大多数情况下是固定的它通常是 20字节不包括任何选项但如果启用了选项则最多可以达到 60字节。下面是 TCP包头的一般结构
源端口号16位表示发送方的端口号。目标端口号16位表示接收方的端口号。序列号32位用于对数据流中的字节进行编号以便对方能够按顺序重新组装数据。确认号32位表示期望接收到的下一个序列号。数据偏移4位指示 TCP包头的长度以 4字节为单位。因此数据偏移的值乘以 4就是 TCP包头的总长度。这个字段也被称为 头部长度。保留位6位保留供将来使用目前全部为 0。标志位6位用于控制 TCP连接的状态包括 SYN、ACK、FIN、RST、PSH、URG等。窗口大小16位表示发送方的接收窗口大小用于流量控制。校验和16位用于验证 TCP报文的完整性。紧急指针16位当 URG标志被设置时紧急指针表示紧急数据的末尾位置。选项可选可以包含各种选项如最大报文段大小MSS、窗口缩放因子等每个选项的大小不定。
在三次握手过程中我们主要关注序列号、确认号以及标志位中的SYN和ACK
三次握手过程
通常来说服务器会开放监听端口而客户端则主动连接这个端口创建连接的时候会进行三次握手过程如下图所示
客户端发送 SYN包到服务器附上一个随机生成的序列号(ISN)。此时客户端处于 SYN_SEND状态。服务器返回 SYNACK包到客户端附上一个随机生成的序列号确认号则是客户端上传的序列号1。此时服务端处于SYN_RECV状态。客户端返回 ACK到服务器确认号是服务器下发的序列号1。此时客户端处于ESTABLISHED状态连接已建立这个包可以顺带发一些数据。服务端收到ACK后也进入ESTABLISHED状态可以收发数据。
三次握手的一个重要功能是客户端和服务端交换 ISN(Initial Sequence Number)以便让对方知道接下来接收数据的时候如何按序列号组装数据。同时也确保了服务端和客户端的收发都能正常进行。
使用 wireshark抓包工具我们可以看到三次握手的数据 为什么是三次握手不是两次、四次
1. TCP 连接使用三次握手的首要原因是为了防止旧的重复连接初始化造成混乱。
想像一个场景客户端发了SYN之后宕机了重启后又发了新的SYN。如果只有两次握手的话当服务器收到旧的SYN之后发送ACK给客户端就直接进入ESTABLISHED状态这时候就可以发数据了。
但是客户端期待的是新的SYN的序列号发现服务端发的确认号不对应会关闭这个连接而服务器此时已经发了数据过来这就造成了混乱。
而三次握手客户端可以收到ACK之后判断确认号正确则返回ACK错误则返回RST告诉服务器关闭这个连接。
使用三次握手和RST控制消息将是否建立连接的最终控制权交给了客户端因为只有客户端有足够的上下文来判断当前连接是否是错误的或者过期的这也是TCP使用三次握手建立连接的最主要原因。
2. 三次握手的第二个原因是为了交互双方的序列号。
TCP协议的通信双方都必须维护一个序列号用来保证数据包的有序以及丢包时能够重发所以这个初始化的序列号是很重要的。当客户端发SYN给服务器时服务器需要返回ACK确认而服务器发SYN给客户端时客户端也需要发ACK确认才能确保两边都有正确的序列号。服务器在发SYN和ACK时可以合并成一条消息发送所以是不需要四次握手的。
参考资料
4.1 TCP 三次握手与四次挥手面试题 - 小林coding