接着是:序号
这里序号是两个部分之和。第一部分是一个随机初始值,这个随机初始值由发起方生成。第二部分是TCP报文体中封装的数据段,在原始数据报文中的字节偏移位置值。
之后是确认号:
确认号有两个作用
1、确认号就是告诉TCP通信的另一方,自己已经收到了对方发的TCP报文。
2、告诉另一方下次该请求哪个数据包
在TCP建立连接阶段:
发起方第一次握手时,发送的TCP报文的头部会携带一个序号(随机值),接收方收到第一次握手报文后,会反馈第二次握手报文给发起方,该报文头中有一个确认号,它的计算规则是:“确认号 = 第一次握手时序号 + 1”
例如:
发起方收到第二次握手报文后,检查确认号是否比第一次握手时序号大1,是的话,则认为就是接收方确认接收到了。
并且确认号也表示希望发起方下次从 确认号指定的位置开始发起请求。
在TCP通信阶段:
比如浏览器会请求服务器的某个资源文件而发起HTTP请求,服务器会对HTTP请求回应,回应报文中包含了资源文件的大小,此时服务器会通过TCP连接来传输资源文件。注意资源文件首先会被分解为多个数据段,服务器将数据段封装为TCP报文,然后依次发送给浏览器。
此时服务器发送的TCP报文中,报文头会带一个确认号,该确认号此时的工作不再单纯是告诉浏览器自己确认收到了你的TCP请求,即确认号不再是 seq + 1了,而是告诉浏览器下次该请求哪个数据段对应的TCP数据包了。它的计算规则是: 确认号 = seq + 请求资源文件大小 - 54
为什么要减去54呢?
因为这里通过HTTP获取到请求资源文件的大小不仅包含了 原始数据段,还有各层对原始数据段的封装头信息,比如:
14字节Ethernet报头(数据链路层),20字节的IP报头(网络层),20字节的TCP报头(传输层),它们加起来就是54字节
减去这54字节,才能得到原始数据段大小。
例如:
这里ack确认号 396的计算过程就是 = 1 + 449 - 54
再比如
这里服务器让客户端下次从854位置开始请求,这个确认号计算过程是:396 + 512 - 54 = 854
目前TCP报文头中的序号和确认号已经能够帮助通信双方来识别对方是否已经确认收到消息了,但是这样就能实现可靠传输了吗?
还不行。
TCP还有一种应对 无确认反馈的机制。即发起方发起TCP报文请求后,接收方如果不及时反馈确认收到消息给发起方,则发起方会认为接收方没有收到,会再次重发。同样地,如果接收方发起TCP报文给发起方,如果发起方没有及时给出确认收到消息反馈,则接收方也会重发。
而如果发起方或接收方收到多个相同TCP报文,则会根据报文头中序号来判断多余报文并丢弃。
这就是TCP保证 丢包和重包 的机制。
而错包,更多的是依靠TCP头部的校验和信息来确认的。
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618191877)
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!