TCP协议深度解析:格式、应答机制、序号管理、超时重传与报头标记位


🍑个人主页:Jupiter. 🚀 所属专栏:Linux从入门到进阶 欢迎大家点赞收藏评论😊

目录


理解分装与解包

  • 操作系统内可能存在大量还没来得及处理的报文。那么,OS需要将这些没有被处理的报文进行管理,先描述,再组织。

所以,一个报文会有一个描述报文的结构体 struct sk_buff,并且还有一个内存空间,内存空间里面存储的就是报文的数据。所以对OS内报文的管理就变成了对链表的增删查改。

data就指向报文的数据存放的起始位置,head指针指向报头的起始位置,其中还包含有tail指针等等。

所谓的封装,实际上就是该类型的报头的结构体对象的拷贝,改变head指针的位置
所谓的解包,就是强转加改变head的位置

TCP 协议

TCP 全称为 "传输控制协议(Transmission Control Protocol"). 人如其名, 要对数据的传输进行一个详细的控制;

TCP 协议段格式

  • 源/目的端口号: 表示数据是从哪个进程来, 到哪个进程去;
  • 32 位序号/32 位确认号: 后面会详细介绍;
  • 4 位 TCP 报头长度: 表示该 TCP 头部有多少个 32 位 bit(有多少个 4 字节); 所以TCP 头部最大长度是 15 * 4 = 60字节,报头(除了选项)只占用了20字节,即选项最大可以占用40字节,并且必须是4字节的整数倍。(为0101=4的时候,即标识没有选项)
  • 6 位标志位:位段,每一个标记位只有一个比特位)
    • SYN: 请求建立连接; 我们把携带 SYN 标识的称为同步报文段
    • ACK: 确认号是否有效
    • PSH: 提示接收端应用程序立刻从 TCP 缓冲区把数据读走
    • URG: 紧急指针是否有效
    • RST: 对方要求重新建立连接; 我们把携带 RST 标识的称为复位报文段
    • FIN: 通知对方, 本端要关闭了, 我们称携带 FIN 标识的为结束报文段
  • 16 位窗口大小: 后面会详细介绍
  • 16 位校验和: 发送端填充, CRC 校验. 接收端校验不通过, 则认为数据有问题. 此处的检验和不光包含 TCP 首部, 也包含 TCP 数据部分.
  • 16 位紧急指针: 标识哪部分数据是紧急数据; (后面也详细介绍)
  • 40 字节头部选项: 暂时忽略;

确认应答(ACK)机制

客户端和服务器怎么知道对方是否收到了自己发送的报文了呢?

  • 这就要引出确认应答机制了。

当发送端(如计算机A)发送一个TCP报文段给接收端(如计算机B)时,它会等待接收端的确认应答。这个确认应答是一个ACK报文段,其中包含了接收端期望收到的下一个报文段的第一个字节的序号(即确认序号)。

但是对于这种,每发一条消息都会应答一下效率太低了,TCP真实的发送消息的模式是:客户端可以同时向服务器发送多条报文,未来服务器会同时收到很多报文,这样服务器就可以同时发送多个应答。这样可以提高发送的效率。

序号与确认序号

一次发送多条信息,怎么保证发送的顺序与收到的顺序一致呢?

  • TCP 将发送缓冲区的数据的每个字节的数据都进行了编号. 即为序列号。
  • 客户端发送数据给服务端的时候,每条数据都带有一个特殊的序号,也就是TCP报头中的32位序号,服务端收到该信息后,给客服端进行发送确认应答的时候,也会带上相应的确认序号(也就是TCP报头中的32位确认序号)。确认序号一般是收到的报文的报头里序号的值+1比如:收到的报文的报头里序号为1000,则对应的应答的报文的确认序号就应该的是1000+1 = 1001;1001的确认序号表示的是,序号之前的内容我已经收到了,下次发送请从确认序号开始。

  • 每一个 ACK 都带有对应的确认序列号, 意思是告诉发送者, 我已经收到了哪些数据; 下一次你从哪里开始发。

  • 双方在互相发消息的时候,都是基于报文发的,都会携带相应的报头,这里谈的是传输层TCP协议,就是要携带TCP的报头的,可以是不携带数据的,但是至少带有一个完整的报头。

