对于TCP报文中seq和ack的理解

1、TCP协议头

img

Sequence Number(seq)32bit,表示tcp包的序列号,根据seq来确认是否有数据包丢失。

Acknowledgment Number(ack)32bit,表示tcp包的确认号。表示已经收到对方多少数据。

2、seq和ack的作用

通过对seqack标志位的设置,实现了tcp作为可靠传输协议的部分功能。

3、seq和ack的理解

TCP连接的用途可以简化为下图。客户端把发送区的数据发出去,服务端收到数据后放进自己的接收区;服务端把发送区的数据发出去,客户端收到数据后放进自己的接收区。

请添加图片描述
对于seq来说,可以理解为,我已经发出了多少数据;

对于ack来说,可以理解为,我已经接收了多少数据。

这是在此次发包的时候,对当前状态的总结不包括本次发送的包,因为此次发送的动作并没有完成。

4、注意

发出带有SYNFIN标志的报文,seq需要+1;只带有ACK标志的报文,seq不需要+1。

可以简单理解为带有SYN或FIN标志的包,包大小为1个字节;只带有ACK标志的包,包为空。

5、示例

请添加图片描述
上图,简单模拟了一个TCP完整的流程。其中:1-3号报文为三次握手,4-5号报文为一次数据发送,6-9号报文为四次挥手。

三次握手

(1)【报文1】Client发送一个[SYN]报文。此时连接还没建立好,对于Client来说,既没有发出过报文,也没有接收到报文,所以seq=0ack=0

表示Client现在还没有发出过任何包,也没有收到任何包

(2)【报文2】Server收到[SYN]报文后,发送[SYN,AKC]报文。对于Server来说,他并没有发出过报文,但接收到了【报文1】,所以syn=0ack=1

表示Server现在还没有发出去任何包,但接收到了1个字节的包

(3)【报文3】Client收到[SYN, ACK]报文,发送[ACK]报文。对于Client来说,之前已经发出过【报文1】,并接收到了【报文2】,所以syn=1ack=1

表示Client端现在已经发出过1个字节,也接收到了1个字节


数据发送

(1)【报文4】Client发送[PSH, ACK]报文,并且data length=100。对于Client来说,虽然发出了【报文1】和【报文3】,但根据上面第4点的注意,【报文3】只带有ACK标志,这个包的大小为0。所以syn=1ack=1

表示Client端现在已经发出了1个字节,也接收到了1个字节

(2)【报文5】Server收到[PSH, ACK]报文,发送[ACK]报文。对于Server来说,收到了【报文4】,数据大小为100个字节。所以syn=1, ack=101

表示Server现在已经发出了1个字节,接收到了101个字节


四次挥手

(1)【报文6】Server端发送一个[FIN]报文。对于Server来说,上一个包发出去的包是【报文5】,只带[ACK]标志。所以syn=1, ack=101

表示Server现在已经发出了1个字节,接收到了101个字节

(2)【报文7】Client收到[FIN]报文,发送[ACK]报文。对于Client来说,上一个包发出去的包是【报文4】,长度为100字节。所以syn=101ack=2

表示Client已经发出了101个字节,接收到了2个字节

(3)【报文8】Client发送[FIN, ACK]报文。对于Client来说,上一个发出去的包是【报文7】,只带有[ACK],包大小为1,所以syn=101ack=2

表示Client已经发出了101个字节,接收到了2个字节

(4)【报文9】Server收到[FIN, ACK]报文,发送[ACK]报文。对于Server来说,上一个发出去的包是【报文6】,所以syn=2,ack=101

表示Server已经发出了2个字节,接收到了101个字节

在此次TCP连接示例中,Client最后状态为发送101个字节,接收到2个字节;Server最后状态为发送2个字节,接收到101个字节。状态匹配正确。

6、其他

  • 对于示例中频繁出现的只带有[ACK]标志的报文,其实就是搭配着seqack标志位的使用,一起来确认数据是否到达对端的一种手段。
  • 每一次收到报文时,都会比较此次收到的报文中seq值是否等于上一次发出的报文中ack值;也可以认为每一次发出报文中的ack值其实也是对下一次将要收到的报文seq值的预测。如果值不相等,认为发生了丢包。
  • 8
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
TCP的三次握手和四次挥手seqack是用来进行序列号和确认号的传递和确认的。在三次握手,客户端发送SYN报文段给服务端,其seq字段表示客户端的初始序列号。服务端收到后,会回复一个SYN+ACK报文段,其ack字段表示服务端确认客户端的序列号,并且在自己的seq字段设置自己的初始序列号。最后,客户端再回复一个ACK报文段,其ack字段表示客户端确认服务端的序列号。这样,三次握手完成了连接的建立。\[1\] 在四次挥手,当客户端想要关闭连接时,会发送一个FIN报文段给服务端,其seq字段表示客户端的序列号。服务端收到后,会回复一个ACK报文段,其ack字段表示服务端确认客户端的序列号。然后,服务端也会发送一个FIN报文段给客户端,其seq字段表示服务端的序列号。最后,客户端再回复一个ACK报文段,其ack字段表示客户端确认服务端的序列号。这样,四次挥手完成了连接的关闭。\[2\] 总结起来,seq字段用于传递发送方的序列号,ack字段用于确认接收方已经收到的序列号。通过这样的序列号和确认号的交互,TCP可以保证可靠的数据传输和连接的建立与关闭。 #### 引用[.reference_title] - *1* *3* [两张动图-彻底明白TCP的三次握手与四次挥手](https://blog.csdn.net/qzcsu/article/details/72861891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [一文搞懂TCP的三次握手和四次挥手](https://blog.csdn.net/m0_38106923/article/details/108292454)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值