欢迎光临
我们一直在努力

TCP协议:现代网络数据传输的守护者——十大核心机制赋能高效可靠通信

一、先谈UDP协议

1.1、UDP协议端格式

        16位UDP长度,表示整个数据报(UDP首部+UDP数据)的最大长度,源端口号和目的端口号占16个二进制位(2字节),范围0-65535

        如果校验和出错,则会直接丢弃 

UDP的特点

         无连接:不需要与对端建立连接,知道对端的端口号和IP即可直接传输

        • 不可靠:没有确认应答、超时重传机制,即使因网络问题无法发送的对方,UDP协议也不会给应用层任何错误信息

        • 面向数据报:不能灵活的控制读写数据的次数和数量

UDP使用注意事项

        UDP协议首部有一个16位的最大长度,也就是UDP能传输的数据最大长度是64K(首部+数据),但在当今互联网环境下,64K是一个非常小的数据

        如果我们想要传输的数据超过64K,就要在应用层手动的分包,多次发送,在接收端手动拼装

 二、TCP协议

        TCP全称为 "传输控制协议(Transmission Control Protocol"), 即要对数据的传输进行⼀个详细的控制

TCP协议端格式

         • 源/目的端口:表示数据从哪个进程发送,哪个进程要接收

         • 32位序号/确认号分别表示数据段的第一个字节的编号,用于保证数据按序到达和接收方期望的下一个字节序号,即已接收数据最高序号加1

         • 4位数据偏移(等同报头长度):表示该TCP首部有多少个32位bit(4字节),所以TCP首部最大长度为15*4 = 60

         • 6位标志位

                URG:紧急指针是否有效

                ACK确认号是否有效

                PSH:催促接收端应用程序立刻从TCP缓存区将数据读走

                RST:携带该标识的称为复位报文段:对方要求重新建立连接

                SYN:携带该标识的称为同步报文段:请求重新建立连接

                FIN:携带该标识的称为结束报文段:通知对端,本端将关闭

         • 16位窗口大小表示​​接收方当前可用缓冲区空间​​(单位:字节),接收方通过该字段告知发送方最多可发送多少未确认数据。

         • 16位校验和:发送端填充,CRC校验,不通过则认为数据有问题,此处校验和:TCP首部 + TCP数据

         • 16位紧急指针:表示哪些部分数据是紧急数据

         • 40字节头部选项:可变长扩展区域,用于增强协议功能并适应复杂网络需求。

        TCP协议的十大核心机制共同构建了其可靠传输与高效通信的基础架构,下面我们将对各机制详细讲解

三、TCP协议的十大核心机制

3.1、确认应答(可靠机制)

        发送方每发送一个数据段,接收方需返回 ACK 报文确认接收成功。通过序号(32位)和确认号(32位)标识数据位置,解决网络“后发先至”导致的乱序问题

        在传输数据的过程中,TCP将每个字节的数据都进行了编号,即为序列号

        下图为TCP的载荷部分,因为TCP面向字节流,一个TCP载荷由多个字节构成,编写时每个字节都要分配一个编号,且连续递增

        每一个ACK都带有对应的确认序列号,ACK确认序号隐含表示此前所有数据均已正确接收,如ACK=2001意味着1-2000字节数据全部到达 

         发送方传输数据时,序号字段填写的是载荷部分第一个字节的序号,真正的数据在载荷,如此一来,接收方就可以根据序号对数据进行排序~

后发先至问题

        网络波动在我们生活中很正常,当然在传输过程中也可能遇到一系列情况

 

        TCP在接收方会有“接收缓冲区” (内存,操作系统内核中),先把通过网卡读到的数据放到缓冲区里,后续代码里调用read方法从缓冲区里来读