序号与确认序号的意义

序号,在TCP协议中,该序号表示该报文段中数据的第一个字节在整个数据流中的位置。这个序号用于确保数据的顺序性和完整性。TCP协议通过为每个数据包分配一个唯一的序号,来确保接收方能够按照正确的顺序重组数据,并且能够检测到是否有数据丢失。

  • 唯一性:每个数据包的序号都是唯一的,这有助于接收方区分不同的数据包。
  • 顺序性:序号保证了数据包的顺序,接收方可以根据序号将数据包重新排序,以恢复原始数据的顺序。
  • 完整性:通过序号,接收方可以检测到数据包的丢失或重复,从而请求发送方重传丢失的数据包。
确认序号的意义

确认序号,是接收方向发送方发送的确认消息中包含的一个字段。它用于告知发送方接收方已经成功接收到的数据的序号。确认序号的存在,是TCP协议实现可靠传输的关键机制之一。

  • 可靠性:确认序号确保了数据的可靠传输。当接收方成功接收到数据包后,它会向发送方发送一个包含确认序号的确认消息,以告知发送方哪些数据已经被成功接收。
  • 流量控制:通过确认序号,接收方还可以控制发送方的发送速率,防止网络拥塞。如果接收方的缓冲区已满,它可以通过延迟发送确认消息或调整确认序号来减缓发送方的发送速率。
  • 有序性:确认序号还保证了数据包的有序性。接收方会按照序号的顺序接收数据包,并在确认消息中包含已接收到的最高序号的数据包。这样,发送方就可以知道哪些数据包已经被接收,哪些还需要重传。

捎带应答

TCP(传输控制协议)中的捎带应答是一种优化机制,旨在提高网络传输效率。捎带应答建立在延时应答的基础上,通过将原本需要单独发送的确认应答(ACK)报文与其他数据报文合并发送,从而减少了网络中的报文数量,降低了网络拥塞的可能性,并提高了整体传输效率。

捎带应答的基本原理

在TCP协议中,当接收端收到发送端发送的数据后,需要返回一个确认应答(ACK)报文给发送端,以告知发送端数据已被成功接收。通常情况下,这个ACK报文是单独发送的,即每收到一定数量的数据就返回一个ACK。然而,在捎带应答机制中,接收端会等待一段时间(这个时间通常是根据网络状况和应用需求来设定的),看是否有其他数据需要发送给发送端。如果有,接收端就会将ACK报文与这些数据合并,形成一个包含数据和确认信息的复合报文发送给发送端。

捎带应答的优势
  • 减少报文数量:通过合并ACK报文和其他数据报文,减少了网络中的报文数量,降低了网络拥塞的可能性。
  • 提高传输效率:由于减少了报文数量,网络的带宽利用率得到了提高,从而加快了数据传输的速度。
  • 降低延迟:在某些情况下,捎带应答可以减少发送ACK报文所需的等待时间,从而降低了传输延迟。

既是应答,又携带了数据。可以提高效率。其中在捎带应答里面会同时使用序号和确认序号

超时重传机制

  • 主机 A 发送数据给 B 之后, 可能因为网络拥堵等原因, 数据无法到达主机 B;
  • 如果主机 A 在一个特定时间间隔内没有收到 B 发来的确认应答, 就会进行重发;

但是, 主机 A 未收到 B 发来的确认应答, 也可能是因为 ACK 丢失了;

因此主机 B 会收到很多重复数据. 那么 TCP 协议需要能够识别出那些包是重复的包, 并且把重复的丢弃掉.

  • 这时候我们可以利用前面提到的序列号, 就可以很容易做到去重的效果.

那么, 如果超时的时间如何确定?

  • 最理想的情况下, 找到一个最小的时间, 保证 "确认应答一定能在这个时间内返
    回".
  • 但是这个时间的长短, 随着网络环境的不同, 是有差异的.
  • 如果超时时间设的太长, 会影响整体的重传效率;
  • 如果超时时间设的太短, 有可能会频繁发送重复的包;

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

  • Linux 中(BSD Unix 和 Windows 也是如此), 超时以 500ms 为一个单位进行控制, 每次判定超时重发的超时时间都是 500ms 的整数倍.
  • 如果重发一次之后, 仍然得不到应答, 等待 2*500ms 后再进行重传.
  • 如果仍然得不到应答, 等待 4*500ms 进行重传. 依次类推, 以指数形式递增.
  • 累计到一定的重传次数, TCP 认为网络或者对端主机出现异常, 强制关闭连接.

