前言:互联网的"可靠邮差"
想象你要给朋友寄一份重要文件:
- 如果随便找个路人捎带(UDP协议),可能丢件、乱序、破损,但速度极快。
- 如果委托专业快递(TCP协议 ),对方会签收确认、顺序整理、破损重发,确保万无一失,代价是稍慢一些。
TCP(Transmission Control Protocol) 就是互联网世界的"可靠邮差",掌管着网页浏览、文件传输、邮件收发等一切需要精准交付的任务。
一、TCP是什么?
1.1 定义
TCP(Transmission Control Protocol 传输控制协议)是一种基于IP的传输层协议,TCP协议面向连接、正面确认与重传、缓冲机制、流量控制、差错控制、拥塞控制,可保证高可靠性(数据无丢失、数据无失序、数据无错误、数据无重复到达) 传输层协议。
上图形象展示了TCP协议是基于IP协议的传输层协议
TCP
是当今互联网当中使用最为广泛的传输层协议,没有之一。
TCP
协议被广泛应用,其根本原因就是提供了详尽的可靠性保证,基于 TCP
的上层应用非常多,比如 HTTP
、HTTPS
、FTP
、SSH
等,甚至 MySQL
底层使用的也是 TCP
。
1.2 核心使命
解决一个根本问题:如何在不可靠的网络(可能丢包、乱序、拥塞)中实现可靠的数据传输?
为什么网络中会存在不可靠?
虽然输入设备、输出设备、内存、CPU都在一台机器上,但这几个硬件设备是彼此独立的。如果它们之间要进行数据交互,就必须要想办法进行通信,因此这几个设备实际是用"线"连接起来的,其中连接内存和外设之间的"线"叫做 IO
总线,而连接内存和 CPU
之间的 "线" 叫做系统总线。由于这几个硬件设备都是在一台机器上的,因此这里传输数据的"线"是很短的,传输数据时出现错误的概率也非常低。
但如果要进行通信的各个设备相隔千里,那么连接各个设备的"线"就会变得非常长,传输数据时出现错误的概率也会大大增高,此时要保证传输到对端的数据无误,就必须引入可靠性。
总之,网络中存在不可靠的根本原因就是,长距离数据传输所用的"线"太长了,数据在长距离传输过程中就可能会出现各种各样的问题,而 TCP
就是在此背景下诞生的, TCP
就是一种保证可靠性的协议。
此外,单独的一台计算机可以看作成一个小型的网络,计算机上的各种硬件设备之间实际也是在进行数据通信,并且它们在通信时也必须遵守各自的通信协议,只不过它们之间的通信协议更多是描述一些数据的含义。
1.3 关键角色
- 发送方:将数据分割成"报文段"(Segment)
- 接收方:按顺序重组数据,并反馈确认
- 路由器:网络中的"中转站",负责转发报文
1.4 TCP和IP的关系
TCP和IP是协议栈中的两个不同层次:TCP位于传输层,而IP位于网络层。
TCP依赖于IP来在网络中传输数据包。IP负责将数据包从源地址传输到目标地址,而TCP则负责在这些数据包之间建立可靠的通信通道。
TCP将数据分割成数据段,并且在IP数据包中包含TCP数据段,然后将这些数据包通过网络传输。
TCP和IP共同构成网络通信的基础,并为全球范围内的数据传输提供可靠性和正确性。在互联网和局域网中扮演着关键的角色,支持着现代网络通信的稳定运行。
1.5 TCP的应用场景
1. 必须用TCP的场景
场景 | 原因 |
---|---|
网页浏览(HTTP/HTTPS) | 确保文本/图片完整加载,避免页面错乱 |
文件传输(FTP) | 大文件不能丢失任何字节 |
电子邮件(SMTP/POP3) | 邮件内容必须100%准确送达 |
远程登录(SSH) | 键入的命令与服务器响应需严格对应 |
2. 慎用TCP的场景
场景 | 问题 | 替代方案 |
---|---|---|
实时视频会议 | 延迟敏感,重传导致卡顿 | UDP + QUIC |
在线游戏(射击类) | 高延迟影响操作体验 | UDP + 自定义可靠层 |
物联网传感器上报 | 小数据量,TCP开销过大 | MQTT(基于TCP优化)/CoAP(UDP) |
二、TCP发展简史:从阿帕网到万物互联
时间 | 里程碑事件 | 意义 |
---|---|---|
1974年 | Vinton Cerf和Bob Kahn发表TCP论文 | 奠定互联网基础架构 |
1981年 | RFC 793正式定义TCP协议 | 首个标准化版本 |
1988年 | 引入拥塞控制算法(Jacobson算法) | 解决网络崩溃问题 |
1990s | TCP/IP取代ISO/OSI成为互联网主流协议 | 全球互联网爆发式增长 |
2010s | 优化算法(如BBR)应对高速移动网络 | 提升5G/物联网时代体验 |
💡 趣闻:早期TCP和IP是一个协议,1983年拆分为两层,TCP专注"可靠传输",IP专注"路径寻址"。
备注:详细发展历史,可阅读之前文章:
【TCP/IP协议精解:IP协议------互联网世界的邮政编码系统 】blog.csdn.net/qq_17153885...
三、TCP核心特点
1. 面向连接(Connection-Oriented)
-
三次握手建立连接:
客户端 → SYN → 服务端 客户端 ← SYN+ACK ← 服务端 客户端 → ACK → 服务端
类比:打电话时"喂,听得到吗?"→"听到了,你呢?"→"我也听到了,开始说吧!"
markdown
在TCP连接建立阶段,客户端和服务器通过三次握手来建立连接。这个过程包括:
1.客户端发送SYN报文:客户端发送一个SYN(同步)报文,包含序列号,用于建立连接。
2. 服务器回应ACK+SYN报文:服务器收到客户端的SYN报文后,回应一个ACK(确认)和SYN报文,确认收到客户端的连接请求。
3. 客户端回应ACK报文:客户端收到服务器的ACK+SYN报文后,回应一个ACK报文,确认连接建立完成。
-
四次挥手断开连接:
cssA → FIN → B (A说"我说完了") A ← ACK ← B (B答"知道了") A ← FIN ← B (B说"我也说完了") A → ACK → B (A答"好的,挂吧")
2. 可靠传输(Reliability)
- 确认应答(ACK) :接收方每收到一个包,必须回复"我已收到第X号包"。
- 超时重传:发送方等待ACK超时,自动重发数据包。
- 序列号与排序:每个字节分配唯一序号,接收方按序号重组数据。
3. 流量控制(Flow Control)
- 滑动窗口机制 :接收方通过
窗口大小
字段告知发送方:"我还能接收多少数据"。 类比:快递员根据仓库容量调整发货速度,避免压垮仓库。
4. 拥塞控制(Congestion Control)
- 慢启动:初始窗口=1,每轮翻倍(指数增长)。
- 拥塞避免:窗口达阈值后,每轮+1(线性增长)。
- 快重传/快恢复:收到3个重复ACK立即重传,避免等待超时。
5. 全双工通信(Full-Duplex)
双方可同时发送和接收数据,如同双向车道。
6. 基于字节流(Byte Stream)
TCP把数据视为无结构的字节流,不保留消息边界(需应用层自行分割)。
✅ 对比UDP:无连接、不保证可靠、基于数据报(保留边界)、无拥塞控制。
四、TCP协议格式
4.1 TCP/IP参考模型
首先回忆TCP/IP的参考模型,基于TCP/IP的参考模型将协议分成四个层次,它们分别是链路层、网络层、传输层和应用层。下图表示TCP/IP模型与OSI模型各层的对照关系。
TCP/IP协议族按照层次由上到下,层层包装。最上面的是应用层,这里面有http,ftp 等等我们熟悉的协议。而第二层则是传输层,著名的TCP和UDP协议就在这个层次。第三层是网络层,IP协议就在这里,它负责对数据加上IP地址和其他的数据以确定传输的目标。第四层是数据链路层,这个层次为待传送的数据加入一个以太网协议头,并进行CRC编码,为最后的数据传输做准备。
上图清楚地表示了TCP/IP协议中每个层的作用,而TCP/IP协议通信的过程其实就对应着数据入栈与出栈的过程。入栈的过程,数据发送方每层不断地封装首部与尾部,添加一些传输的信息,确保能传输到目的地。出栈的过程,数据接收方每层不断地拆除首部与尾部,得到最终传输的数据。
以HTTP协议为例,具体说明
4.2 TCP协议格式
TCP(Transmission Control Protocol,传输控制协议)是互联网中最核心的传输层协议之一,它提供了一种面向连接的、可靠的、基于字节流的通信服务。
为了实现这些特性,TCP 在 IP 数据报之上定义了特定的报文格式。一个完整的 TCP 报文段(Segment)由固定头部、可选头部和数据部分组成。TCP 首部的长度是可变的,但至少为 20 字节,最长可达 60 字节。
TCP报文格式图示
diff
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data | |U|A|P|R|S|F| |
| Offset| Reserved |R|C|S|S|Y|I| Window |
| | |G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options (if Data Offset > 5) |
| ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1、固定头部(Fixed header)
每个TCP数据段均携带的,长度固定20字节。
位段 | 字段名 | 值 |
---|---|---|
[0:15] | 源端口,16 bits(Source Port) | 表示发送端的应用进程端口号 |
[16:31] | 目的端口,16 bits(Destination Port) | 表示接收端的应用进程端口号 |
[32:63] | 序号,32 bits(Sequence Number) | 表示当前该数据段中,数据部分第一个字节的序号。一个完整的 应用层数据流,每个字节均有一个序号 |
[64:95] | 确认号,32 bits(Acknowledgment Number) | 期望接收到的下一个字节的序号 |
[96:99] | 数据偏移,4 bits(Data Offset) | 表示TCP头部长度(含可选头部),单位4字节(即值每增加1, 长度增加4个字节),最小值为5(5*4=20为固定头部的长度, |
是TCP头部所必需),最大值为15(15*4=60为固定+可选头部 的最长长度) | ||
[100:103] | 保留,4 bits(Reserved) | 为0,保留不使用 |
[104:111] | 控制位,8 bits(Control Bits) | 也叫标志位(Flags) 104:CWR,拥堵窗口减少标志 105:ECE,ECN-Echo标志 106:URG,紧急指针有效(指示数据段包含紧急数据) 107:ACK,确认号有效(确认已接收到数据) 108:PSH,推送功能(接收方立即将数据给应用层,不进行缓存) 109:RST,重置连接(强制关闭异常连接) 110:SYN,同步序号(建立连接,发送方发送SYN=1的报文) 111:FIN,结束连接(发送方发完所有数据,请求关闭连接) |
[112:127] | 窗口大小,16 bits(Window) | 接收窗口大小,单位为字节。表示发送该数据报的主机,当前 只能接收多少字节的数据量,用于流量控制 |
[128:143] | 校验和,16 bits(Checksum) | 校验整个TCP数据报(TCP固定+可选头部+数据部分,RFC 793 还规定校验和需加上伪首部),避免数据在传输过程中出现错误 |
[144:159] | 紧急指针,16 bits(Urgent Pointer) | 表示紧急数据结束位置的偏移值(从序号开始计算),仅在控 制位URG=1时生效 |
💡控制位:RFC 793(1981.9)中规定只有6个控制位,在此之后RFC 3168(2001.9)中,规定增加两个控制位,从保留位中借取位,共8个控制位。
下图源自RFC 3168,为新增控制位与旧控制位区别
💡校验和(Checksum):关于校验和中提到的伪首部,其长度为12字节(IPv4),包含源IP、目的IP、保留字节(0x00)、协议类型(TCP协议号6)、TCP数据总长度(长度只包括头部+数据,不含伪首部)。RFC 793规定计算校验和时,需要将伪首部参与计算,计算时伪首部位于数据串最前端(校验顺序:伪首部+头部+数据)。
💡伪首部:在实际中,发送方将TCP数据报发出时,会丢弃伪首部;接收方收到数据报后,从网络层提取相关信息,重新生成伪首部参与校验计算。之所以叫"伪首部",就是其不存在于实际传输过程,仅用于校验计算时临时生成使用。
2、可选头部(optional header)
可选,补充一些额外信息,长度0~40字节。
位段 | 字段名 | 值 |
---|---|---|
[0:39] | 可选字段(Options) | 可选,用于补充固定头部的信息(如最大 报文段长度、窗口扩大银子、时间戳、选择性 确认等)。最大长度40字节,受数据偏移( Data Offset)最大值15(15*4-20=40)限制 |
填充(Padding) | 用于补足可选头部的长度,因可选字段(Options)的实际 长度是可变的,而数据偏移(Data Offset)的值是以4字节 为单位增减。若可选字段不为4字节的整倍数,则需填充"0" 使可选头部长度与Data Offset*4-20相等 |
3、数据部分(Data)
承载应用层数据部分,最大不超过1460字节。
💡MSS(Maximum Segment Size,最大报文段大小):用于定义TCP单次传输的的数据部分最大长度(不含TCP头部),最大长度MSS=MTU(最大1500字节)-TCP头部(20字节,无可选头部)-IP头部(20字节,无可选头部)=1460字节。
💡RFC 791中规定,主机必须能接收和处理至少576字节的IP数据报。所以当TCP连接时双方未协商MSS,则默认使用536字节长度(576-TCP头部20-IP头部20=536字节)。
五、TCP的使用:开发者视角
1. 套接字(Socket)编程示例(Python)
ini
# 服务端
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建TCP Socket
server.bind(("0.0.0.0", 8080))
server.listen()
client, addr = server.accept() # 等待客户端连接
data = client.recv(1024) # 接收数据
client.send(b"Received!") # 发送响应
# 客户端
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("127.0.0.1", 8080))
client.send(b"Hello TCP!")
response = client.recv(1024)
2. 关键参数调优
- 超时重传时间(RTO) :动态计算网络延迟调整
- 最大报文段(MSS) :避免数据包被路由器分片
- 窗口缩放因子:支持高速网络的大窗口传输
3. 抓包分析工具(Wireshark)
六、TCP的挑战与进化
现存问题
- 队头阻塞(HOL) :一个丢包延迟后续所有包(即使已到达)。
- 移动网络适应性差:频繁切换WiFi/4G导致连接重置。
- 加密开销大:TLS握手叠加TCP握手延迟高。
新一代解决方案
-
QUIC协议(HTTP/3基础):
- 在UDP上实现可靠传输,解决队头阻塞
- 内置加密,0-RTT快速建连
-
多路径TCP(MPTCP) :
- 手机同时用4G+WiFi传输,提升稳定性
-
BBR拥塞控制算法(Google开发):
- 更精准测量带宽,避免传统算法"主动饿死"问题
结束语:数字世界的"秩序守护者"
从1974年诞生至今,TCP协议:
- 以"笨办法"守住了互联网的可靠性底线------确认、重传、排序、流控,看似低效却无可替代。
- 启示技术设计哲学:在复杂系统中,有时需用"冗余"换取"确定"。
正如互联网之父Vint Cerf所言:
"我们选择TCP,不是因为它快,而是因为它值得信赖。"
在5G、物联网、元宇宙呼啸而来的时代,TCP或许会隐身于QUIC、HTTP/3等新协议之后,但其"可靠传输"的思想,将永远流淌在互联网的血液中。
如果你对网络进阶技巧感兴趣,欢迎关注公众号【技海拾贝】,获取更多技术干货与实战案例!