一、TCP的定位与核心特性

TCP(Transmission Control Protocol,传输控制协议)是TCP/IP协议栈中传输层的核心协议,与UDP(用户数据报协议)共同承担端到端数据传输功能。其设计目标是在不可靠的IP网络上提供可靠、有序、面向连接的字节流服务,是互联网中绝大多数应用(如HTTP、FTP、SMTP等)的基础。

与UDP相比,TCP的核心特性差异如下:

  • 面向连接:通信前需通过“三次握手”建立连接,结束后需“四次挥手”释放连接;UDP无连接。
  • 可靠传输:通过序号、确认、重传等机制确保数据不丢失、不重复、按序到达;UDP不保证可靠性。
  • 字节流服务:将应用层数据视为连续字节流,无消息边界;UDP保留消息边界。
  • 流量控制与拥塞控制:通过滑动窗口避免接收方缓冲区溢出,通过拥塞算法避免网络拥塞;UDP无此类机制。
  • 适用于场景:对可靠性要求高(如文件传输、网页加载);UDP适用于实时性要求高(如视频通话、游戏)。
二、TCP报文结构

TCP报文由首部数据两部分组成,首部最小20字节,最大60字节(含选项字段)。各字段含义如下:

字段长度(字节)含义
源端口/目的端口2/2标识发送端和接收端的应用进程(如HTTP默认80端口)。
序号(Sequence Number)4本报文数据段第一个字节的序号(用于按序重组和去重)。
确认号(Acknowledgment Number)4期望接收的下一字节序号(仅当ACK=1时有效,即确认已收到序号≤(确认号-1)的数据)。
数据偏移(Header Length)4位表示TCP首部长度(以32位字为单位,最小值5(20字节),最大值15(60字节))。
保留位6位预留未来使用,目前需设为0。
控制位(Flags)6位共6个标志位:URG(紧急指针有效)、ACK(确认号有效)、PSH(推数据至应用层)、RST(重置连接)、SYN(同步序号,建立连接)、FIN(终止连接)。
窗口大小(Window)2字节接收窗口(rwnd),告知发送方可接收的字节数(流量控制核心字段)。
校验和(Checksum)2字节用于检测报文段在传输中是否损坏(覆盖伪首部、TCP首部、数据)。
紧急指针(Urgent Pointer)2字节当URG=1时有效,指示紧急数据在报文段中的偏移量(紧急数据优先处理)。
选项(Options)0-40字节可选字段,如MSS(最大报文段长度)、SACK(选择确认)、Window Scale(窗口扩大因子)等。
三、TCP连接管理

TCP是“面向连接”的协议,连接管理包含建立连接(三次握手)释放连接(四次挥手) 两个过程,通过控制位(SYN、ACK、FIN)实现。

1. 三次握手(建立连接)

三次握手的目标是:① 确保双方收发能力正常;② 协商初始序号(ISN);③ 同步连接状态。流程如下:

  • 第一次握手:客户端 → 服务器
    发送SYN报文(SYN=1,ACK=0),携带客户端初始序号ISN_c(如x)。此时客户端进入SYN_SENT状态。

  • 第二次握手:服务器 → 客户端
    服务器收到SYN后,回复SYN+ACK报文(SYN=1,ACK=1),携带服务器初始序号ISN_s(如y),并确认客户端序号(确认号=ISN_c+1=x+1)。此时服务器进入SYN_RCVD状态。

  • 第三次握手:客户端 → 服务器
    客户端收到SYN+ACK后,发送ACK报文(ACK=1),确认服务器序号(确认号=ISN_s+1=y+1)。此时客户端进入ESTABLISHED状态;服务器收到ACK后也进入ESTABLISHED状态,连接建立。

在这里插入图片描述

为何需要三次握手?

  • 防止“过期连接请求”干扰:若客户端的SYN报文因网络延迟到达服务器,服务器会误以为是新连接并回复SYN+ACK。若仅两次握手,服务器会直接建立连接并等待数据,但客户端已丢弃该过期请求,导致服务器资源浪费。三次握手通过客户端的最终ACK,确保双方确认“当前连接有效”。

