TCP可靠性的体现:seq和ack机制

提到TCP和UDP的区别,很容易想到的就是TCP的可靠性,那TCP是通过什么机制实现了可靠性的呢?解释这个之前先来区分TCP中的大写ACK和小写ack。看一张经典的TCP三次握手过程图:

这张图里似乎有个大写的ACK也有个小写的ack,这也是容易混淆的地方。

大写的ACK是控制位,在TCP报文头中有8个标志比特,也就是TCP报文头中有8位大小的数据是标志位,看一下TCP报文格式更好理解:

它们中的多个可以同时被设置成1:

CWR(Congestion Window Reduce):拥塞窗口减少标志,用来表明它接收到了设置ECE标志的TCP包。并且,发送方收到消息之后,通过减小发送窗口的大小来降低发送速率。
ECE(ECN Echo):用来在TCP三次握手时表明一个TCP端是具备ECN功能的。在数据传输过程中,它也用来表明接收到的TCP包的IP头部的ECN被设置为 11,即网络线路拥堵。
URG(Urgent):表示本报文段中发送的数据是否包含紧急数据。URG=1时表示有紧急数据。当URG=1时,后面的紧急指针字段才有效。
ACK:表示前面的确认号字段是否有效。ACK=1时表示有效。只有当 ACK=1时,前面的确认号字段才有效。TCP规定,连接建立后,ACK必须为 1。
PSH(Push):告诉对方收到该报文段后是否立即把数据推送给上层。如果值为1,表示应当立即把数据提交给上层,而不是缓存起来。
RST:表示是否重置连接。如果RST=1,说明TCP连接出现了严重错误(如主机崩溃),必须释放连接,然后再重新建立连接。
SYN:在建立连接时使用,用来同步序号。当SYN=1,ACK=0时,表示这是一个请求建立连接的报文段;当SYN=1,ACK=1时,表示对方同意建立连接。SYN=1时,说明这是一个请求建立连接或同意建立连接的报文。只有在前两次握手中SYN才为1。
FIN:标记数据是否发送完毕。如果 FIN=1,表示数据已经发送完成,可以释放连接。

这是大写的ACK,而小写的ack是确认序列号,和它一对的是seq即顺序序列号,也就是上图TCP报文格式中的Sequence Number和Acknowledgment Number。

前面说了这么多只是为了区分TCP中的大写ACK和小写ack,也没其他方法就用大小写区分吧,本文关注的重点就是TCP中的seq和ack机制,通过它们实现了TCP的可靠性传输,当然TCP通过很多方面去保证了可靠性传输,这里seq和ack机制是防止数据丢失丢包的机制。

顺序号seq:用来标识从TCP源端向TCP目的端发送的数据字节流,它表示在这个报文段中的第一个数据字节的顺序号。理解起来就是TCP用顺序号对每个字节进行计数。由上图TCP报文格式中可以看出序号是 32bit 的无符号数,序号到达 2^{23}-1后又重新开始计数。当建立一个新的连接时,顺序号字段包含由这个主机选择的该连接的初始顺序号 ISN ( Initial Sequence Number ),也就是说seq并不一定是从0开始的,所以刚在画TCP三次握手的时候,写的seq=x,即使还没有数据传输,seq包含了ISN后就成了一个随机数,并不是0。

确认号ack:理解起来就一句话,所期望收到的下一个顺序号seq。

TCP为应用层提供全双工服务,这意味数据能在两个方向上独立地进行传输,也就是说服务端和客户端都可能成为数据接收或者数据发送的一端。

数据发送端在发送TCP报文时,计算在本次seq计数内,之前所有发送的报文中数据长度之和是多少,也就是计数记到哪里了,这就是seq。然后再计算之前所有收到的报文中收到的数据长度之和是多少,这就是ack。需要注意的是seq和ack是分开计数的。需要注意的是,SYN和FIN的TCP报文传输虽然没有数据,但是数据长度算1,ACK的传输,数据长度算0。

数据接收端收到TCP报文后,将这次报文中的seq取出来,和自己最后一次发送的ack对比,如果一致,则代表数据没有丢失,理解起来就是这次的顺序号和上次自己期望的顺序号一致嘛。如果不一致就说明有丢包发生。其实就是TCP用0~2^{23}-1对每个字节进行计数,用下图举个例子解释一下:

三个过程:

1.A在发送某个TCP报文前,发现此时自己这边的seq计数已经到了x,那这次的报文中seq=x,也就是在一次seq计数内,该端之前所有发送的报文中数据长度之和为x。然后这次又在这个报文中携带了长度为100bit的数据。

2.B在收到这个报文后,拿到报文中的seq=x,又拿到了长度为100bit的数据,然后回包的时候ack=x+100。意思是告诉B你已经发了x+100位的数据了,下次发包的时候别忘了把seq改成x+100。

3.A收到B回的数据包后,拿到报文中的ack=x+100,然后和自己这边的计数着的seq一比对,如果一样,说明A发的B都收到了没问题,如果不一样,假如A一看自己这边的seq已经等于y了,也就是自己计数着的已经发送y位的数据了,可是听B的意思它才收到x+100位数据,丢包了呗。然后就是重发什么的是TCP的另外一些机制。

TCP就是通过seq和ack机制去确认传输过程中有没有丢包现象,前面说在一次计数范围内,seq并不一定是从0开始的,可以当我们用Wireshark抓包时,上面显示的seq确实从0开始的,这是因为Wireshark等抓包软件为了让seq和ack展示更直观,自动帮我们减去了初始顺序号 ISN,当然也可以设置为直接展示真正的seq和ack,那就看着比较乱了,贴一张Wireshark处理后的seq和ack变化过程图:

图中前三步即TCP的三次握手,之后是数据传输。可以结合该图去更好的理解本文。

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值