《深入理解 RFC 793:传输控制协议(TCP)》

📅 2026/7/6 15:30:13
《深入理解 RFC 793:传输控制协议(TCP)》
本文基于 RFC 793 原始规范整理所有内容均来自文档原文无外部延伸知识适合网络开发、运维及协议学习者阅读。一、文档速览RFC 793 基本信息基础属性RFC 编号793完整标题TRANSMISSION CONTROL PROTOCOL传输控制协议副标题为DARPA INTERNET PROGRAM PROTOCOL SPECIFICATIONDARPA 互联网项目协议规范协议状态文档明确定义为美国国防部DoD标准传输控制协议基于此前 9 版 ARPA TCP 规范制定发布日期1981 年 9 月替代关系替换 RFC 761及此前 9 版 ARPA TCP 相关规范对应 IEN 编号129、124、112、81、55、44、40、27、21、5当前文档未提及被后续 RFC 更新或废弃的信息核心目标TCP 的核心设计目标是在不可靠的分组交换互联网络中为不同主机上的进程提供面向连接、可靠、有序、全双工的端到端通信服务同时完整定义 TCP 的实现逻辑、与上层应用及下层协议的接口适配多网络分层协议栈架构。简单来说TCP 是在“不靠谱”的网络底层之上给应用层搭的一套“靠谱数据传输管道”。二、核心机制通俗讲解把 TCP 当成“可靠快递系统”1. 整体运行流程与关键角色你可以把 TCP 的通信过程想象成两家公司之间的可靠快递合作关键角色发送端/接收端 TCP相当于两家的快递调度中心负责打包、校验、重发、排序快递应用进程相当于两家的具体业务部门要寄/收快递IP 协议相当于公共快递网络负责把包裹运到对方公司不保证不丢、不乱TCB传输控制块相当于每个合作的档案袋记录当前合作的序列号、窗口大小、状态等信息整体流程业务部门把要发的文件给调度中心 → 调度中心打包成快递TCP 报文段→ 交给公共快递网络IP运输 → 对方调度中心收到后校验、排序 → 交给对方业务部门。如果快递丢了、坏了调度中心会自动重发。2. 报文结构TCP 快递的“面单”长什么样TCP 报文段直接封装在 IP 数据报中传输固定头部 20 字节后方为可选选项和数据结构类似快递的「面单货物」表格字段通俗解释核心作用源端口/目的端口发件/收件部门的编号确定是哪两个应用在通信比如网页服务默认用 80 端口FTP 默认用 21 端口序列号每个字节的快递单号给每个传输的字节编号哪怕快递乱序收件方也能按单号排好顺序确认号“我已收到单号 X 之前的所有快递”告诉对方我下次要从哪个字节开始收确认对方的数据我已收到控制位URG/ACK/PSH/RST/SYN/FIN特殊指令标记SYN我要建立合作ACK我收到你的消息了FIN我没快递要发了RST出错了终止合作PSH这个快递要马上送URG这个快递是加急窗口“我现在最多能收 100 件快递”流量控制核心告诉对方我当前能接收的字节数对方不能超过这个量发送校验和快递包装的防震检查检查报文有没有损坏坏了就直接丢弃要求重发紧急指针加急快递的标记配合 URG 标志指向加急数据之后的位置告诉对方哪部分是急件3. 连接交互三次握手建连四次挥手断连TCP 的所有通信都要先建立连接就像合作前要签合同三次握手建立连接第一步客户端A发SYN包“我要和你建立连接我的初始单号是 X”相当于 A 给 B 发合作意向书第二步服务端B回SYNACK包“我收到你的意向了我也同意合作我的初始单号是 Y我确认收到你的 X 单号”B 回意向书附上自己的单号第三步A 回ACK包“我收到你的意向了确认你的 Y 单号”A 回确认合同生效连接建立四次挥手关闭连接第一步A 发FIN包“我没快递要发了准备终止合作”A 说我要结束了第二步B 回ACK包“我知道你发完了”B 说我知道了第三步B 发FIN包“我也没快递要发了”B 也说要结束第四步A 回ACK包“我知道你也发完了拜拜”A 确认然后等 2 倍 MSL 时间再彻底终止防止 B 没收到确认4. 协议依赖TCP 在协议栈里的位置根据 RFC 793 的协议关系图TCP 的分层位置如下应用层Telnet/FTP/Voice 等 ↓ 主机层TCP/RTP 等其他主机协议 ↓ 网关层IP 协议 ICMP ↓ 网络层以太网/ARPANET 等本地网络协议下层依赖 IPTCP 完全不关心下层网络是什么只要 IP 能提供不可靠的数据报服务就行IP 负责跨网络路由、分片重组。上层服务应用应用不需要自己处理重传、排序、流控直接调用 TCP 的OPEN/SEND/RECEIVE/CLOSE接口就能实现可靠通信。三、开发者必知5 个排错/开发核心要点1. 序列号的“环形”规则与安静时间序列号是 32 位无符号整数所有计算要对2^32取模范围是 0~2^32-1到顶后回到 0比较的时候不能用普通的/要用模运算比较。初始序列号ISN每 4 微秒加 14.55 小时循环一次避免旧连接报文干扰。如果 TCP 崩溃后丢失了序列号记忆必须等 2 分钟MSL最大报文生存时间才能发任何报文这个“安静时间”是强制要求。2. 窗口不能随便缩零窗口要探测已经公布的窗口不能主动缩小只能等应用层消费数据后自然扩大不然会丢包触发不必要的重传。如果接收方窗口为 0发送方必须每 2 分钟发一次零窗口探测报文不然接收方窗口重新打开后无法通知发送方。3. TIME-WAIT 必须等 2MSL主动关闭连接的一方最后会进入TIME-WAIT状态必须等4 分钟2 倍 MSL才能彻底关闭这是为了处理最后 ACK 丢失的场景不然会导致连接状态异常。4. SYN/FIN 占序列号ACK 不占SYN和FIN控制位会各占用 1 个序列号ACK纯确认报文不占用序列号空间这点经常被忽略导致序列号计算错误。5. 校验和必须覆盖伪头部TCP 的校验和计算不仅要算 TCP 头部和数据还要算伪头部源 IP、目的 IP、协议号、TCP 长度不然可能出现 IP 路由错误但 TCP 仍然接收报文的问题。四、总结一句话记住 TCP在不可靠的 IP 网络之上用三次握手建连、序列号排序、ACK 确认、超时重传、滑动窗口流控实现可靠有序全双工通信的传输层协议。