用最简单的例子解释为什么需要三次握手:
A: 喂,能听见吗?
B: 能听见,你能听见我吗?
A: 能听见。

在这里插入图片描述

2. 四次挥手(释放连接)

TCP支持“半关闭”(一方关闭发送后仍可接收数据),因此释放连接需四次交互:

  • 第一次挥手:客户端 → 服务器
    客户端主动关闭,发送FIN报文(FIN=1,ACK=1),表示不再发送数据(但可接收),携带序号u(最后发送字节的序号+1)。客户端进入FIN_WAIT_1状态。

  • 第二次挥手:服务器 → 客户端
    服务器收到FIN后,回复ACK报文(ACK=1),确认号=u+1,告知客户端“已收到关闭请求”。服务器进入CLOSE_WAIT状态,客户端进入FIN_WAIT_2状态(等待服务器剩余数据)。

  • 第三次挥手:服务器 → 客户端
    服务器发送完剩余数据后,发送FIN报文(FIN=1,ACK=1),携带序号v(服务器最后发送字节的序号+1),确认号=u+1(与第二次挥手一致)。服务器进入LAST_ACK状态。

  • 第四次挥手:客户端 → 服务器
    客户端收到FIN后,回复ACK报文(ACK=1),确认号=v+1,客户端进入TIME_WAIT状态;服务器收到ACK后进入CLOSED状态。客户端等待2MSL(最大报文段寿命,通常为1-2分钟)后,也进入CLOSED状态,释放连接。

在这里插入图片描述

四次挥手:
A:再见
B:收到
B:再见
A:收到

关键细节

  • 为何四次挥手? 第二次挥手(ACK)和第三次挥手(FIN)无法合并,因为服务器可能还有数据需发送(半关闭状态)。
  • TIME_WAIT状态:持续2MSL(确保最后一个ACK被服务器收到;防止旧报文干扰新连接)。若服务器未收到ACK,会重发FIN,客户端需在TIME_WAIT内处理。
3. TCP状态机

连接管理的状态转换可通过状态机描述,核心状态包括:

  • 客户端:CLOSEDSYN_SENTESTABLISHEDFIN_WAIT_1FIN_WAIT_2TIME_WAITCLOSED
  • 服务器:CLOSEDLISTENSYN_RCVDESTABLISHEDCLOSE_WAITLAST_ACKCLOSED

异常状态:RST(重置连接,用于处理错误,如连接不存在时强制关闭)。

四、TCP可靠传输机制

TCP通过多重机制确保数据“可靠传输”(不丢失、不重复、按序到达),核心包括序号与确认超时重传快速重传与恢复选择确认(SACK) 等。

1. 序号与确认机制
  • 序号:每个字节数据分配唯一序号(初始为ISN,后续按字节递增)。例如,若ISN=100,发送50字节数据,序号为100-149,下一个序号为150。
  • 确认号:采用“累计确认”,表示“已正确接收序号≤(确认号-1)的所有数据”,期望接收确认号对应的字节。例如,收到序号100-149的数据,确认号为150。
2. 超时重传

当发送方未在规定时间内收到确认,会重传该数据,关键是超时时间(RTO) 的计算:

  • RTO需动态调整(基于RTT,往返时间):
    • 样本RTT(SampleRTT):单次报文往返时间;
    • 平滑RTT(SRTT):SRTT = (1-α)×SRTT + α×SampleRTT(α通常为0.125);
    • RTT偏差(RTTVAR):RTTVAR = (1-β)×RTTVAR + β×|SampleRTT - SRTT|(β通常为0.25);
    • 最终RTO = SRTT + 4×RTTVAR(确保97%的RTT落在RTO内)。
