【Linux网络】Linux 网络编程:传输层协议TCP(五)

🎬 个人主页艾莉丝努力练剑
专栏传送门 :《C语言》《数据结构与算法》《C/C++干货分享&学习过程记录
Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享

⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平


🎬 艾莉丝的简介:


文章目录

  • 思维导图
  • [1 ~> 滑动窗口机制](#1 ~> 滑动窗口机制)
    • [1.1 滑动窗口的基本概念](#1.1 滑动窗口的基本概念)
    • [1.2 窗口大小协商与滑动原理](#1.2 窗口大小协商与滑动原理)
    • [1.3 滑动窗口的变化特性与越界处理](#1.3 滑动窗口的变化特性与越界处理)
    • [1.4 丢包问题与重传机制](#1.4 丢包问题与重传机制)
  • [2 ~> 拥塞控制](#2 ~> 拥塞控制)
    • [2.1 拥塞控制的基本概念与核心判断](#2.1 拥塞控制的基本概念与核心判断)
    • [2.2 拥塞窗口与慢启动机制](#2.2 拥塞窗口与慢启动机制)
    • [2.3 拥塞避免与拥塞处理](#2.3 拥塞避免与拥塞处理)
  • [3 ~> TCP 性能优化机制](#3 ~> TCP 性能优化机制)
    • [3.1 延迟应答](#3.1 延迟应答)
    • [3.2 捎带应答](#3.2 捎带应答)
  • [4 ~> 面向字节流特性与粘包问题](#4 ~> 面向字节流特性与粘包问题)
    • [4.1 面向字节流的本质](#4.1 面向字节流的本质)
    • [4.2 粘包问题](#4.2 粘包问题)
    • [4.3 粘包问题的解决方案](#4.3 粘包问题的解决方案)
  • [5 ~> TCP 异常情况处理](#5 ~> TCP 异常情况处理)
    • [5.1 进程终止](#5.1 进程终止)
    • [5.2 机器重启](#5.2 机器重启)
    • [5.3 机器掉电 / 网线断开](#5.3 机器掉电 / 网线断开)
    • [5.4 RST 标志位](#5.4 RST 标志位)
  • [6 ~> TCP 报头核心字段与选项](#6 ~> TCP 报头核心字段与选项)
    • [6.1 固定报头核心字段](#6.1 固定报头核心字段)
    • [6.2 常用 TCP 选项](#6.2 常用 TCP 选项)
  • [7 ~> TCP 与 UDP 对比](#7 ~> TCP 与 UDP 对比)
    • [7.1 经典面试题:用 UDP 实现可靠传输](#7.1 经典面试题:用 UDP 实现可靠传输)
    • [7.2 还有一道面试题:HTTP 获取网页的完整过程](#7.2 还有一道面试题:HTTP 获取网页的完整过程)
  • [8 ~> TCP 核心机制总览与总结](#8 ~> TCP 核心机制总览与总结)
    • [8.1 可靠性机制](#8.1 可靠性机制)
    • [8.2 性能优化机制](#8.2 性能优化机制)
    • [8.3 辅助机制](#8.3 辅助机制)
  • 本文总结
  • 结尾


思维导图

导入语

TCP 协议是互联网传输层的基石,它在 IP 协议提供的不可靠数据报服务之上,构建了一套完整的可靠端到端传输体系。从浏览器打开网页到微信发送消息,从文件下载到在线支付,几乎所有的互联网应用都依赖于 TCP 协议的可靠传输能力。

TCP 协议的复杂性源于它的双重目标:既要保证数据传输的绝对可靠,又要在复杂多变的网络环境下尽可能提高传输效率。为了实现这两个目标,TCP 的设计者们引入了数十种精妙的机制,这些机制相互配合,共同构成了 TCP 协议的完整体系。

本文基于 TCP 协议的核心教学内容,全面系统地整理了滑动窗口、拥塞控制、性能优化、面向字节流特性、异常处理等所有关键知识点。每一个机制都从 "是什么、为什么、怎么做" 三个维度进行深入讲解,同时保留了大量便于理解的实例和面试高频考点。无论是课程复习、面试准备还是网络编程实践,本文都能为你提供最全面、最准确的参考。


1 ~> 滑动窗口机制

1.1 滑动窗口的基本概念

滑动窗口是 TCP 协议实现流量控制和批量数据传输的核心机制。它本质上是发送缓冲区中的一个可变大小的发送区间,这个区间内的数据可以连续发送而不需要等待每一个报文的单独应答,从而将 TCP 从 "停等协议" 的低效模式中解放出来,大幅提升了网络吞吐量。

发送缓冲区被滑动窗口逻辑上划分为三个连续的区域:

  • 已发送已确认区:位于窗口左侧,数据已经被接收方成功确认,可以从缓冲区中安全丢弃
  • 滑动窗口区:位于中间,数据已经发送但尚未收到确认,或者可以立即发送
  • 待发送区:位于窗口右侧,数据还不能发送,需要等待窗口滑动后才能进入发送队列

滑动窗口的实际大小由三个因素共同决定,完整的核心公式为:

Plain 复制代码
滑动窗口大小 = min(接收方通告的ACK窗口大小, 拥塞窗口大小, 本地待发送数据量)

1.2 窗口大小协商与滑动原理

TCP 连接建立的三次握手阶段,双方会在 SYN 报文中交换各自的初始窗口大小。因此,当第一次发送应用数据时,发送方已经知道了接收方的初始接收能力,不需要再进行额外的探测。

滑动窗口的滑动通过两个逻辑指针精确控制:

  • win_left:窗口左边界,严格等于接收方返回的最新确认序号 (ACK Seq)。确认序号的含义是 "该序号之前的所有字节都已经被成功接收"。
  • win_right:窗口右边界,等于win_left + 当前窗口大小

当发送方收到一个确认序号为 2001 的 ACK 时,win_left会立即移动到 2001 的位置,同时win_right会根据新的窗口大小重新计算。整个窗口向右滑动,将已确认的数据移出窗口,同时将新的待发送数据纳入窗口。

1.3 滑动窗口的变化特性与越界处理

滑动窗口具有以下不可违背的特性:

  1. 只能整体向右滑动 :由于确认序号是严格单调递增的,win_left永远不会向左移动,因此滑动窗口整体只能向右滑动,不可能回退。
  2. 大小动态可变
    1. 变大:当接收方应用层快速消费数据,接收缓冲区剩余空间增加时,ACK 窗口会变大,滑动窗口随之扩大
    2. 变小:当接收方应用层处理速度跟不上数据到达速度,接收缓冲区剩余空间减少时,ACK 窗口会变小,滑动窗口随之缩小
    3. 不变:当发送方发送的数据量恰好等于接收方应用层消费的数据量时,ACK 窗口大小保持不变,窗口整体右移但大小不变
    4. 为 0:当接收方应用层完全停止读取数据,接收缓冲区被填满时,ACK 窗口变为 0,发送方必须停止发送数据,只能定期发送窗口探测报文
  3. 线性空间越界处理:由于 TCP 序号是 32 位的循环计数器,发送缓冲区在逻辑上被抽象为一个环形空间。通过模运算和算法映射,解决了滑动窗口一直向右滑动导致的线性空间越界问题。

1.4 丢包问题与重传机制

在滑动窗口机制下,所有的丢包问题最终都可以归结为 **"左侧丢失"** 这一种本质情况。无论丢失的是窗口最左侧、中间还是最右侧的报文,接收方都只能返回确认序号为窗口最左侧未收到报文起始序号的 ACK。

例如,如果 1001-2000 的报文丢失了,即使接收方已经成功收到了 2001-7000 的所有后续报文,它也只能连续返回确认序号为 1001 的 ACK。这是 TCP 协议最天才的设计之一,它用最简单的逻辑解决了复杂的乱序和丢包问题。

TCP 提供了两种互补的重传机制:

  1. 快重传机制 :当发送方连续收到 3 个相同的确认序号时,立即重传对应的数据段。这种机制不需要等待超时定时器触发,能够在几十毫秒内恢复丢失的报文,是 TCP 高性能的关键。
  2. 超时重传机制:当发送方在超时时间内没有收到对应报文的 ACK 时,触发超时重传。超时时间会根据 RTT (往返时间) 动态调整。这种机制是 TCP 可靠性的最后一道防线,确保即使在网络极端恶劣的情况下,数据也能最终到达。

快重传和超时重传是完美的互补关系:快重传保证了传输的性能上限,能够快速处理 99% 以上的丢包情况;超时重传保证了传输的可靠性下限,能够处理所有可能的极端情况


2 ~> 拥塞控制

2.1 拥塞控制的基本概念与核心判断

滑动窗口机制完美解决了发送方和接收方之间的流量控制问题,但它没有考虑网络中间路径的承载能力。在实际的互联网中,丢包不一定是因为接收方来不及接收,更常见的原因是网络中间的路由器因为报文积压过多而主动丢弃报文,这种情况就是网络拥塞

TCP 拥塞控制的核心思想是:网络是所有主机共享的公共资源,当网络出现拥塞时,所有主机都必须主动降低发送速率,避免拥塞进一步恶化。如果所有主机在拥塞时都继续重传数据,只会形成 "拥塞→重传→更严重拥塞" 的恶性循环,最终导致整个网络瘫痪。

TCP 通过丢包率来判断网络是否发生拥塞:

  • 少量丢包 (1%~1.5%):属于网络正常波动,只需要重传丢失的报文即可
  • 大量丢包 (≥3%):判定为网络拥塞,必须立即降低发送速率

2.2 拥塞窗口与慢启动机制

为了实现拥塞控制,TCP 引入了 ** 拥塞窗口 (cwnd)** 的概念。拥塞窗口是发送方维护的一个整型变量,它表示在当前网络状态下,发送方最多可以连续发送的数据量。

TCP 采用慢启动机制来安全地探测网络的承载能力:

  1. 连接建立时,拥塞窗口的初始值为 1 个 MSS (最大段大小,通常为 1460 字节)
  2. 每收到一个 ACK 应答,拥塞窗口加 1 个 MSS
  3. 这样,在每个 RTT (往返时间) 内,拥塞窗口就会翻倍,呈现2^n 的指数级增长

慢启动机制的设计极具智慧:

  • 前期慢:刚开始只发送极少量的数据探路,避免在不清楚网络状态的情况下突然发送大量数据导致拥塞
  • 后期快:一旦确认网络没有拥塞,就以指数级速度快速增大发送量,尽快利用网络的全部带宽

2.3 拥塞避免与拥塞处理

为了防止拥塞窗口无限指数增长导致网络拥塞,TCP 引入了慢启动阈值 (ssthresh)的概念。当拥塞窗口的大小超过慢启动阈值时,就不再按照指数方式增长,而是切换为线性增长模式 ,每个 RTT 只增加 1 个 MSS,这个阶段叫做拥塞避免

当网络发生拥塞 (触发超时重传) 时,TCP 会执行以下拥塞处理操作:

  1. 将慢启动阈值 (ssthresh) 设置为当前拥塞窗口大小的一半
  2. 将拥塞窗口 (cwnd) 重置为 1 个 MSS
  3. 重新进入慢启动阶段

拥塞控制的完整生命周期可以总结为:

Plain 复制代码
指数增长(慢启动) → 线性增长(拥塞避免) → 乘法减小(网络拥塞) → 指数增长(慢启动)

这是一个永不停歇的动态探测过程。理论上,如果网络永远不发生拥塞,拥塞窗口会一直增长,直到达到发送方网卡的物理带宽极限或者接收方的最大窗口大小。但在实际网络中,拥塞总是会周期性地发生,拥塞窗口也会随之周期性地升降。


3 ~> TCP 性能优化机制

3.1 延迟应答

延迟应答是 TCP 为了最大化网络吞吐量而设计的基础优化机制。如果接收方收到数据后立即返回 ACK,那么返回的窗口大小只能反映当前接收缓冲区的剩余空间。但如果接收方稍微等待一会儿,应用层可能已经消费了部分数据,接收缓冲区的剩余空间会更大,此时返回的窗口大小也会更大。

例如:

  • 接收缓冲区总大小为 1M
  • 一次收到了 500K 的数据
  • 如果立即应答,返回的窗口大小为 500K
  • 如果等待 200ms,应用层已经消费了这 500K 数据,返回的窗口大小为 1M

窗口越大,网络吞吐量就越大,传输效率就越高。延迟应答的目标就是在保证网络不拥塞的情况下,尽可能增大接收窗口。

为了避免过度延迟导致发送方超时重传,TCP 设置了两个严格的限制条件:

  • 数量限制:每隔 N 个数据包就必须应答一次,主流操作系统中 N=2
  • 时间限制:超过最大延迟时间就必须应答一次,主流操作系统中最大延迟为 200ms

3.2 捎带应答

捎带应答是在延迟应答基础上的进一步优化,它充分利用了 TCP 全双工通信的特性。在大多数客户端 - 服务器交互场景中,通信模式是 "一发一收" 的:客户端发送一个请求,服务器处理后返回一个响应。

在这种模式下,服务器不需要单独发送一个 ACK 报文来确认客户端的请求,而是可以将 ACK 标志位和确认序号捎带在服务器的响应数据报文中一起发送给客户端。这样就减少了网络中一半的独立 ACK 报文数量,显著降低了网络开销。

延迟应答和捎带应答是 TCP 最核心的两个性能优化机制,它们的组合使用能够将 TCP 的传输效率提升数倍。


4 ~> 面向字节流特性与粘包问题

4.1 面向字节流的本质

TCP 是面向字节流 的协议,这是 TCP 与 UDP 最本质的区别之一。面向字节流的核心含义是:TCP 只负责将字节流从一端可靠地传输到另一端,不维护任何应用层的数据边界

当创建一个 TCP socket 时,Linux 内核会为该 socket 同时分配一个发送缓冲区 和一个接收缓冲区

  • 调用write()系统调用时,数据只是从用户空间拷贝到内核的发送缓冲区,然后立即返回。数据什么时候发送、发送多少,完全由内核的 TCP 协议栈决定。
  • 接收数据时,数据首先从网卡驱动程序拷贝到内核的接收缓冲区,然后应用程序通过read()系统调用从接收缓冲区读取数据。

由于内核缓冲区的存在,TCP 程序的读操作和写操作是完全异步的,读写次数不需要一一匹配:

  • 你可以调用 1 次write()发送 100 个字节,也可以调用 100 次write()每次发送 1 个字节
  • 对方可以调用 1 次read()读取 100 个字节,也可以调用 100 次read()每次读取 1 个字节

这种特性就是面向字节流的本质。除了 TCP 之外,Unix 管道、C 语言的标准输入输出 (stdin/stdout) 也都是面向字节流的设计。

需要特别注意的是:UDP 协议只有发送缓冲区,没有真正意义上的接收缓冲区。UDP 收到数据后,如果应用层没有及时读取,数据会被直接丢弃。

4.2 粘包问题

面向字节流的特性带来了一个不可避免的问题:粘包问题 。这里的 "包" 特指应用层的数据包,而不是 TCP 的报文段。

站在传输层的角度,TCP 确实是一个一个报文段传输的,每个报文段都有自己的序号。但站在应用层的角度,看到的只是一串连续的、没有任何边界的字节流。应用程序无法知道从哪个字节开始到哪个字节结束,是一个完整的应用层数据包。

例如:

  • 应用层连续发送了两个数据包:"Hello" 和 "World"
  • TCP 可能将它们合并成一个 TCP 报文段发送:"HelloWorld"
  • 也可能将它们拆分成两个 TCP 报文段发送:"Hel" 和 "loWorld"
  • 还可能拆分成更多的 TCP 报文段发送

无论 TCP 如何拆分和合并,应用层收到的都只是一串连续的字节流,无法区分原来的两个数据包边界。

UDP 协议不存在粘包问题。因为 UDP 报头中有一个 16 位的长度字段,明确标识了每个 UDP 报文的数据长度。UDP 是一个一个完整地将报文交付给应用层的,要么收到完整的 UDP 报文,要么收不到,永远不会出现 "半个" 报文的情况。

4.3 粘包问题的解决方案

解决粘包问题的核心思想非常简单:在应用层明确约定数据包的边界。TCP 协议本身不提供这个功能,必须由应用层协议自己实现。

主流的解决方案有三种:

  1. 定长包:约定所有应用层数据包的长度都是固定的。例如,约定每个数据包都是 128 字节。接收方每次从缓冲区中读取 128 字节,就是一个完整的数据包。这种方式最简单,但灵活性最差,会浪费大量带宽。
  2. 包头长度字段 :在每个数据包的开头,用固定长度的字段 (通常是 2 字节或 4 字节) 表示整个数据包的总长度。接收方先读取长度字段,然后根据长度读取后续的数据包内容。这是最常用、最高效的解决方案,HTTP 协议的Content-Length字段就是这种方式的典型应用。
  3. 特殊分隔符 :在数据包之间插入一个特殊的分隔符,这个分隔符不会出现在数据包的正文中。接收方通过查找分隔符来区分不同的数据包。例如,FTP 协议使用回车换行符 (\r\n) 作为命令的分隔符。这种方式实现简单,但需要扫描整个字节流查找分隔符,效率较低。

5 ~> TCP 异常情况处理

TCP 协议提供了完善的异常处理机制,能够应对各种可能的网络和系统异常:

5.1 进程终止

当通信的一方进程正常终止或异常崩溃时,操作系统会回收该进程的所有文件描述符。当 TCP 连接对应的文件描述符被释放时,内核会自动向对方发送一个 FIN 报文,然后进行正常的四次挥手过程关闭连接。

这种情况和应用层主动调用close()关闭连接没有任何区别,属于正常的连接关闭流程。

5.2 机器重启

当机器正常重启时,操作系统会在关机前依次终止所有正在运行的进程。和进程终止的情况一样,每个 TCP 连接都会收到 FIN 报文,进行正常的四次挥手关闭。

这就是为什么当你打开很多网络应用时,关机速度会变慢的原因之一:操作系统需要花费时间关闭所有的 TCP 连接。

5.3 机器掉电 / 网线断开

当机器突然掉电或者网线被意外断开时,操作系统没有任何机会发送 FIN 报文给对方。此时,对方主机完全不知道连接已经断开,会一直认为连接处于正常状态。

TCP 提供了两种机制来处理这种半开连接问题:

  1. 写入操作触发 RST:如果对方主机尝试向半开连接写入数据,会收到 ICMP 不可达报文,内核会立即发送 RST 报文重置连接。
  2. TCP 保活机制:TCP 内置了一个保活定时器,当连接空闲一段时间后,会自动向对方发送一个不携带任何数据的探测报文。如果连续多次探测都没有收到响应,内核会认为对方已经不可达,然后发送 RST 报文重置连接。

需要特别注意的是:TCP 的保活机制在实际应用中很少使用 。因为它的默认超时时间太长 (通常是 2 小时),无法满足大多数应用的实时性要求。在实际工程中,几乎所有的应用都会在应用层实现自己的保活机制,例如 HTTP 长连接的心跳机制、QQ 的断线重连机制、王者荣耀的挂机检测机制等。

5.4 RST 标志位

RST 是 TCP 报头中的一个重要标志位,它的作用是强制重置连接。当 TCP 收到一个 RST 报文时,会立即释放连接的所有资源,不需要进行四次挥手过程。

RST 报文通常在以下情况下发送:

  • 连接请求到达一个不存在的端口
  • 向已经关闭的连接发送数据
  • 检测到半开连接
  • 应用层需要强制关闭连接

6 ~> TCP 报头核心字段与选项

TCP 报头分为固定部分和可变选项部分,固定部分长度为 20 字节,选项部分最长为 40 字节,因此 TCP 报头的最大长度为 60 字节。

6.1 固定报头核心字段

  • 16 位源端口号 / 16 位目的端口号:标识数据从哪个进程来,到哪个进程去
  • 32 位序号:本报文段所携带数据的第一个字节的序号
  • 32 位确认号:期望收到对方下一个报文段的第一个字节的序号,确认号之前的所有字节都已经被成功接收
  • 4 位首部长度:表示 TCP 报头有多少个 32 位字,因此最大报头长度为 15×4=60 字节
  • 6 位标志位
    • URG:紧急指针是否有效
    • ACK:确认号是否有效
    • PSH:接收方应立即将数据交付给应用层
    • RST:强制重置连接
    • SYN:同步序号,用于建立连接
    • FIN:释放连接
  • 16 位窗口大小:接收方通告的接收窗口大小,用于流量控制
  • 16 位检验和:检测 TCP 报文段在传输过程中是否发生错误
  • 16 位紧急指针:当 URG 标志位有效时,标识紧急数据的结束位置

6.2 常用 TCP 选项

TCP 报头的选项部分用于提供各种扩展功能,以下是最常用的 TCP 选项:

类型 选项名称 功能简介 关键说明
0 EOL (选项列表结束) 标识选项列表的结束 单字节选项,用于填充选项末尾
1 NOP (无操作) 选项之间的填充符 单字节,用于 32 位边界对齐
2 MSS (最大段大小) 通告本端能接收的最大 TCP 数据段大小 仅在 SYN 包中发送,防止 IP 分片
3 Window Scale (窗口扩大因子) 将 16 位窗口大小左移指定位数 仅在 SYN 包中协商,最大支持 1GB 窗口
4 SACK Permitted (允许选择性确认) 告知对端本端支持 SACK 机制 仅在 SYN 包中协商
5 SACK (选择性确认) 告知发送方已收到的非连续数据块列表 支持只重传丢失的报文,而非全部
8 Timestamp (时间戳) 携带发送方时间戳和回显时间戳 用于精确计算 RTT、防止序号回绕 (PAWS)
14 User Timeout (用户超时) 指示本端等待 ACK 的最大时间 超时则自动断开连接,参见 RFC 5482
19/20/29 TCP-AO & MD5 提供数据完整性校验和防伪造保护 MD5 为 RFC 2385,TCP-AO 为替代方案 RFC 5925
30 MPTCP (多路径 TCP) 允许单条连接同时利用多条网络路径 提升带宽利用率与连接冗余性

其中,时间戳选项是现代 TCP 最重要的选项之一。它不仅可以用于精确计算 RTT,从而动态调整超时重传时间,还可以解决 32 位序号回绕问题 (PAWS)。当序号增长到最大值后回绕到 0 时,通过比较时间戳可以轻松区分是新的报文还是旧的重复报文。


7 ~> TCP 与 UDP 对比

TCP 和 UDP 是传输层最重要的两个协议,它们分别代表了两种完全不同的设计哲学:

特性 TCP UDP
连接性 面向连接,需要三次握手建立连接 无连接,不需要建立连接
可靠性 可靠,保证数据按序到达、不丢失、不重复 不可靠,不保证数据一定到达,不保证顺序
开销 大,固定报头 20 字节,最多 60 字节 小,固定报头 8 字节
流量控制 有,滑动窗口机制
拥塞控制 有,慢启动、拥塞避免等机制
传输模式 面向字节流,无数据边界 面向数据报,有明确数据边界
双工性 全双工,同一连接同时收发 全双工
适用场景 文件传输、HTTP/HTTPS、邮件、支付等对可靠性要求高的场景 视频直播、在线游戏、实时通信、DNS、广播等对性能要求高的场景

需要特别强调的是:不能简单地说 TCP 优于 UDP 或者 UDP 优于 TCP。它们是为不同的应用场景设计的不同工具。TCP 将复杂性隐藏在协议栈内部,为应用层提供了简单可靠的传输服务;UDP 则将复杂性交给了应用层,为应用层提供了最大的灵活性和最高的性能。

7.1 经典面试题:用 UDP 实现可靠传输

这是网络编程岗位最经典的面试题之一,其实质是考察对 TCP 可靠性机制的理解程度。要在 UDP 之上实现可靠传输,本质上就是在应用层重新实现 TCP 的核心可靠性机制:

  1. 引入序列号机制:为每个 UDP 数据包分配一个唯一的、连续的序列号。接收方通过序列号判断数据是否重复、是否乱序,并将乱序的数据重新排序。
  2. 引入确认应答机制:接收方收到一个数据包后,向发送方返回一个包含该数据包序列号的 ACK 确认报文。
  3. 引入超时重传机制:发送方发送一个数据包后,启动一个定时器。如果在超时时间内没有收到对应的 ACK 确认报文,就重传该数据包。
  4. 可选扩展:可以进一步实现滑动窗口流量控制、拥塞控制、选择性确认 (SACK) 等机制,从而在 UDP 之上实现一个完整的、高性能的可靠传输协议。

7.2 还有一道面试题:HTTP 获取网页的完整过程

这道面试题艾莉丝单独整理了一篇博客。


8 ~> TCP 核心机制总览与总结

TCP 协议之所以能够成为互联网的基石,是因为它在可靠性和性能之间找到了一个完美的平衡点。我们可以将 TCP 的所有机制分为三大类:

8.1 可靠性机制

这是 TCP 协议的核心,它保证了数据能够在不可靠的网络环境下可靠地传输:

  • 校验和:检测数据在传输过程中的比特错误
  • 序列号:保证数据按序到达,处理重复报文
  • 确认应答:确保对端已经收到了数据
  • 超时重传:丢失的数据会被自动重传
  • 连接管理:通过三次握手建立可靠连接,通过四次挥手安全释放连接
  • 流量控制:防止发送方发送过快导致接收方缓冲区溢出
  • 拥塞控制:防止发送方发送过快导致网络拥塞

8.2 性能优化机制

在保证可靠性的前提下,TCP 引入了大量机制来尽可能提高传输效率:

  • 滑动窗口:实现批量数据传输,将 TCP 从停等协议的低效模式中解放出来
  • 快速重传:不需要等待超时,快速恢复丢失的报文
  • 延迟应答:尽可能增大接收窗口,提高网络吞吐量
  • 捎带应答:将 ACK 与反向数据合并发送,减少网络报文数量

8.3 辅助机制

  • 各类定时器:超时重传定时器、保活定时器、TIME_WAIT 定时器等
  • 报头扩展选项:提供 MSS、窗口扩大、选择性确认、时间戳等各种扩展功能

本文总结

TCP 协议是计算机网络领域最伟大的发明之一。它用软件的方法解决了硬件网络不可靠的问题,为上层应用提供了一个简单、可靠、高效的端到端传输服务。TCP 协议的设计充满了智慧,它的很多思想和方法,如滑动窗口、拥塞控制、超时重传等,已经被广泛应用于其他分布式系统的设计中。

深入理解 TCP 协议,不仅是学习计算机网络的必经之路,也是成为一名优秀后端工程师的必备技能。希望本文能够帮助你全面、系统地掌握 TCP 协议的核心知识点,为你的学习和工作提供有力的支持。


结尾

uu们,本文的内容到这里就全部结束了,艾莉丝在这里再次感谢您的阅读!

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ### 艾莉丝努力练剑 C/C++ & Linux 底层探索者 | 一个正在努力练剑的技术博主 *** ** * ** *** 👀 【关注】 跟随我一起深耕技术领域,见证每一次成长。 ❤️ 【点赞】 让优质内容被更多人看见,让知识传递更有力量。 ⭐ 【收藏】 把核心知识点存好,在需要时随时查、随时用。 💬 【评论】 分享你的经验或疑问,评论区一起交流避坑! 不要忘记给博主"一键四连"哦! "今日练剑达成!" "技术之路难免有困惑,但同行的人会让前进更有方向。" |

结语:希望对学习Linux相关内容的uu有所帮助,不要忘记给博主"一键四连"哦!

往期回顾

【Linux网络】Linux 网络编程:传输层TCP(四)

🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡 ૮₍ ˶ ˊ ᴥ ˋ˶₎ა

相关推荐
小则又沐风a1 小时前
进程篇: 进程概念的补充(了解环境变量和虚拟地址空间)
linux·运维·服务器·c++
无足鸟ICT1 小时前
【RHCA+】toilet命令(生成艺术字)
linux
kebidaixu1 小时前
设备树修改
linux
晚风吹红霞1 小时前
进程调度深度解析:从优先级到O(1)调度算法
linux·运维
say_fall1 小时前
深入理解Linux内核进程调度:从基础概念到O(1)调度算法
linux·运维·服务器·算法·计算机组成
零基础的修炼1 小时前
定长内存池
网络
零点一顿微胖1 小时前
[Agent] 初始化Agent服务 Rust版
开发语言·网络·rust
鹿鸣天涯1 小时前
网规第三版:第9章网络安全部署案例
网络·安全·web安全·软考·网络规划设计师
青梅橘子皮1 小时前
Linux---命令行参数和环境变量
linux·运维·服务器