TCP协议简介
前言在互联网世界中我们浏览网页、传输文件、微信聊天、下载资源绝大多数数据传输都依赖 TCP 协议。HTTP、HTTPS、WebSocket、MySQL、SSH 等上层应用协议底层全部构建在 TCP 之上。很多开发者学会 Socket 编码之后只懂得调用 send、recv却不了解 TCP 底层机制遇到粘包、连接断开、超时重传等问题时无从下手。本文用通俗易懂的方式讲解 TCP 核心原理结合开发场景说明实际意义。TCP 全称传输控制协议Transmission Control Protocol工作在 OSI 七层模型的传输层。一、TCP 的核心特性TCP 最重要的标签面向连接、可靠传输、有序、全双工、流量控制、拥塞控制。面向连接通信双方传输数据前必须先建立专属连接通信结束正常断开。不像 UDP发数据包不需要提前打招呼。可靠传输保证数据准确送达不会丢包、不会重复接收。依靠确认应答、重传机制实现。有序传输多个数据包到达对方时TCP 会根据序列号重新排序上层应用收到的数据和发送顺序保持一致。全双工通信连接建立后双方可以同时互相发送数据不需要轮流单向传输。类似打电话两边随时可以说话。基于字节流TCP 没有清晰数据包边界只看作一串连续字节流。这也是网络开发最常遇到TCP粘包的根本原因。对比记忆UDP 无连接、不可靠、面向报文TCP 面向连接、可靠、面向字节流。二、三次握手建立连接客户端想要和服务端通信首先执行三次握手建立 TCP 连接。目的确认双方发送能力、接收能力正常协商初始序列号。流程第一次握手客户端 → 服务端发送 SYN 报文。客户端请求建立连接。第二次握手服务端 → 客户端回复 SYN ACK。同意连接并确认收到客户端请求。第三次握手客户端 → 服务端回复 ACK。确认收到服务端应答连接正式建立。通俗理解客户端能听到我吗SYN服务端能听到你能听到我吗SYNACK客户端可以听到ACK连接建立完成双方即可开始传输业务数据。开发常见问题服务端listen()之后等待连接内核自动完成三次握手防火墙、端口未开放、路由不通都会导致握手失败客户端抛出连接超时 / 连接拒绝。三、四次挥手断开连接TCP 连接是双向通道关闭连接需要四次挥手任何一方都可以主动发起关闭。流程客户端主动关闭为例第一次挥手客户端发送 FIN表示客户端不再发送数据。第二次挥手服务端回复 ACK确认收到关闭请求。此时服务端依然可以继续向客户端发送剩余数据。第三次挥手当服务端数据全部发送完毕发送 FIN告诉客户端服务端也不再发数据。第四次挥手客户端回复 ACK双方通道彻底关闭。通俗理解客户端我说完了不再说话了FIN服务端收到我知道你不说了ACK服务端我这边数据也发完了我也不说了FIN客户端收到通话结束ACK⚠️ 关键点不能简化成三次。因为一方关闭发送通道后另一方可能还有残留数据需要传输。四、可靠性如何实现TCP 通过一系列机制保障数据不丢失序列号Sequence Number每一段字节分配序号用于排序、去重、确认。确认应答 ACK接收方收到数据后返回 ACK告诉发送方“哪些数据我收到了”。超时重传发送数据后启动计时器如果迟迟等不到 ACK自动重新发送报文解决丢包。重复报文去重收到重复数据包依靠序列号识别并丢弃副本。五、流量控制防止发送方发送速度太快接收方缓冲区塞满造成数据丢失。核心机制滑动窗口协议。接收方在 ACK 报文中通知发送方自己剩余缓冲区大小发送方严格控制发送量不能超过接收方处理上限。六、拥塞控制流量控制解决「发送方和接收方之间」速度匹配拥塞控制解决「整条网络链路」拥堵问题。如果网络路由器过载、大量丢包TCP 主动降低发送速率避免持续加剧网络拥堵。常见算法慢启动、拥塞避免、快重传、快恢复。七、TCP 开发避坑重点Socket 开发必看1. TCP 粘包TCP 是字节流没有数据包边界。多次发送的数据可能合并在一起被一次 recv 读到就是粘包。解决方案固定数据包长度使用分隔符分割数据包包头包体头部携带数据长度先读长度再读取对应字节数据2. 不要认为 send 成功代表对方收到数据send() 仅仅代表数据写入本机操作系统 TCP 缓冲区如果后续网络彻底断开缓冲区数据依然可能发送失败应用层无法直接感知。3. recv 返回空字节b代表 TCP 连接已经正常关闭对方执行四次挥手业务代码需要主动断开套接字。4. KeepaliveTCP保活长时间没有数据传输时开启 TCP Keepalive内核定时探测连接是否存活及时清理僵死连接。常用于内网穿透、长连接服务。八、TCP 适用场景✅ 适合文件传输、数据库访问、网页访问、即时通讯、远程登录要求数据完整不丢失。❌ 不适合直播、语音通话、游戏实时数据包这类场景允许少量丢包追求极低延迟一般选用 UDP。九、总结TCP 通过三次握手建立连接、四次挥手关闭连接依靠序列号、ACK应答、重传、滑动窗口实现可靠有序传输。所有上层网络应用协议都建立在 TCP 之上理解 TCP 原理才能真正看懂网络异常、解决 Socket 通信中的粘包、断线、超时等疑难问题。掌握 TCP 理论后再结合 Python Socket、Netty、Go net 等网络库编码就不再只是复制粘贴代码能够从底层理解每一个现象背后的原因。