3、重传与丢包基础概念

各位好,我是老张。今天咱们聊聊网络里最基础、也最让人头疼的两个概念——重传和丢包。说实话,我干了十几年网络排障,遇到最多的问题就是这两个家伙搞的鬼。你抓包一看,满屏的TCP Retransmission,心里基本就有数了:网络出问题了。

但很多刚入行的朋友,对这两个概念的理解其实挺模糊的。什么叫丢包?什么叫重传?它们之间到底是什么关系?别急,咱们一个一个掰开揉碎了讲。

3.1 什么是丢包

丢包,字面意思就是数据包在传输过程中丢了。你发了一个包,对方没收到。就这么简单。

但为什么会丢?我打个比方。你开车上高速,从北京到上海。正常情况下一路畅通,但突然前面修路,或者出了事故,你的车就被堵住了。如果堵得太久,或者干脆掉坑里了,那你就到不了上海了。数据包在网络上跑,也是这个道理。

从技术层面看,丢包发生在网络设备的转发过程中。路由器、交换机、防火墙,这些设备都有处理能力上限。当流量超过它们的处理能力时,多余的包就会被直接丢弃。这就是最常见的丢包原因——队列溢出。

核心要点:丢包的本质是数据包在传输路径上被中间设备或接收端主动丢弃,导致发送端无法收到预期的确认。

我在项目中遇到过最典型的一个案例:某公司做视频会议,一到下午3点就卡顿。抓包一看,丢包率高达5%。查了半天,发现是核心交换机的某个端口队列满了,因为有人在那个时间段跑大数据备份。嗯,这就是典型的队列溢出导致的丢包。

3.2 什么是重传

重传,就是重新传输。发送端发现某个包丢了,就再发一次。

但发送端怎么知道包丢了呢?这就要靠TCP的确认机制了。TCP是可靠的传输协议,它要求接收端每收到一个包,都要回复一个ACK(确认包)。如果发送端发了一个包,等了一段时间没收到ACK,它就会认为这个包丢了,于是重新发送。

这个等待的时间,叫做超时重传时间(RTO)。RTO不是固定的,它会根据网络状况动态调整。如果网络延迟大,RTO就长一些;如果网络延迟小,RTO就短一些。

我的经验:在Wireshark里看到TCP Retransmission,别急着下结论说网络不好。先看看RTO的值,再结合RTT(往返时间)来判断。有时候RTO设置得太短,也会导致不必要的重传。

除了超时重传,TCP还有一种更高效的重传机制——快速重传。当接收端收到乱序的包时,它会重复发送之前期望收到的那个包的ACK。发送端连续收到3个相同的ACK,就会立即重传,不用等超时。这比傻等超时要快得多。

3.3 重传与丢包的关系

重传和丢包,说白了就是一对孪生兄弟。有丢包,就必然有重传。但反过来,有重传不一定代表真的丢了包。

你可能会问:这怎么可能?重传不就是因为丢包才触发的吗?

其实不然。我举个例子:发送端发了一个包,接收端收到了,也回复了ACK。但这个ACK在回传的路上丢了。发送端没收到ACK,以为包丢了,于是重传。但实际上,接收端已经收到了原始包。这就是所谓的假重传。

所以,重传是丢包的结果,但重传本身并不100%证明网络真的丢了数据包。它只能证明发送端认为包丢了。

场景 实际丢包 触发重传 Wireshark显示
数据包丢失 是 是 TCP Retransmission
ACK包丢失 否(数据已收到) 是 TCP Retransmission
网络延迟过大 否 可能(超时触发) TCP Retransmission
接收端缓冲区满 是 是 TCP Retransmission + ZeroWindow

你看,同样是TCP Retransmission,背后的原因可能完全不同。所以,抓包分析的时候,不能只看表面现象,要结合上下文来推断。

避坑指南:我曾经在一个项目中,看到大量重传,以为是网络问题。折腾了两天,最后发现是服务器端的应用程序处理太慢,导致接收缓冲区满了,操作系统直接丢包。所以,重传不一定是网络的问题,也可能是应用层的问题。

3.4 常见的丢包原因

丢包的原因很多,我总结了几种最常见的,你可以在实际排查中对照着看。

3.4.1 网络设备队列溢出

这是最常见的原因。路由器和交换机的端口都有缓冲区,当流量瞬间增大,缓冲区满了,新来的包就只能被丢弃。你想想看,就像高速公路的收费站,车太多,排队排不下,后面的车就只能被劝退了。

3.4.2 链路质量差

物理链路的问题,比如网线接触不良、光纤衰减过大、无线信号干扰等,都会导致数据包在传输过程中损坏或丢失。我在一个工厂里遇到过,车间里的网线被叉车压过,外皮都破了,结果那个网段的丢包率一直居高不下。

3.4.3 接收端缓冲区不足

接收端的应用程序处理速度跟不上数据到达的速度,导致操作系统的接收缓冲区被填满。操作系统没办法,只能把新来的包丢掉。这种情况在Wireshark里通常会看到TCP Window Full或者ZeroWindow的提示。

3.4.4 防火墙或安全策略拦截

防火墙的规则配置不当,或者IDS/IPS误判,都可能把正常的流量当成攻击流量给拦截了。我遇到过最离谱的一次,是某安全设备把正常的TCP握手包当成了SYN Flood攻击,直接丢掉了。

3.4.5 MTU问题

当数据包的大小超过了路径上某个设备的MTU(最大传输单元),而且该设备不支持分片时,这个包就会被丢弃。这种情况通常会导致ICMP Fragmentation Needed的消息,但有些网络设备会直接静默丢弃,不通知发送端。

下面这张图,我画了丢包发生的几个主要位置,你可以直观地看到数据包在传输路径上可能在哪里被丢掉。

常见丢包位置示意图 发送端 路由器 队列溢出丢包 防火墙 策略拦截丢包 接收端 物理链路 链路质量差丢包 接收缓冲区 缓冲区满丢包 丢包原因总结 1. 路由器/交换机队列溢出 → 最常见,流量超过设备处理能力 2. 物理链路质量差 → 网线、光纤、无线信号问题 3. 防火墙/安全策略拦截 → 规则配置不当或误判 4. 接收端缓冲区不足 → 应用程序处理太慢