为什么第二次和第三次握手报文中的确认号是将对方的序列号 + 1 后作为确认号呢?SYN 报文是特殊的 TCP 报文,用于建立连接时使用,虽然 SYN 报文不携带用户数据,但是 TCP 将 SYN 报文视为 1 字节的数据,当对方收到了 SYN 报文后,在回复 ACK 报文时,就需要将 ACK 报文中的确认号设置为 SYN 的序列号 + 1,这样做是有两个目的:
- 告诉对方,我方已经收到 SYN 报文 。
- 告诉对方,我方下一次「期望」收到的报文的序列号为此确认号,比如客户端与服务端完成三次握手之后,服务端接下来期望收到的是序列号为 client_isn + 1 的 TCP 数据报文 。

文章插图
在这里插入图片描述
客户端发送 10 字节的数据,通常 TCP 数据报文的控制位是 [PSH, ACK],此时该 TCP 数据报文的序列号和确认号分别设置为:
- 序列号设置为 client_isn + 1 。客户端上一次发送报文是 ACK 报文(第三次握手),该报文的 seq = client_isn + 1,由于是一个单纯的 ACK 报文,没有携带用户数据,所以 len = 0 。根据公式 1(_序列号 = 上一次发送的序列号 + len_),可以得出当前的序列号为 client_isn + 1 + 0,即 client_isn + 1 。
- 确认号设置为 server_isn + 1 。没错,还是和第三次握手的 ACK 报文的确认号一样,这是因为客户端三次握手之后,发送 TCP 数据报文 之前,如果没有收到服务端的 TCP 数据报文,确认号还是延用上一次的,其实根据公式 2 你也能得到这个结论 。
接着,当服务端收到客户端 10 字节的 TCP 数据报文后,就需要回复一个 ACK 报文,此时该报文的序列号和确认号分别设置为:
- 序列号设置为 server_isn + 1 。服务端上一次发送报文是 SYN-ACK 报文,序列号为 server_isn,根据公式 1(_序列号 = 上一次发送的序列号 + len 。特殊情况,如果上一次发送的报文是 SYN 报文或者 FIN 报文,则改为 + 1_),所以当前的序列号为 server_isn + 1 。
- 确认号设置为 client_isn + 11。服务端上一次收到的报文是客户端发来的 10 字节 TCP 数据报文,该报文的 seq = client_isn + 1,len = 10 。根据公式 2(_确认号 = 上一次收到的报文中的序列号 + len_),也就是将「收到的 TCP 数据报文中的序列号 client_isn + 1,再加上 10(len = 10) 」的值作为了确认号,表示自己收到了该 10 字节的数据报文 。
之前有读者问,如果客户端发送的第三次握手 ACK 报文丢失了,处于 SYN_RCVD 状态服务端收到了客户端第一个 TCP 数据报文会发生什么?刚才前面我也说了,发送的第一个 「TCP 数据报文的序列号和确认号」都是和「第三次握手的 ACK 报文中序列号和确认号」一样的,并且该 TCP 数据报文也有将 ACK 标记位置为 1 。如下图:

文章插图
在这里插入图片描述
所以,服务端收到这个数据报文,是可以正常完成连接的建立,然后就可以正常接收这个数据包了 。
四次挥手阶段的变化最后,我们来看看四次挥手阶段中,序列号和确认号的变化 。
数据传输阶段结束后,客户端发起了 FIN 报文,请求服务端端开该 TCP 连接,此时就进入了 TCP 四次挥手阶段,如下图 。
经验总结扩展阅读
- 二 SpringCloud - Eureka注册中心,feign远程调用,hystrix降级和熔断
- 其三 Gitea 1.18 功能前瞻:增强文本预览效果、继续扩展软件包注册中心、增强工单实用功能、完善了用户邀请机制和SEO
- 92猴男和96鼠女哪年结婚最好
- 自然共和国芦荟胶成分有什么?
- 自然乐园和自然共和国是一个牌子吗?
- 华为watch3pro尊享版和时尚版区别_哪款更值得入买
- 雅萌ace和max的区别_雅萌ace和max的参数
- 真我q3和q3s有什么区别_真我q3和q3s参数对比
- 属兔2023年有什么讲究和禁忌
- 和哪些星座恋爱注定虐心虐神虐身