第4章:传输层详解

传输层,说白了就是网络通信的「中间人」。

它夹在应用层和网络层之间,干的是最累的活——保证数据能准确、完整地送到对方手里。我做了这么多年网络,见过太多因为传输层没搞明白而翻车的案例。今天咱们就把TCP和UDP这两个核心协议彻底讲透。

4.1 TCP协议特性

TCP,全称传输控制协议。它最大的特点就一个字:稳。

你想想看,如果发一条消息过去,对方收没收到你都不知道,那还怎么玩?TCP就是来解决这个问题的。

TCP的核心特性:

  • 面向连接:通信前必须先建立连接,通信完必须释放连接
  • 可靠传输:保证数据不丢失、不重复、按序到达
  • 流量控制:根据接收方能力调整发送速度
  • 拥塞控制:根据网络状况动态调整发送速率
  • 全双工通信:双方可以同时收发数据

我记得有一次排查线上问题,发现某个服务经常超时。查了半天,原来是TCP的拥塞控制算法在作怪——网络稍微有点波动,发送窗口就缩得特别小,导致数据卡在半路上。嗯,这里要注意,TCP的「可靠」是有代价的。

4.2 TCP报文结构

TCP报文长什么样?我习惯把它拆成两部分来看:头部和数据。

头部最少20字节,最多60字节。咱们重点看几个关键字段:

字段 长度 说明
源端口 16位 发送方的端口号
目的端口 16位 接收方的端口号
序列号 32位 本报文段数据的第一个字节序号
确认号 32位 期望收到的下一个字节的序号
数据偏移 4位 头部长度,单位是4字节
标志位 6位 URG、ACK、PSH、RST、SYN、FIN
窗口大小 16位 接收窗口,用于流量控制
校验和 16位 校验头部和数据部分

这里有个坑,我刚开始学的时候总搞混序列号和确认号。说白了,序列号是告诉对方「我发到哪了」,确认号是告诉对方「你发到哪了,下一个该发啥」。

小技巧:抓包的时候,重点关注SYN、ACK、FIN这三个标志位。三次握手和四次挥手全靠它们来识别。

4.3 三次握手

三次握手,就是建立TCP连接的过程。为什么是三次?不是两次也不是四次?

我直接说结论:两次不够可靠,四次太浪费。三次刚刚好。

具体流程是这样的:

  1. 第一次握手:客户端发送SYN包,序列号设为x,进入SYN_SENT状态
  2. 第二次握手:服务器收到SYN,回复SYN+ACK包,确认号设为x+1,自己的序列号设为y,进入SYN_RCVD状态
  3. 第三次握手:客户端收到SYN+ACK,发送ACK包,确认号设为y+1,进入ESTABLISHED状态

服务器收到ACK后,也进入ESTABLISHED状态。连接建立完成。

注意:我曾经遇到过一个问题——客户端发完SYN后一直没收到SYN+ACK。查了半天,发现是防火墙把SYN包给丢了。所以排查连接问题时,别忘了检查中间设备。

三次握手的核心目的有两个:

  • 确认双方的收发能力都正常
  • 同步双方的初始序列号

你想想看,如果只有两次握手,服务器怎么知道客户端有没有收到自己的SYN+ACK?万一丢了,服务器还傻等着,那就出问题了。

4.4 四次挥手

四次挥手,就是断开TCP连接的过程。比握手多了一次,因为TCP是全双工的,每一路都需要单独关闭。

流程是这样的:

  1. 第一次挥手:客户端发送FIN包,序列号为u,进入FIN_WAIT_1状态
  2. 第二次挥手:服务器收到FIN,回复ACK包,确认号为u+1,进入CLOSE_WAIT状态
  3. 第三次挥手:服务器发送FIN包,序列号为v,进入LAST_ACK状态
  4. 第四次挥手:客户端收到FIN,回复ACK包,确认号为v+1,进入TIME_WAIT状态

客户端在TIME_WAIT状态要等2MSL(最大报文段生存时间)才能彻底关闭。为什么?

说白了,就是为了确保最后一个ACK能到达服务器。如果ACK丢了,服务器会重发FIN,客户端还能再回应一次。

避坑指南:我曾经在生产环境遇到过大量TIME_WAIT连接堆积的问题。原因是短连接太多,客户端频繁建立和断开连接。解决方案是改用长连接,或者调整系统参数缩短TIME_WAIT时间。

4.5 UDP协议特性

UDP,用户数据报协议。和TCP完全相反,它主打一个「快」字。

UDP的特点:

  • 无连接:发数据前不需要建立连接
  • 不可靠:不保证数据到达,不保证顺序
  • 无流量控制:发多少算多少
  • 无拥塞控制:网络堵了也不管
  • 开销小:头部只有8字节

你可能会问:这么不靠谱的协议,有什么用?

我举个例子你就明白了——视频通话。你愿意为了等一帧画面而卡住整个视频吗?显然不愿意。丢几帧画面无所谓,但卡顿是不能忍的。这就是UDP的用武之地。

UDP报文结构更简单:

字段 长度 说明
源端口 16位 发送方的端口号
目的端口 16位 接收方的端口号
长度 16位 UDP报文的总长度
校验和 16位 可选,不校验时填0

看到没?就4个字段,8个字节。比TCP的20字节头部轻量多了。

UDP的典型应用场景:

  • DNS查询:发一个请求,等一个响应,丢了就重发
  • 视频直播:允许少量丢包,追求低延迟
  • 在线游戏:实时性要求高,丢包比延迟好
  • 物联网:设备资源有限,UDP开销小

4.6 TCP vs UDP 对比

我习惯用一个表格来对比这两个协议,一目了然:

对比项 TCP UDP
连接方式 面向连接 无连接
可靠性 可靠 不可靠
顺序保证 保证 不保证
流量控制 有 无
拥塞控制 有 无
头部大小 20-60字节 8字节
传输方式 字节流 数据报
典型应用 HTTP、FTP、SMTP DNS、视频、游戏

选哪个协议,说白了就看你的业务需求。要可靠就选TCP,要速度就选UDP。没有的好坏,只有合不合适。

我的建议:如果你不确定选哪个,默认用TCP。等发现性能瓶颈了,再考虑换成UDP或者基于UDP的自定义协议。别一开始就搞复杂了。

4.7 本章知识体系

下面这张图,把传输层的核心逻辑串起来了:

传输层核心知识体系 传输层 TCP协议 UDP协议 面向连接 可靠传输 流量/拥塞控制 无连接 不可靠 低开销 三次握手 / 四次挥手 报文结构简单 选TCP还是UDP?看业务需求!

这张图把传输层的核心脉络理清楚了。TCP这边,重点掌握三次握手和四次挥手;UDP这边,记住它简单、快速、无状态就行。

好了,传输层的内容就讲到这里。下一章咱们进入应用层,看看HTTP协议到底是怎么工作的。


可可精品资料库