大家好,我叫徐锦桐,个人博客地址为www.xujintong.com。平时记录一下学习计算机过程中获取的知识,还有日常折腾的经验,欢迎大家访问。
TCP在连接时,客户端和服务端会进行3次握手,来确定两者能进行稳定的连接。我们通过图文结合的方式讲解,并且会通过Wireshark来进行抓包分析。
TCP头部
在讲解TCP握手挥手之前,我们来先介绍一下TCP的头部格式。
序列号(seq):两端进行TCP连接时,都会初始化一个随机的32位无符号整数(最大值4G,超过4G会进行回绕),之后每次发包都会在这个初始化的序列号上进行累加,序列号是为了防止包的乱序问题的。
确认应答号(Acknowledgment Number): 就是期望下次收到的序列号。发送端收到这个确认应答号,可以认为它之前的包都成功接受了。
控制位:
- ACK:置为 1 时,使确认应答号有效。
- RST:表示重置连接。
- SYN:置为 1 时,使序列号有效,表示希望建立连接。
- FIN:置为 1 时,表示希望断开连接。
三次握手
第一次握手
第一次握手客户端会将报文中的SYN置为1,并且初始化一个32位的无符号整数序列号,发送报文给服务端。
第一个包TCP头部
第一次握手抓包
第二次握手
第二次握手服务端将报文中的SYN和ACK置为 1,并且服务端也会生成一个32位的随机序列号。
确认序列号(Acknowledgment Number)是上一次接收到的序列号+1,表示下次期望的序列号,客户端可以认为之前的包都成功接受。
第二次握手TCP头部
第二次握手抓包
第三次握手
第三次握手也是将报文的SYN和ACK置为 1,序列号是上一次发送的序列号+1(当前客户端递增到的序列号),确认应答号是上一次接受的序列号+1(服务端递增到的序列号)。
注意:TCP标准协议规范中,第三次握手包是允许传输数据的!
第三次握手默认不携带数据,并且SYN=0,所以并不消耗此次序列号
第三次握手TCP头部
第三次握手抓包
三次握手总结
三次握手中,客户端和服务端一共发送过两个确认序列号。确认序列号将对方的初始化序列号+1,就是起确认的作用,我确认收到了你的初始化序列号,我加上1表示你下次传过来的序列号应该是这个。
当SYN为0时,在连接的建立阶段不会消耗序列号
在TCP连接的建立和数据传输过程中,序列号(Sequence Number)的消耗和SYN标志位的设置有关,但不仅仅是SYN标志位是否为0。
首先,让我们澄清一些关于TCP序列号和SYN标志位的重要概念:
- SYN标志位: SYN标志位用于TCP的连接建立过程。在三次握手中,客户端的初始序列号(ISN - Initial Sequence Number)在第一个数据包中,而服务器的ISN在第二个数据包中。SYN标志位用于指示这些数据包是用于连接建立的,以及在序列号字段中包含了初始序列号。
- 序列号: 序列号是用于跟踪和管理TCP数据流的重要字段。它不仅在连接建立时使用,还在整个连接的生命周期中使用,用于确定数据包的顺序和完整性。
当SYN标志位为0时,连接的建立阶段将不会消耗序列号,因为序列号通常在连接建立时用于协商初始序列号(ISN),而ISN的协商是在建立连接时使用SYN标志位来表示的。当SYN标志位为1时,序列号字段中包含了初始序列号。当SYN标志位为0时,数据包不会用于建立连接,因此也不会影响序列号的消耗。
总之,SYN标志位的设置与连接的建立和序列号的协商有关,当SYN标志位为1时,用于建立连接并协商初始序列号,当SYN标志位为0时,不用于连接建立,因此不会消耗序列号。序列号在TCP连接的整个生命周期中都会被消耗,用于跟踪数据包的顺序和完整性。
四次挥手
四次挥手挺简单的,最终是,双方都向对方发送了一次FIN
和ACK
。
首先客户端下将FIN报文(FIN位置为1)发送给服务器,自己进入FIN_WAIT_
状态。
服务端收到FIN报文后发送ACK确认报文,然后进入CLOSED_WAIT
状态。
客户端收到服务端发送的ACK报文后,会进入FIN_WAIT_2
状态。
等待服务端处理数据完成(完成收尾工作),服务端会向客户端发送FIN报文,然后进入LAST_ACK
报文。
客户端收到FIN报文后会发送ACK报文,进入TIME_WAIT
状态,等待2个MSL时间关闭。
服务端收到ACK确认报文后就会关闭。