3. 快速重传与快速恢复
  • 快速重传:当发送方收到3个重复确认(确认号相同),无需等待超时,立即重传未被确认的报文(推断该报文已丢失)。
  • 快速恢复:重传后不执行慢启动(避免网络拥塞加剧),而是将拥塞窗口(cwnd)设为慢启动阈值(ssthresh),直接进入拥塞避免阶段。
4. 选择确认(SACK)

累计确认的缺陷:若中间报文丢失,后续报文即使到达也无法被单独确认。SACK通过选项字段告知发送方“已接收的非连续数据块”,发送方仅重传丢失部分。例如,接收方收到1-100、201-300,SACK会标记这两个区间,发送方仅重传101-200。

五、流量控制

流量控制用于防止发送方速率超过接收方处理能力,基于“滑动窗口机制”,通过接收窗口(rwnd)实现。

1. 滑动窗口原理
  • 发送窗口:发送方可发送但未确认的数据范围,大小由接收窗口(rwnd)和拥塞窗口(cwnd)共同决定(发送窗口=min(rwnd, cwnd))。
  • 接收窗口:接收方缓冲区剩余空间(rwnd = 接收缓冲区大小 - 已接收未读取数据量),通过TCP报文的“窗口大小”字段告知发送方。

窗口分为三部分:

  • 已发送且确认:序号≤已确认序号;
  • 已发送未确认:序号在已确认序号+1 至 发送窗口左沿-1;
  • 未发送但可发送:序号在发送窗口左沿 至 发送窗口右沿-1;
  • 不可发送:序号≥发送窗口右沿。
2. 窗口动态调整
  • 接收方随缓冲区使用情况更新rwnd(若缓冲区满,rwnd=0);
  • 发送方根据rwnd调整发送窗口:若rwnd=0,发送方停止发送,定期发送“零窗口探测报文”(1字节),接收方回复新的rwnd后恢复发送。
六、拥塞控制

拥塞控制用于防止发送方速率超过网络承载能力(避免网络拥塞导致丢包),核心是通过调整拥塞窗口(cwnd) 控制发送速率,涉及四大算法:慢启动、拥塞避免、快重传、快恢复。

1. 核心参数
  • 拥塞窗口(cwnd):发送方根据网络拥塞状态动态调整的窗口(初始为1MSS);
  • 慢启动阈值(ssthresh):cwnd增长的临界点(初始为较大值,如65535字节)。
2. 算法流程
  • 慢启动:cwnd从1MSS开始,每收到一个确认(或每经过一个RTT),cwnd翻倍(指数增长),直到cwnd达到ssthresh,进入拥塞避免阶段。
  • 拥塞避免:cwnd每经过一个RTT增加1MSS(线性增长),降低拥塞风险。
  • 拥塞处理
    • 若超时重传(严重拥塞):ssthresh = cwnd/2,cwnd重置为1MSS,重新慢启动;
    • 若收到3个重复确认(轻度拥塞):触发快重传,ssthresh = cwnd/2,cwnd = ssthresh,进入拥塞避免(快恢复)。
七、其他重要特性
  1. 面向字节流:TCP将应用数据视为连续字节流,无消息边界,应用层需自行处理数据分割(如通过长度字段或分隔符)。
  2. 最大报文段长度(MSS):TCP报文段最大数据部分长度(MSS = MTU - IP首部长度 - TCP首部长度,以太网中通常为1460字节),在三次握手的SYN报文中协商。
  3. Nagle算法:减少小报文数量(如连续发送多个1字节数据),规则是:未确认数据时,仅当数据达MSS或收到确认,才发送。可通过TCP_NODELAY选项关闭(适用于实时性场景,如SSH)。
  4. 延迟确认:接收方不立即回复ACK,而是延迟500ms(或在发送数据时一并确认),减少ACK数量。若500ms内收到新数据,会合并确认。