3.2、超时重传(可靠机制)

        超时重传就是针对丢包的情况做出处理~~ 

        在一段时间后,A未收到B返回的应答,那么A 会再次向B发送一个一样的数据包

        那么,我们如何确定超时的时间呢?

 TCP为了保证无论在任何环境下都能比较高性能的通信,因此会动态计算这个最大超时时间

        • Linux中(BSDUnix和Windows也是如此),超时以500ms为⼀个单位进行控制,每次判定超时重发的超时时间都是500ms的整数倍.

        • 如果重发⼀次之后,仍然得不到应答,等待2*500ms后再进行重传.

        • 如果仍然得不到应答,等待 4*500ms 进行重传.依次类推,以指数形式递增.

        • 累计到⼀定的重传次数,TCP认为网络或者对端主机出现异常,强制关闭连接

3.3、连接管理(可靠机制)

⚽ 建立连接的意义:

         •  投石问路,确认当前通信路径是否畅通.

         •  协商参数,通信双方共同确认⼀些通信中的必备参数数值

        正常通信流程:

        3.1、三次握手

         以上来回三次通信即“三次握手”

目的

        • 初步探索网络的通信链路是否通畅(可靠传输的前提条件)

        • 验证双方的发送能力和接收能力是否正常

        • 协商通信过程的关键信息(序号从几开始,为了避免相邻的两次通信,序号是不从1开始的,而且两次连接传输的序号差别还很大)

3.2、四次挥手

3.4、滑动窗口(效率机制)

        上文我们谈到数据传输过程,每发送一个数据包,都要等一个ACK响应,这种方法确实保证了TCP传输数据的可靠性,但是也是要付出代价滴~,在数据量较大且往返时间长的情况下,这种方法的效率低,性能差

        这样一发一收的方式性能较低,那么我们是否可以一次发多个,一次收多个ACK应答,进行批量传输,发到一定量之后,再等待

        •  窗口大小指的是无需等待确认应答而可以继续发送数据的最大值,上图的窗口大小就是4000个字节 (四个段)

        •  发送前四个段的时候,不需要等待任何ACK,直接发送

        •  收到第⼀个ACK后,滑动窗口向后移动,继续发送第五个段的数据,依次类推

        •  操作系统内核为了维护这个滑动窗口,需要开辟发送缓冲区来记录当前还有哪些数据没有应答,只有确认应答过的数据,才能从缓冲区删掉

        •  窗口越大,则网络的吞吐率就越高

 丢包情况一、数据到达,返回的ACK丢失

 丢包情况二、数据包丢失

        当序号为 1001-2000 的数据包丢失,发送端会一直收到 1001 这样的 ACK,若发送端连续收到 3 次这样重复的确认应答,就会把相应的数据重发一遍,此时接收端收到再次发送的数据后,就会直接返回 7001 的ACK应答 ,因为 2001-7000 的数据已被接收,放入到接收缓冲区中,这种机制被称为"高速重发控制"(也叫"快重传")

超时重传:传输的数据少,没有构成滑动窗口批量传输的形式

快速重传:数据量大,形成了滑动窗口

3.5、流量控制(效率机制) 

        针对滑动窗口机制,窗口越大,效率越高,但是不能 “无限大” ~~,接收端处理数据的速度是有限的,如果发的太快,接收端的缓冲区就会堆满,后面来的数据包就会丢包,继而引发丢包重传等一系列连锁反应

        因此TCP支持根据接收端的处理能力,来决定发送端的发送速度,这个机制就叫做流量控制(Flow Control)

        • 接收端将自己可以接收的缓冲区大小放入TCP首部中的"窗口大小"字段,通过ACK端通知发送端

        • 窗口大小字段越大,说明网络的吞吐量越高

        • 接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送端

        • 发送端接受到这个窗口之后,就会减慢自己的发送速度;

        • 如果接收端缓冲区满了,就会将窗口置为0,这时发送方不再发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端

         接收端就是把窗口大小的信息存放到TCP首部中16位的一个窗口字段,滑动窗口的大小是动态变化的

        零窗口探测​​:当窗口为0时,发送方定期发送1字节探测包,直至接收方恢复可用窗口

