TCP(一)

本文深入解析TCP协议,从首部格式、应答机制、超时重传、拥塞控制(慢启动、快速重传与恢复)、滑动窗口等方面,阐述TCP如何确保数据的完整、可靠传输。并探讨了紧急数据、校验值和标志位的作用,为理解TCP的可靠性打下基础。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

TCP协议是传输层的重要协议,TCP协议保证将数据包完整、可靠地送达对端,是网络中最重要的协议之一,本文我们结合TCP的首部格式来了解TCP。

TCP的首部格式

TCP首部包括20bytes的固定字段和64bytes的可选字段(如下图),16位的源端口号和目的端口号是传输层的基本要求,下面我们通过这些字段来理解TCP的机制。
在这里插入图片描述

应答

TCP为每个数据包添加自增的32位序列号,在接收到数据包时,TCP也需要根据包的序列号向对端发送应答,使用client-server模型,可以通过下图来表达这个过程,其中序列号使用seq来表示,应答序号使用ack来表示。
在这里插入图片描述
当然,在实际的网络通信过程中,有很多包在收发,ack应答通常和数据包一起发送,提高发送效率,因此这个通信过程应该是这样:
在这里插入图片描述
从上图可以发现规律:每个ack的值就是收到的上一个数据包的seq+1,而seq的值就是上一个数据包的ack值,不妨这样理解:数据包ack的值就是希望收到的下一个包的序列号,因此当确定包的seq值时,就看上一个包希望收到的包是哪个序号的包;当确定包的ack值时,就看现在收到了那些连续的序列号,将缺失的最小的序列号作为ack值。

超时重传

由于IP层协议是不保证可靠的,因此TCP接收到的数据包经常会遇到丢包的情况,此时将不会收到对端发送的对应的ack包,当超过一定时间,TCP认为这个包在网络中丢失了,将重传这个包。
在这里插入图片描述
超时重传存在的问题是如何计算定时器计时的时间,超时重传时间被称为RTO,RTO是基于RTT来计算的,而RTT指的是数据包在从发送到接收到该数据包对应的确认包所需的时间。
在这里插入图片描述
RTO的计算过程如下:

  1. 通过下面的公式计算SRTT:
    在这里插入图片描述
  2. 计算SRTT金额RTT的差值:
    在这里插入图片描述
  3. 计算RTO:
    在这里插入图片描述

目前在linux下,α=0.125, β=0.25, u=1,a=4。
在网络通信过程中,一个数据包传送完后,等待该数据包的应答到达以后再传输下一个包需要RTT时间,这时间内通常会继续发送数据包以提高发送效率,而对端在发送应答时,如果已经接收到了多个连续的数据包,则可以多个数据包一起应答,如下图:
在这里插入图片描述
在上图中,如果seq=x+2的包丢失了,那么将发生下面的情况:
在这里插入图片描述
无论后续接收到的包序号是多少,只要缺少了seq为x+2的数据,server每收到一个seq>x+2的包,就发送一次ack=x+2,至于后续收到的seq=x+3和x+4的包,可能被直接丢弃,也可能放在缓存中,等待接收seq=x+2的数据包后发送ack=x+5的包。

拥塞控制

慢启动和拥塞避免

TCP在三次握手时,会确定慢启动门限的值ssthresh和拥塞窗口的值cwnd,在刚启动时cwnd的值为1,发送方每收到一个新报文的确认,就将cwnd的值翻倍,当cwnd的值不小于ssthresh时,为了避免网络的压力太大,将进入拥塞避免状态,即每收到一个新报文的确认,就将cwnd的值线性增加,直到遇到网络拥塞。

快速重传和快速恢复

在讨论超时重传时,我们看到当丢失一个包时,对端将一直重传相同的ack,当在一个RTO时间内接收到了三个相同的冗余ack包,TCP将启动快速重传,直接重传这个ack请求的数据包,而不等待超时重传,这样做的有点也就是避免超时重传等待时间的消耗。注意这里是接收到三个冗余ack,也就是一共接收到四个相同的ack。触发超时重传后,TCP连接将进入快速恢复状态。
TCP目前使用的快速恢复算法是reno算法,reno算法使进入快速恢复状态将ssthread变为之前的一半,然后线性继续线性增加。
假设ssthresh被初始化为20,那么cwnd可能的变化情况如下:
在这里插入图片描述
勘误:根据《计算机网络-自顶向下方法》的描述,遇到网络拥塞时,reno算法将ssthread变为当前拥塞窗口(cwnd)的一半,而cwnd变为ssthread+3,上图画的有些错误。

滑动窗口

TCP首部中包含16bit的滑动窗口,这指示了当前缓冲区可以接纳多大容量的数据,对端将根据这个窗口大小发送相应大小的数据包。
应用程序调用send()发送tcp报文时,报文并不会立马被发到对端,这是因为tcp是一种流式协议,当程序调用send(),报文会被加入到内核中的缓冲区中,内核会将缓冲区中的数据按照滑动窗口的大小发送到对端,对端接收到数据以后,先存入内核缓冲区中,再提交到应用程序。
在这里插入图片描述
随着数据的发送与接收,缓冲区的大小在不停的变化,因此通过窗口大小字段控制两端传输数据量,这种发送次数与接收次数不相等的传输协议称为流式协议。
滑动窗口和拥塞窗口都是控制流量的方法,但滑动窗口考虑的是传输两端的窗口大小,而拥塞控制考虑的是网络传输路径上的拥塞情况,实际TCP通常取滑动窗口和拥塞窗口中较小的作为发送窗口的大小。

校验值和紧急数据

TCP首部字段还包括16位校验值,校验值由发送端根据TCP首部和数据计算,接收端接收后,可以根据校验值计算数据包与发送时是否一致,如果不一致则直接丢弃数据包。
16位紧急指针用于指示紧急数据在字节流中的位置,在数据传输的过程中,由于缓冲区的存在,数据不会马上被发送,接收端也不会马上传递给应用层,当有数据希望被立刻传输时,可以使用TCP发送带外数据。
当发送带外数据时,需要标识出数据在字节流中的位置,这通过紧急指针来计算:
带外数据字节号 = TCP报文序号 + 紧急指针 - 1

标志位

TCP首部字段中还包括6个标志位,标志位的作用是标识对应的字段有效。
在这里插入图片描述

  • URG标志位为1时,表明紧急指针有效,此时根据紧急指针可以找到带外数据;
  • ACK标志位为1时,表明确认号有效,此时32位确认号标识下一个希望收到包的序号;
  • PSH标志位标识接收到当前报文后PUSH到应用进程,例如当发送的包大小为4096bytes时,假设被拆分成四个包发送,最后一个包带上PSH标识,则对端接收到最后一个包时上应用层递交缓冲区数据;
  • RST标志位为复位标识,当TCP连接出现异常,如一端关闭时,关闭的一端会向对端发送一个RST复位报文;
  • SYN标志位标识这个报文是握手报文;
  • FIN标志为标识这个报文是挥手报文。

总结

本文介绍了TCP固定首部字段,并通过这些字段介绍了TCP的特性,TCP正是通过这些特性来保证将数据可靠地送达对端,下篇文章将介绍TCP经典的三次握手和四次挥手相关的知识。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值