八、常见问题与优化
  1. 粘包问题:TCP字节流无边界,导致应用层收到的数据可能合并(粘包)或拆分。解决方法:

    • 固定长度:每个消息固定大小;
    • 分隔符:用特殊字符(如\r\n)分隔消息;
    • 长度前缀:消息头部包含长度字段。
  2. TIME_WAIT积累:高并发场景下,大量TIME_WAIT状态连接会占用端口。优化方案:

    • 开启SO_REUSEADDR:允许端口快速复用;
    • 缩短TIME_WAIT时长(如调整net.ipv4.tcp_fin_timeout)。
  3. 拥塞控制优化:传统算法(如Reno)在高带宽延迟网络(如卫星链路)效率低,现代算法如BBR(基于带宽和延迟)、CUBIC(基于三次函数增长)可提升性能。


TCP是互联网可靠传输的基石,通过三次握手建立连接、四次挥手释放连接,结合序号确认、超时重传、SACK等机制确保可靠性,通过滑动窗口实现流量控制,通过慢启动、拥塞避免等算法实现拥塞控制。理解TCP的核心机制,对网络编程、性能优化及问题排查至关重要。其设计兼顾了可靠性与效率,是计算机网络中最复杂且应用最广泛的协议之一。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/93043.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/93043.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/93043.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

week1-[分支嵌套]公因数

week1-[分支嵌套]公因数 题目描述 给定 444 个正整数 a,b,c,ka,b,c,ka,b,c,k。如果 a,b,ca,b,ca,b,c 都是 kkk 的倍数,那么称 kkk 是 a,b,ca,b,ca,b,c 的公因数。否则如果某两个数都是 kkk 的倍数,那么称 kkk 是这两个数的公因数。问 kkk 是哪些数的公因…

C#枚举/结构体讲一讲

先展示一段简单代码// 定义枚举 public enum thisday {吃饭,不吃 }// 定义结构体 public struct person {public string name;public int age;public thisday zhuangtai; // 使用枚举类型作为字段 }static void Main(string[] args) {// 创建结构体实例person thisperson;thisp…

C++-setmap详解

Cset&map 1. 序列式容器和关联式容器 1.1 序列式容器 序列式容器按照线性顺序存储元素,元素的位置取决于插入的时间和位置,与元素的值无关。 主要特点:元素按插入顺序存储可以通过位置(索引)直接访问元素不自动排序…

解决程序连不上RabbitMQ:Attempting to connect to/access to vhost虚拟主机挂了的排错与恢复

前言:在分布式系统里,RabbitMQ作为消息中间件,是服务间通信的关键纽带。但实际使用中,程序连接RabbitMQ失败的情况时有发生。本文结合真实报错,细致呈现从问题发现到解决的完整排错思路,还会深入讲解Rabbit…

K8S中如何配置PDB(Pod Disruption Budget)

1. PDB 核心概念作用:控制自愿中断(如节点升级、缩容)期间,应用的最小可用副本数或最大不可用比例。关键参数:minAvailable:必须保持运行的 Pod 数量(如 2 或 50%)。maxUnavailable&…

从 0 到 1:用 MyCat 打造可水平扩展的 MySQL 分库分表架构

一、为什么要分库分表? 单机 MySQL 的极限大致在:维度经验值单表行数≤ 1 000 万行(B 树三层)单库磁盘≤ 2 TB(SSD)单机 QPS≤ 1 万(InnoDB)当业务继续增长,数据量和并发…

电池模组奇异值分解降阶模型

了解如何将奇异值分解 (SVD) 降阶模型 (ROM) 应用于电池模块热模拟。挑战随着电池模块在电动汽车和储能系统中的重要性日益提升,其热性能管理也成为一项重大的工程挑战。高功率密度会产生大量热量,如果散热不当,可能导致电池性能下降、性能下…

《Python函数:从入门到精通,一文掌握函数编程精髓》

坚持用 清晰易懂的图解 代码语言,让每个知识点变得简单! 🚀呆头个人主页详情 🌱 呆头个人Gitee代码仓库 📌 呆头详细专栏系列 座右铭: “不患无位,患所以立。” Python函数:从入门到…

【记录贴】STM32 I2C 控制 OLED 卡死?根源在 SR1 与 SR2 的读取操作