16位数字最大表示65535,那么TCP窗口最大就是65535字节嘛,实际上,TCP首部40字节的选项中还包含一个窗口扩大因子M,实际窗口大小就是窗口字段的值左移M位 

3.6、拥塞控制(效率机制)

        刚谈到流量控制是依据接收方处理能力进行限制的,而拥塞控制则是依据传输链路的转发能力,进行限制的

        网络上有大量计算机可能当前的网络状态已经比较拥堵,在不清楚当前网络状态下贸然发送大量数据,很可能会引发问题,故TCP引入慢启动机制,先发少量的数据,摸清当前的网络状态,再决定按照多大的速度进行传输数据


上图仅用于学习,无商业目的

        • 此处引入一个概念程为拥塞窗口

        • 发送开始的时候,定义拥塞窗口大小为1

        • 每次收到⼀个ACK应答,拥塞窗口加1

        • 每次发送数据包的时候,将拥塞窗口和接收端主机反馈的窗口大小做比较,取较小的值作为实际发送的窗口

像上面这样的拥塞窗口增长速度,是指数级别的,"慢启动"只是指初使时慢,但是增长速度非常快

        • 为了不增长的那么快,因此不能使拥塞窗口单纯的加倍

        • 此处引入一个叫做慢启动的阈值

        • 当拥塞窗口超过这个阈值的时候,不再按照指数方式增长,而是按照线性方式增长

        • 当TCP开始启动的时候,慢启动阈值等于窗口最大值

        • 在每次超时重发的时候,慢启动阈值会变成原来的一半,同时拥塞窗口置回1

        少量的丢包,我们触发超时重传,大量的丢包,我们就认为网络堵塞,大概流程如下:

3.7、延时应答(效率机制)

         在前几个TCP机制中,接收方都是在收到数据包时,立即返回ACK应答,特别是在滑动窗口处,我们每次应答还需返回窗口大小,倘若我们多等一会再返回ACK应答,此时接受方的缓冲区内容就会一直被读取,等待的这一段时间后,我们再做出ACK应答,返回的窗口大小就可能比之前的大了,但要注意,不是所有包都可以延时应答

        •  数量限制:每隔N个包就应答⼀次;

        •  时间限制:超过最大延迟时间就应答⼀次;

 3.8、捎带应答(效率机制)

        捎带应答是在TCP延时应答的基础上引入的,通俗来说就是,返回业务数据的时候,顺便把上次的ACK也带过去

        没有延时应答时,返回ACK的时机和返回响应的时机是不同的时机,引入延时应答,ACK的返回可以往后延长一段时间,返回响应的时候就可以把ACK顺便带回去,提高效率~~

        ​​数据与ACK合并​​:在双向通信中,业务数据报文可携带对反向数据的ACK,降低网络负载。例如,服务器响应请求时同时确认客户端数据

3.9、面向字节流与粘包处理(数据处理)

        TCP协议是通过字节流的方式传输,在应用层很容易混淆包与包的界限,从而无法区分哪到哪是一个完整的应用层数据包

        此问题在TCP层次上无解,需要在应用层解决,定义好应用层协议,明确包之间的边界~

        1、约定包与包之间的分隔符(包的结束标记,如TCP回显服务器中的“ \\n ”)

        2、约定包的长度

        而UDP则不存在粘包问题,因为UDP传输的是一整个数据报

3.10、异常处理(可靠性保障)

        进程终止:进程终止会释放文件描述符,仍然可以发送FIN,和正常关闭没有什么区别.

        机器重启:和进程终止的情况相同.

        机器掉电/网线断开:接收端认为连接还在,⼀旦接收端有写入操作,接收端发现连接已经不在了,就会进行reset,即使没有写入操作,TCP自己也内置了一个保活定时器,会定期询问对方是否还在,如果对方不在,也会把连接释放

复位报文:

赞(0)
未经允许不得转载:171主机测评 » TCP协议:现代网络数据传输的守护者——十大核心机制赋能高效可靠通信
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址