TCP报头标记位

在通信的时候,会存在很多不同类型的报文,设置标记位,是为了通信双方可以根据不同的报文类型去实施下一步操作。

TCP报头中包含标记位(也称为标志位或控制位),它们用于控制和管理TCP连接的各种状态和操作,确保数据的可靠传输和连接的正确管理。以下是TCP报头中标记位的作用:

  1. SYN(Synchronize)
    作用:用于建立连接。当一个TCP客户端希望与服务器建立连接时,会将SYN标志位置为1,并发送一个带有SYN标志位的数据包。这是TCP三次握手过程中的第一步,用于同步双方的初始序列号
  2. ACK(Acknowledgment)
    作用:用于确认收到数据。当一个TCP数据包携带ACK标志位时,表示接收方已经成功收到之前的数据包,并发送了一个确认应答。
    意义:ACK机制保证了TCP传输的可靠性,通过确认机制,发送方可以确保数据已被接收方正确接收,从而避免数据丢失或重复传输。
    3. FIN(Finish)
    作用:用于关闭连接。当一个TCP连接的一方希望关闭连接时,会将FIN标志位置为1,并发送一个带有FIN标志位的数据包。
    意义:FIN的存在使得TCP连接可以优雅地关闭,通过发送FIN数据包,双方可以确认连接的终止,并释放相关资源。
  3. RST(Reset)
    作用:用于重置连接。当一个TCP连接发生错误或异常时,可以发送一个带有RST标志位的数据包来重置连接,中断通信。
    意义:RST机制提供了一种快速恢复机制,当连接出现严重问题时,可以立即中断连接,避免错误状态的持续和资源的浪费。
  4. PSH(Push)
    作用:用于立即传输数据。当一个TCP数据包携带PSH标志位时,表示发送方希望立即将数据传输给接收方,而不缓存或等待其他数据。如果接收端缓冲区的大小一直没有改变,也就是一直 没有被读走,那么发送端可以催促接收端主机尽快将数据读走。
    意义:PSH机制提高了数据传输的实时性,使得重要或紧急的数据可以优先传输,减少了数据的等待时间。
  5. URG(Urgent)
    作用:用于指示紧急数据。当一个TCP数据包携带URG标志位时,表示其中包含了紧急数据,需要优先处理。(比如需要让服务端将之前的报文放弃处理等),常常与16位紧急指针一起使用,代表的是紧急数据在报文数据中的偏移量。在TCP中,紧急数据只有一个字节。也就是这16位紧急指针指向的是一个字节,常常是约定好的状态码,错误码等,这一个字节可以被上层优先读取,根据这个字节的内容,上层从而知道下一步的动作。
    意义:URG机制确保了紧急数据能够得到及时处理,提高了数据传输的灵活性和效率。

相关推荐
岳不谢2 分钟前
VPN技术-VPN简介学习笔记
网络·笔记·学习·华为
编程修仙8 分钟前
Collections工具类
linux·windows·python
follycat11 分钟前
信息收集--CDN绕过
网络·安全·网络安全
芝麻团坚果24 分钟前
对subprocess启动的子进程使用VSCode python debugger
linux·ide·python·subprocess·vscode debugger
战术摸鱼大师26 分钟前
计算机网络-理论部分(二):应用层
计算机网络
写点什么啦31 分钟前
[debug]不同的window连接ubuntu的vscode后无法正常加载kernel
linux·vscode·ubuntu·debug
wellnw38 分钟前
[ubuntu]编译共享内存读取出现read.c:(.text+0x1a): undefined reference to `shm_open‘问题解决方案
linux·ubuntu
不爱学习的YY酱40 分钟前
【操作系统不挂科】<CPU调度(13)>选择题(带答案与解析)
java·linux·前端·算法·操作系统
DC_BLOG41 分钟前
Linux-Nginx虚拟主机
linux·运维·nginx