问题描述最近在复用以前STM32F407控制OLED的代码,移植到STM32F103 上,使用硬件 I2C 通信方式。按照常规流程,先发送 OLED 的从机地址,OLED 有正常应答,但当发送第一个控制命令(0xAE)前的控制字节…

【AI驱动的语义通信:突破比特传输的下一代通信范式】

文章目录1 语义通信简介1.1 基本概念:什么是语义通信?语义通信的核心目标1.2 基本结构:语义通信系统结构语义通信系统的通用结构组成语义通信系统的结构关键模块1.3 基于大模型的语义通信关键技术🧠语义通信系统中AI大模型的设计建…

网络原理-HTTP

应用层自定义协议自定义协议是指根据特定需求设计的通信规则,用于设备或系统间的数据交换。其核心在于定义数据结构、传输方式及处理逻辑。协议结构示例典型的自定义协议包含以下部分:头部(Header):标识协议版本、数据…

ROS配置debug指南

一. 安装插件 下面的这一个插件过期了需要用下面的这一个插件来替换:二. 设置CMakeLists.txt的编译模式 set(CMAKE_BUILD_TYPE "Debug") set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb") set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAG…

微软正式将GPT-5接入Microsoft Copilot Studio(国际版)

微软宣布正式在Microsoft Copilot Studio(国际版)中集成GPT-5,推动智能体构建能力实现突破性升级。此次更新不仅为企业用户带来更高效的响应速度、更精准的语境理解能力,还通过增强的逻辑推理功能,显著提升了AI交互的深…

微算法科技(NASDAQ:MLGO)通过蚁群算法求解资源分配的全局最优解,实现低能耗的区块链资源分配

随着区块链网络规模的不断扩大和业务需求的日益复杂,资源分配问题逐渐成为制约其发展的关键因素之一。传统的区块链资源分配方法往往存在效率低下、能耗过高、难以达到全局最优解等问题。高能耗不仅增加了运营成本,还对环境造成了较大的压力。因此&#…

深入浅出JVM:Java虚拟机的探秘之旅

深入浅出JVM:Java虚拟机的探秘之旅一、JVM 初相识:揭开神秘面纱 在 Java 的世界里,JVM(Java Virtual Machine,Java 虚拟机)就像是一个神秘的幕后大 boss,掌控着 Java 程序运行的方方面面。你可以…

Nginx学习笔记(八)—— Nginx缓存集成

🗄🗄 Nginx缓存集成 📌📌 一、缓存核心价值 #mermaid-svg-CNji1KUDOsF8MwoY {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-CNji1KUDOsF8MwoY .error-icon{fill:#5522…

httpx 设置速率控制 limit 时需要注意 timeout 包含 pool 中等待时间

假设通过 httpx.Client 设置 limit 速率控制后,同时发起多个请求访问 youtube。并且由于科学原因一直连接不上 假设一共 4 个连接,max_connection2,timeout5s。 默认会发生的情况不是前两个连接 tcp 握手 timeout,后两个连接再发起…

【网络】TCP/UDP总结复盘

1.UDP的格式2.TCP的格式3.TCP是来解决什么问题的?答:解决IP层的不可靠传输问题,可能数据包丢失、损坏、重复等为上层应用层提高可靠有序的数据传输服务通过校验和、确认应答机制、序列号来解决不可靠传输和无序性问题通过流量控制--->>…

Nginx 配置中,root 和 alias 区别

在 Nginx 配置中,root 和 alias 都用于定义文件路径,但它们的行为有重要区别,特别是 路径拼接方式 和 末尾斜杠 (/) 的影响。1. root 和 alias 的区别 (1) root 指令 作用:root 会将 location 的 URI 拼接到 root 路径后面&#x…

基于vue.js的无缝滚动

方法一&#xff1a;基于requestAnimationFrame demo <template><h-page-container class"hoem-page"><h1>无缝滚动</h1><h2>垂直方向</h2><div class"container1"><AutoScroll :data"list" :item-…