TCP协议基础与可靠传输机制
一、TCP协议概述
TCP(Transmission Control Protocol,传输控制协议)是传输层最重要的协议之一。正如其名,TCP的核心使命是对数据的传输进行精细化控制,确保数据能够可靠、有序、无差错地到达目的地。
与UDP的无连接、不可靠传输不同,TCP通过一系列复杂的机制,在不可靠的IP网络之上构建了一条可靠的逻辑通信信道。
二、TCP协议段格式
TCP报文段由首部(Header)和数据(Payload)两部分组成。理解TCP首部各字段的含义,是掌握TCP工作原理的基础。
2.1 关键字段详解
| 字段 | 长度 | 说明 |
|---|---|---|
| 源/目的端口号 | 各16位 | 标识数据从哪个进程来,到哪个进程去 |
| 32位序列号(Seq) | 32位 | 标识本报文段发送的数据的第一个字节的序号 |
| 32位确认号(Ack) | 32位 | 期望收到对方下一个报文段的第一个数据字节的序号 |
| 4位首部长度 | 4位 | 表示TCP头部有多少个32位字(4字节),最大值为15,因此首部最大长度为60字节 |
| 6位标志位 | 6位 | URG、ACK、PSH、RST、SYN、FIN(见下文) |
| 16位窗口大小 | 16位 | 接收方告诉发送方自己的接收缓冲区还剩多少空间 |
| 16位校验和 | 16位 | CRC校验,覆盖首部和数据两部分 |
| 16位紧急指针 | 16位 | 标识紧急数据的末尾位置 |
| 选项 | 最多40字节 | 如窗口扩大因子、时间戳等 |
2.1.1 4位首部长度(数据偏移)
| 要点 | 说明 |
|---|---|
| 单位 | 基本单位是4字节(32位),不是1字节! |
| 取值范围 | [0, 15] |
| 实际字节范围 | [0, 60] 字节 |
| 最小值 | 5(即 5 × 4 = 20字节,标准报头无选项时) |
| 最大值 | 15(即 15 × 4 = 60字节,含40字节选项) |
| 计算方式 | 实际报头长度 = 4位值 × 4 |
为什么这样设计?
因为TCP报头长度必须是4字节的整数倍,方便内存对齐。
2.2.2 两个经典问题
问题a:报头和有效载荷如何分离?
答:通过 4位首部长度 字段
读取该字段值 × 4 = 报头总长度
从报文开头跳过该长度,后面就是数据
问题b:如何交付给上层(哪个进程)?
答:通过 16位目的端口号
操作系统根据目的端口号找到对应的进程
将数据交付给该进程
2.2 六大标志位
URG(紧急):紧急指针是否有效,用于发送紧急数据
ACK(确认):确认号是否有效,建立连接后所有报文都应置1
PSH(推送):提示接收端立即将数据从缓冲区交给应用层
RST(复位):要求重新建立连接,用于异常情况的连接重置
SYN(同步):请求建立连接,携带SYN的报文称为同步报文段
FIN(结束):通知对方本端要关闭连接,携带FIN的报文称为结束报文段
2.3 窗口大小
发送端构建的报文,信息都是给对方的!
TCP是全双工通信,双方既是发送端也是接收端
我发送报文时,报头中的窗口大小字段填的是我的接收窗口
这个信息是告诉对方:"我还能接收多少"
对方收到后,就知道自己最多还能发多少
双方互相告知,互相配合,实现流量控制
三、确认应答(ACK)机制
TCP可靠传输的基石是确认应答机制。TCP将每个字节的数据都进行了编号,这个编号就是序列号(Sequence Number)。
核心逻辑:
发送方发送数据时,TCP首部中的序列号字段填入该报文段第一个字节的序号
接收方收到数据后,返回ACK报文,确认号字段填入期望收到的下一个字节的序号
发送方收到ACK后,就知道哪些数据已被成功接收,可以继续发送后续数据
3.1 序列号的作用
TCP将每个字节的数据都进行了编号 : 序列号
序列号不仅用于排序,更重要的是:
消除重复:通过序列号识别重复的数据包
按序重组:接收方根据序列号将乱序到达的报文重新排序
确认定位:确认号明确告知发送方"我收到了哪些,接下来要什么"
四、超时重传机制
网络环境复杂,数据包可能因网络拥堵等原因丢失。TCP通过超时重传机制保证可靠性。
4.1 两种丢包场景
场景一:数据包丢失
- 主机A发送数据给B之后,可能因为网络拥堵等原因,数据无法到达主机B;
- 如果主机A在一个特定时间间隔没有收到B发来的确认应答,就会进行重发;
场景二:ACK丢失
因此主机B会收到很多重复数据,那么TCP协议需要能够识别初那些包是重复的包,并且把重复的丢弃掉
这时候我们可以利用前面提到的序列号,就可以很容易的做到去重的效果。
在这两种情况下,发送方都会在超时后重传数据。接收方通过序列号识别出重复的数据包,直接丢弃,只向应用层交付一份。
4.2超时时间的动态计算
超时时间(RTO, Retransmission Timeout)的设置至关重要:
太长:影响重传效率,降低吞吐量
太短:频繁发送重复包,造成网络拥塞
TCP采用自适应算法动态计算RTO:
Linux实现:以500ms为一个单位进行控制,超时时间都是500ms的整数倍
指数退避:首次超时等待500ms,第二次等待2×500ms,第三次4×500ms,以此类推
连接终止:累计到一定重传次数后,TCP认为网络或对端异常,强制关闭连接
这种指数退避策略避免了在网络拥塞时继续加重负担,给网络恢复留出时间。
