Wireshark抓包实战:TCP三次握手、四次挥手与超时重传全解析

1. 抓包之前先想清楚:TCP实验到底在验证什么

很多人做Wireshark的TCP实验,打开软件就开始抓,抓完一看满屏的包,完全不知道从哪下手。我刚开始接触的时候也是这样,抓了上百个包,最后只看出"哦,有三次握手",然后就没了。后来带过几批新人做实验,我发现问题的根源不在工具,而在于动手之前没有想清楚:这个实验到底要验证哪些TCP的核心机制。

TCP协议本身是一个庞大的话题,但落到Wireshark实验这个场景里,核心就是几件事:连接怎么建立、数据怎么传、连接怎么断、出了问题怎么恢复。这四件事对应到协议层面就是三次握手、数据传输与确认、四次挥手、超时重传与流量控制。你抓包的目的,就是用真实的报文把这几件事"看见"。

所以这篇内容适合两类人:一类是正在做计算机网络课程实验的学生,需要一份能直接照着操作的指南;另一类是想重新梳理TCP底层细节的开发者,平时写代码调网络问题,总觉得抓包看到的东西和课本对不上。不管你是哪一类,我都会从环境准备开始,一步步把每个环节的操作、参数、判断依据讲清楚,并且告诉你哪些地方容易踩坑。

关键词方面,Wireshark抓包、TCP三次握手、TCP四次挥手、序列号与确认号、超时重传、滑动窗口、流量控制这些会贯穿全文。我不会堆砌术语,而是把每个术语放到具体的报文里,让你看到它长什么样、为什么是这个值。

另外说一句,做这个实验不需要多复杂的网络环境。一台电脑,装好Wireshark,能上网或者能访问局域网内的某台服务器就够了。真正重要的是你对报文字段的解读能力,这个能力一旦建立起来,以后排查任何网络问题都用得上。

2. 实验环境搭建与抓包前的关键设置

2.1 工具准备与网卡选择

Wireshark的安装没什么好说的,官网下载对应系统的版本,一路下一步就行。Windows上安装的时候会提示安装Npcap,这个必须装,它是底层抓包驱动,不装的话Wireshark找不到任何网卡。安装过程中有一个选项叫"Restrict Npcap to administrators only",如果你不是管理员账户,建议不要勾选,否则普通用户权限下抓不了包。

装完之后打开Wireshark,你会看到网卡列表。这里有个选择的问题:到底抓哪块网卡。如果你用的是有线网络,选以太网那块;如果用WiFi,选WLAN那块。怎么确认?看网卡旁边的实时流量波形图,哪个在动就选哪个。我见过有同学对着一个完全没流量的虚拟网卡抓了半天,还纳闷为什么一个包都没有。

提示:如果你不确定选哪块网卡,可以先随便选一块,然后看Wireshark左上角的接口列表,有流量波动的就是当前活跃的网卡。

选好网卡之后,先不要急着点开始。Wireshark默认会抓取网卡上的所有流量,在实验室或者宿舍这种共享网络环境下,你会抓到大量和你无关的包。所以下一步是设置过滤器。

2.2 捕获过滤器的正确写法

过滤器分两种:捕获过滤器(Capture Filter)和显示过滤器(Display Filter)。这两个的区别很关键,很多人搞混。

捕获过滤器是在抓包之前设置的,它决定Wireshark"只抓哪些包",不满足条件的包直接丢弃,不写入内存。显示过滤器是在抓包之后用的,它不丢弃任何包,只是把满足条件的包"筛出来给你看"。捕获过滤器用BPF语法,显示过滤器用Wireshark自己的语法,两者写法完全不同。

做TCP实验,我建议在捕获阶段就加上过滤条件,减少干扰。常用的捕获过滤器写法:

# 只抓某台特定主机的流量 host 192.168.1.100 # 只抓某台主机且协议为TCP的流量 host 192.168.1.100 and tcp # 只抓某个端口相关的TCP流量 tcp port 80 # 抓某台主机与另一台主机之间的TCP流量 host 192.168.1.100 and host 203.0.113.5 and tcp

这里有个实操经验:如果你要访问的是某个网站,先用ping或者nslookup拿到它的IP地址,然后把IP填进捕获过滤器。但要注意,很多大型网站用的是CDN,你解析出来的IP和实际建立TCP连接的IP可能不一样。更稳妥的做法是先用一个宽松的过滤器抓一小段,看看实际通信的对端IP是什么,再收紧过滤条件。

注意:捕获过滤器一旦设置,不满足条件的包就彻底看不到了。如果你不确定过滤条件写得对不对,宁可先不加过滤器,抓完再用显示过滤器筛。抓多了可以删,抓少了就得重来。

2.3 抓包位置的选择与影响

这一点很多人忽略,但它直接影响你看到的报文内容。Wireshark抓包的位置决定了你能看到什么层次的协议数据。

如果你在本机抓包,看到的是本机网卡进出的流量。这种情况下,你看到的TCP报文是完整的,序列号、确认号、窗口大小、标志位都能看到。但有一个问题:本机的TCP/IP协议栈可能会对报文做一些处理,比如网卡硬件卸载(TSO、LRO),导致你看到的报文长度和实际传输的不一致。

如果你在中间设备上抓包(比如交换机镜像端口、路由器),看到的是经过转发的流量。这种方式的优点是不影响本机协议栈,看到的是"真实在网络上跑的包"。缺点是需要额外的设备配置权限。

对于课程实验来说,本机抓包完全够用。但你要知道一个现象:有时候你会看到一些"奇怪"的报文,比如长度特别大的TCP段,或者校验和显示不正确。这通常是网卡硬件卸载导致的,不是真的有问题。可以在Wireshark的设置里关掉相关选项,或者直接忽略这些异常。

2.4 实验目标的确定与流量构造

抓包之前,你得明确这次要抓什么。TCP实验通常要覆盖以下几个场景:

  • 三次握手:建立连接的过程
  • 数据传输:发送数据、确认收到、窗口更新
  • 四次挥手:断开连接的过程
  • 超时重传:丢包后的恢复机制
  • 流量控制:接收方通过窗口大小控制发送方速率

要触发这些场景,你需要构造相应的流量。最简单的办法是访问一个网页,HTTP over TCP的交互过程天然包含握手、数据传输和挥手。但网页访问的流量比较杂,有多个并发连接,分析起来不够干净。

我更推荐用curl或者wget访问一个简单的HTTP资源,比如一个纯文本文件。这样只有一条TCP连接,报文序列清晰。如果要触发超时重传,可以用tc命令(Linux)或者网络模拟工具人为制造丢包。如果要观察流量控制,可以传输一个大文件,同时观察接收窗口的变化。

# 用curl访问一个HTTP资源,只请求一次 curl -v http://example.com/test.txt # 如果要持续传输大文件观察窗口变化 curl -o /dev/null http://example.com/largefile.bin

在Windows上,可以用PowerShell的Invoke-WebRequest,或者直接用浏览器访问。关键是一次只做一件事,不要同时开多个应用,否则抓到的包会混在一起,分析难度直线上升。

3. 三次握手:从报文里读出连接建立的每一步

3.1 抓取三次握手的操作步骤

先启动Wireshark,选好网卡,设置捕获过滤器为tcp port 80(假设你访问的是HTTP服务)。然后点开始抓包,接着在浏览器或命令行里发起请求。请求完成后,回到Wireshark点停止。

这时候你应该能看到一串TCP报文。找到第一个SYN包,这就是三次握手的起点。Wireshark的显示过滤器在这里很好用,输入tcp.flags.syn == 1就能筛出所有SYN包。

三次握手的三个报文分别是:

  1. 客户端发送SYN,序列号为初始序列号(ISN),比如Seq=0
  2. 服务端回复SYN+ACK,序列号为服务端的ISN,确认号为客户端ISN+1
  3. 客户端发送ACK,确认号为服务端ISN+1

在Wireshark的报文详情面板里,展开"Transmission Control Protocol"这一层,你能看到所有关键字段。我建议你把这三个包的这几个字段都记下来:

报文标志位序列号确认号窗口大小
第一个包SYN客户端ISN0客户端窗口
第二个包SYN, ACK服务端ISN客户端ISN+1服务端窗口
第三个包ACK客户端ISN+1服务端ISN+1客户端窗口

3.2 序列号与确认号的解读逻辑

序列号和确认号是TCP里最容易让人迷糊的东西,但理解了之后其实很直观。

序列号表示"我这个报文里携带的数据的第一个字节在整个数据流中的位置"。注意,SYN和FIN这两个标志位虽然不携带数据,但它们各占一个序列号。这就是为什么第二个包的确认号是"客户端ISN+1"——那个+1就是确认收到了客户端的SYN。

确认号表示"我期望下一次收到你的数据的第一个字节的序号"。它等于"我已经收到的最后一个字节的序号+1"。这是一种累积确认机制,确认号N表示N之前的所有字节都收到了。

举个例子:客户端ISN是1000,发送SYN。服务端回复SYN+ACK,确认号是1001,意思是"我收到了你的SYN(占序号1000),我期望你下一个字节从1001开始"。服务端的ISN假设是5000,那么客户端回复的ACK确认号就是5001。

提示:Wireshark默认显示的是相对序列号,也就是把ISN显示为0,后续的序列号都是相对于ISN的偏移。这样看起来更直观。如果你想看真实的绝对序列号,可以在TCP协议首选项里关掉"Relative sequence numbers"。

3.3 为什么是三次而不是两次或四次

这个问题面试经常问,但很多人背答案不理解。从报文的角度看,三次握手的本质是双方各自确认自己和对方的收发能力都正常。

第一次握手:客户端发SYN,服务端收到。服务端确认了"客户端的发送能力正常,我的接收能力正常"。 第二次握手:服务端发SYN+ACK,客户端收到。客户端确认了"我的发送能力正常,服务端的接收和发送能力都正常"。 第三次握手:客户端发ACK,服务端收到。服务端确认了"客户端的接收能力正常"。

两次不够,因为服务端无法确认客户端能收到自己的报文。四次多余,因为第二次握手已经把服务端的SYN和ACK合并了。

从抓包的角度,你可以验证这一点:第一个SYN包之后,如果服务端没有回复SYN+ACK,客户端会重传SYN。重传的时间间隔是指数退避的,通常是1秒、2秒、4秒、8秒这样递增。你可以在Wireshark里看到这些重传的SYN包,序列号相同,时间间隔逐渐拉大。

3.4 握手阶段的常见异常与排查

实际抓包时,三次握手不一定都顺利。几种常见情况:

SYN没有响应:客户端发了SYN,但一直没有收到SYN+ACK。可能原因是对端服务没启动、防火墙拦截、或者路由不可达。在Wireshark里表现为只有SYN包,没有后续。

SYN被拒绝:服务端回复的是RST+ACK而不是SYN+ACK。这通常意味着目标端口没有服务在监听。RST包在Wireshark里会标红,很容易识别。

SYN重传:客户端发了多个SYN,序列号相同,时间间隔递增。这说明第一个SYN丢了或者响应丢了。如果最终握手成功,说明是偶发丢包;如果一直重传到超时,说明连接建立失败。

SYN+ACK重传:服务端发了多个SYN+ACK,说明客户端没有回复ACK。可能是客户端的ACK丢了,也可能是客户端已经放弃了连接。

排查的时候,重点看时间间隔和序列号。时间间隔能告诉你重传了几次、退避到什么程度;序列号能告诉你这些包是不是同一个连接的。

4. 数据传输与确认:看懂滑动窗口和确认机制

4.1 数据报文的抓取与筛选

三次握手完成后,紧接着就是数据传输。在Wireshark里,你可以用显示过滤器tcp.len > 0来筛出所有携带数据的TCP报文。这些报文的TCP载荷长度大于0,说明它们承载了应用层数据。

如果你访问的是一个网页,数据报文可能比较多,因为HTML、CSS、JS、图片都是通过TCP传输的。为了分析方便,建议访问一个纯文本文件,这样数据报文少而清晰。

抓取数据报文的时候,注意观察几个关键字段:

  • Seq:这个报文携带的数据的起始序号
  • Ack:对之前收到的数据的确认
  • Len:TCP载荷长度
  • Win:接收窗口大小

这四个字段的组合,能让你还原出整个数据传输的过程。

4.2 序列号推进与累积确认

TCP的数据传输是字节流,不是报文流。每个字节都有一个序号,序列号标识的是"这个报文里第一个字节的序号"。如果报文携带了100字节的数据,那么下一个报文的序列号就是当前序列号+100。

确认号是累积的。假设客户端连续发了三个报文,序列号分别是1、101、201,每个携带100字节。服务端收到后,可以只发一个ACK,确认号是301,表示"1到300字节我都收到了,我期望下一个字节从301开始"。这就是累积确认,它减少了确认报文的数量。

在Wireshark里,你可以通过tcp.analysis.ack_rtt字段看到每个ACK的往返时间。这个值反映了从发送数据到收到确认的时间差,是评估网络延迟的重要指标。

注意:Wireshark的"Expert Information"功能会自动标记一些异常,比如重传、乱序、重复ACK。在菜单栏的"分析"里可以打开。做实验的时候,这个功能能帮你快速定位问题报文。

4.3 滑动窗口的工作机制

滑动窗口是TCP流量控制的核心。接收方通过TCP头部的窗口大小字段告诉发送方:"我还能接收多少字节的数据"。发送方根据这个值调整发送速率,确保不会把接收方的缓冲区撑爆。

窗口大小是动态变化的。当接收方处理了缓冲区里的数据,窗口会变大;当接收方来不及处理,窗口会变小,甚至变成0。窗口为0的时候,发送方会停止发送数据,直到接收方发送窗口更新通知。

在Wireshark里,你可以通过tcp.window_size_value字段看到每个报文的窗口大小。如果要做流量控制实验,可以传输一个大文件,同时观察窗口大小的变化曲线。Wireshark的"统计"菜单里有"TCP流图形",可以画出窗口大小随时间的变化。

这里有一个容易混淆的概念:窗口缩放因子。TCP头部的窗口字段只有16位,最大表示65535字节。但在高速网络中,这个值太小了。所以TCP引入了窗口缩放选项,在握手阶段协商一个缩放因子,实际的窗口大小等于窗口字段值左移缩放因子位。Wireshark会自动计算实际窗口大小,显示在tcp.window_size字段里。

4.4 延迟确认与Nagle算法的影响

实际抓包时,你会发现有些数据报文没有立即被确认,而是等了一小段时间。这是延迟确认机制在起作用。接收方不会每收到一个报文就发一个ACK,而是等一小段时间(通常40ms到200ms),看有没有更多数据可以一起确认。这样可以减少ACK报文的数量,提高网络效率。

另一个影响报文发送节奏的是Nagle算法。它要求发送方在收到前一个报文的ACK之前,不发送新的小报文。这样可以把多个小数据合并成一个大的TCP段发送,减少网络上的小包数量。

这两个机制在Wireshark里的表现是:你可能会看到"一个ACK确认了多个数据报文",或者"多个小数据被合并成一个大的TCP段"。这些都不是异常,而是TCP的正常优化行为。

但有时候这些优化会带来问题。比如在交互式应用中,延迟确认和Nagle算法叠加,可能导致明显的延迟。这时候可以通过设置TCP_NODELAY选项来禁用Nagle算法。在Wireshark里,你可以通过观察报文的时间间隔来判断是否存在这种问题。

4.5 数据阶段的异常分析

数据传输阶段常见的异常包括:

重传:同一个序列号的数据被发送了多次。Wireshark会标记为"TCP Retransmission"。重传的原因可能是数据丢了,也可能是ACK丢了。

快速重传:接收方收到乱序报文时,会立即发送重复ACK。发送方收到三个重复ACK后,不等超时就重传丢失的报文。这就是快速重传机制。在Wireshark里,你会看到三个相同的ACK,紧接着一个重传的数据报文。

乱序:报文的序列号不连续,后面的报文先到了。Wireshark会标记为"TCP Out-of-Order"。乱序本身不是错误,但如果频繁发生,说明网络路径上存在多路径或者负载均衡。

零窗口:接收方通告窗口大小为0,发送方停止发送。这通常意味着接收方应用层处理速度跟不上。如果零窗口持续很长时间,可能是接收方应用出了问题。

窗口探测:当窗口为0时,发送方会定期发送窗口探测报文,询问接收方窗口是否更新。这个报文只携带1字节数据或者不携带数据,序列号是上一个已发送字节的序号。

5. 四次挥手:连接释放的完整过程

5.1 挥手报文的抓取与识别

四次挥手发生在数据传输结束之后。主动关闭方发送FIN,被动关闭方回复ACK,然后被动关闭方也发送FIN,主动关闭方回复ACK。这四个报文完成了连接的完全释放。

在Wireshark里,用显示过滤器tcp.flags.fin == 1可以筛出所有FIN包。通常你会看到两个FIN包,一个来自客户端,一个来自服务端。

挥手的四个报文:

  1. 主动关闭方发送FIN+ACK,序列号为最后一个数据字节的序号+1
  2. 被动关闭方回复ACK,确认号为FIN的序列号+1
  3. 被动关闭方发送FIN+ACK,序列号为它最后一个数据字节的序号+1
  4. 主动关闭方回复ACK,确认号为FIN的序列号+1

注意,FIN和SYN一样,虽然不携带数据,但各占一个序列号。这就是为什么确认号要+1。

5.2 为什么挥手需要四次

挥手比握手多一次,原因是TCP连接是全双工的。握手的时候,服务端可以把SYN和ACK合并成一个报文,因为服务端收到SYN后可以立即决定是否接受连接。但挥手的时候,被动关闭方收到FIN后,可能还有数据没发完,不能立即发送FIN。所以它先回复一个ACK,等数据发完了再发送FIN。

这就导致了四次挥手:FIN、ACK、FIN、ACK。中间的两个报文不能合并,因为被动关闭方的数据发送和连接关闭是两个独立的事件。

在某些情况下,被动关闭方没有数据要发了,它可以把ACK和FIN合并成一个报文,这样就变成了三次挥手。在Wireshark里,你会看到第二个报文同时带有ACK和FIN标志。

5.3 TIME_WAIT状态的意义

主动关闭方发送最后一个ACK后,会进入TIME_WAIT状态,等待2MSL(最大报文段生存时间)后才真正关闭连接。在Linux上,这个时间通常是60秒。

TIME_WAIT的作用有两个:一是确保最后一个ACK能到达被动关闭方,如果ACK丢了,被动关闭方会重传FIN,主动关闭方还能响应;二是让本次连接的所有报文在网络中消失,避免影响后续使用相同四元组的新连接。

在Wireshark里,你无法直接看到TIME_WAIT状态,因为它是协议栈内部的状态。但你可以通过netstat命令查看:

# Linux/Mac netstat -an | grep TIME_WAIT # Windows netstat -an | findstr TIME_WAIT

如果TIME_WAIT状态的连接过多,可能会耗尽本地端口资源。这时候可以调整内核参数,比如开启TIME_WAIT重用。但这是把双刃剑,需要根据实际场景权衡。

5.4 挥手阶段的异常情况

FIN重传:主动关闭方发了FIN,但没有收到ACK,会重传FIN。在Wireshark里表现为多个FIN包,序列号相同。

RST代替FIN:有时候连接不是正常关闭的,而是被RST强制终止。RST包表示"连接异常,立即终止"。常见于应用崩溃、端口关闭、或者协议错误。在Wireshark里,RST包会被标红。

半关闭状态:一方发送了FIN,但另一方还在发送数据。这时候连接处于半关闭状态。在Wireshark里,你会看到FIN之后还有数据报文。这是正常的,TCP允许半关闭。

连接被拒绝:如果主动关闭方发送FIN后收到RST,说明对端已经不认这个连接了。可能是对端已经关闭了连接,或者中间设备拦截了报文。

6. 超时重传与流量控制:TCP的可靠性保障

6.1 超时重传的触发条件与观察方法

超时重传是TCP保证可靠性的核心机制。发送方每发送一个报文,就启动一个定时器。如果在定时器超时之前没有收到确认,就重传这个报文。

在Wireshark里,超时重传的报文会被标记为"TCP Retransmission"。你可以通过tcp.analysis.retransmission过滤器筛出所有重传报文。

要人为制造重传,可以用网络模拟工具制造丢包。在Linux上,tc命令可以模拟丢包:

# 在网卡eth0上模拟10%的丢包率 sudo tc qdisc add dev eth0 root netem loss 10% # 实验结束后删除规则 sudo tc qdisc del dev eth0 root

在Windows上,可以用Clumsy或者NetLimiter这类工具模拟丢包。

观察重传的时候,注意重传的时间间隔。TCP使用指数退避算法,第一次重传等待1个RTO(重传超时时间),第二次等待2个RTO,第三次等待4个RTO,以此类推。RTO本身是根据RTT动态计算的,Wireshark会显示每个重传报文的相对时间。

6.2 快速重传与重复ACK

超时重传的问题是等待时间太长。如果发送方收到三个重复ACK,就可以推断某个报文丢了,立即重传,不用等超时。这就是快速重传。

重复ACK的产生过程:接收方收到乱序报文时,会立即发送ACK,确认号还是期望的那个序号。发送方收到多个相同的ACK,就知道中间有报文丢了。

在Wireshark里,你会看到这样的序列:发送方发了Seq=1、Seq=101、Seq=201三个报文,但Seq=101丢了。接收方收到Seq=1后回复Ack=101,收到Seq=201后还是回复Ack=101(因为101没收到)。发送方收到三个Ack=101后,立即重传Seq=101。

Wireshark会把重复的ACK标记为"TCP Dup ACK",把快速重传的报文标记为"TCP Fast Retransmission"。

6.3 流量控制与拥塞控制的区别

这两个概念经常被混淆,但在Wireshark里它们的表现不同。

流量控制是接收方通过窗口大小告诉发送方"我能收多少"。它是端到端的,只涉及收发双方。在Wireshark里,你看到的是窗口大小的变化。

拥塞控制是发送方根据网络状况调整发送速率。它涉及整个网络路径。在Wireshark里,你看到的是发送速率的変化,以及拥塞窗口的变化(但拥塞窗口是发送方内部状态,Wireshark看不到,只能通过发送速率推断)。

拥塞控制有四个阶段:慢启动、拥塞避免、快速重传、快速恢复。在Wireshark里,你可以通过"统计"菜单里的"TCP流图形"看到吞吐量的变化曲线。慢启动阶段吞吐量指数增长,拥塞避免阶段线性增长,发生丢包后吞吐量骤降。

6.4 零窗口与窗口探测的实战分析

当接收方的缓冲区满了,它会通告窗口大小为0。发送方收到零窗口通知后,停止发送数据,但会定期发送窗口探测报文。

窗口探测报文的特点是:序列号是上一个已发送字节的序号,携带1字节数据或者不携带数据。接收方收到探测报文后,如果窗口已经更新,会回复新的窗口大小;如果窗口还是0,会回复一个ACK,窗口仍然为0。

在Wireshark里,你可以用tcp.analysis.zero_window过滤器找到零窗口报文,用tcp.analysis.window_update找到窗口更新报文。零窗口持续的时间越长,说明接收方应用处理越慢。

如果零窗口一直不更新,可能是接收方应用卡死了。这时候需要检查接收方的应用状态和系统资源。

7. 常见问题与排查技巧实录

7.1 抓不到包或抓到的包不完整

这是新手最常遇到的问题。可能的原因和排查方法:

现象可能原因排查方法
一个包都没有选错网卡看接口列表的流量波形,选活跃的网卡
只有部分包捕获过滤器太严先去掉过滤器,抓完再用显示过滤器筛
包不完整网卡硬件卸载关闭TSO/LRO,或在Wireshark里忽略校验和错误
看不到应用层数据加密协议HTTPS流量是加密的,只能看到TCP层,看不到HTTP内容

提示:如果抓HTTPS流量,你只能分析TCP层的行为,看不到HTTP请求和响应。要做应用层分析,需要配置SSLKEYLOGFILE或者使用其他方法。

7.2 序列号和确认号看不懂

这是概念问题,不是操作问题。记住几个要点:

  • 序列号是字节序号,不是报文序号
  • SYN和FIN各占一个序列号
  • 确认号是累积确认,表示期望收到的下一个字节
  • Wireshark默认显示相对序列号,ISN显示为0

如果还是看不懂,找一个简单的HTTP请求,把每个报文的Seq、Ack、Len三个字段列出来,手动算一遍。算过一遍就明白了。

7.3 重传和乱序分不清

重传和乱序在Wireshark里都会显示为"异常的序列号",但它们的含义不同:

  • 重传:同一个序列号的数据被发送了多次,说明数据可能丢了
  • 乱序:序列号不连续,后面的报文先到了,说明网络路径上存在多路径

Wireshark会自动标记这两种情况,但有时候会误判。判断的依据是时间和上下文。如果同一个序列号在短时间内出现多次,大概率是重传;如果序列号跳跃但每个只出现一次,大概率是乱序。

7.4 窗口大小为什么一直是0

零窗口说明接收方缓冲区满了。排查思路:

  1. 检查接收方应用是否在处理数据,还是卡住了
  2. 检查接收方的系统资源,CPU、内存是否正常
  3. 检查接收方的TCP接收缓冲区设置,是否太小
  4. 如果是自己写的应用,检查读取数据的逻辑是否有问题

在Linux上,可以用ss -tln查看socket的接收队列和发送队列。如果Recv-Q很大,说明应用没有及时读取数据。

7.5 实验报告怎么写才不像抄的

这个问题很实际。我的建议是:不要只贴截图,要写你的分析过程。

比如三次握手,不要只放三个包的截图,要写出:

  • 你抓的是什么流量,为什么选这个
  • 三个包的序列号和确认号分别是多少,为什么是这个值
  • 你观察到了什么异常(如果有),你是怎么判断的
  • 你对三次握手有了什么新的理解

这样的报告才有价值,也才能体现出你真的动手做了实验,而不是复制粘贴。

8. 从实验到实战:这些技能能用在什么地方

做完这个实验,你获得的不只是几个截图,而是一种用报文验证协议行为的能力。这种能力在实际工作中有很多应用场景。

排查网络性能问题:用户反馈某个接口很慢,你可以抓包看看是TCP重传多、窗口小、还是RTT高。每个指标对应不同的优化方向。

调试分布式系统:微服务之间的调用超时,抓包能看到是连接建立慢、数据传输慢、还是对端处理慢。比看日志更直接。

理解安全攻击:SYN Flood、RST攻击、会话劫持,这些攻击在Wireshark里都有明显的报文特征。理解了正常行为,才能识别异常行为。

优化应用性能:通过观察TCP的行为,你可以判断是否需要调整Nagle算法、延迟确认、窗口大小等参数。这些调整对高并发应用的影响很大。

我个人在实际工作中的体会是,抓包分析这项技能,入门容易精通难。工具的使用几天就能学会,但报文背后的协议逻辑和网络行为,需要长期的积累和思考。每次遇到网络问题,不要急着搜答案,先抓个包看看,往往能发现意想不到的线索。

最后分享一个小技巧:Wireshark的"追踪TCP流"功能(Follow TCP Stream)可以把一条TCP连接的所有应用层数据拼在一起显示。分析HTTP请求响应的时候特别有用,能直接看到完整的交互内容。但要注意,这个功能只对未加密的流量有效,HTTPS流量看到的是乱码。

相关新闻

Python+Vue学校实验室管理系统开发指南:Django与Flask选型实践

Python+Vue学校实验室管理系统开发指南:Django与Flask选型实践

从标题说起,这类“PythonVue的学校实验室管理系统”几乎是每所高校信息类项目的标配题目。你一看关键词就明白,它涉及三个技术栈:Python做后端、Vue做前端、PyCharm做开发环境,而Django和Flask则是Python生态里真正决定你项目骨架…

2026/10/20 4:07:25 阅读更多 →
Wireshark抓包分析TCP协议:从三次握手到重传机制实战

Wireshark抓包分析TCP协议:从三次握手到重传机制实战

1. 抓包之前先想清楚:TCP实验到底在验证什么很多人做Wireshark的TCP实验,打开软件就开始抓,抓完对着一堆密密麻麻的包发呆,不知道从哪看起。我刚开始接触的时候也是这样,抓了上百个包,最后只看出“哦&#…

2026/10/20 4:07:25 阅读更多 →
知识可搜索,技能需管理:一套从盘点、定位到深耕的实战框架

知识可搜索,技能需管理:一套从盘点、定位到深耕的实战框架

先把话说清楚:这个标题看起来就一个词“skills”,但真正想做事的都知道,这词背后不是简历上那行“熟练掌握XX软件”的自我感觉良好,而是一整套关于“怎么识别、怎么盘点、怎么深挖、怎么把能力变成结果”的方法论。这篇文章不聊虚…

2026/10/20 4:06:25 阅读更多 →

最新新闻

PyTorch深度学习实战:从环境搭建到性能调优的完整指南

PyTorch深度学习实战:从环境搭建到性能调优的完整指南

1. 从零上手 PyTorch:为什么它成了深度学习项目的第一选择如果你刚开始接触深度学习,或者从其他框架迁移过来,大概率会听到身边人反复提到 PyTorch 这个名字。它不是一个能直接解决某个业务问题的应用软件,而是一套用来搭建和训练…

2026/10/20 4:50:51 阅读更多 →
嵌入式语音识别:MFCC+DTW定点C代码完整落地指南

嵌入式语音识别:MFCC+DTW定点C代码完整落地指南

简介:基于MFCC与DTW算法的定点数语音识别C代码工程,适合嵌入式开发者、算法工程师及语音识别入门者。整个资源包共103个文件,压缩后仅1018KB,主体为C源文件与头文件(含dtw_fixpt.c、wxp_mfcc.c、fft.c等)&a…

2026/10/20 4:50:51 阅读更多 →
Agent推理成本降30%:AutoTool核心设计深度拆解

Agent推理成本降30%:AutoTool核心设计深度拆解

上个月在某个AI顶会的Poster区转了一圈,今年大家最关心的不再是哪个模型的能力又涨了几个点,而是Agent应用的账单怎么降下来。起因很多人都知道:一款叫Jev的Agent应用突然火了起来,演示视频里它用自然语言调度十几个工具&#xff…

2026/10/20 4:50:51 阅读更多 →
Agent智能体工作流程全解析:从主循环到工具调用

Agent智能体工作流程全解析:从主循环到工具调用

如果你最近在关注大模型相关的技术动态,那你大概率绕不开Agent(智能体)这个词。朋友圈、技术社区、各种线上分享会,都在说 Agent 会改变我们和 AI 协作的方式,说它是新一代的工作流引擎。但我翻了大量文章之后&#xf…

2026/10/20 4:50:51 阅读更多 →
OSPF邻居与邻接关系详解:从状态机到排障实战

OSPF邻居与邻接关系详解:从状态机到排障实战

1. 为什么邻居和邻接这两个词值得单独拎出来讲刚接触OSPF的人,十有八九会在“邻居”和“邻接”这两个词上栽跟头。书上看一遍,觉得懂了;抓包一看,Hello包满天飞,状态机从Down一路跳到Full,又觉得好像没那么…

2026/10/20 4:50:51 阅读更多 →
2026大模型选型指南:模型维度与应用维度落地逻辑全解析

2026大模型选型指南:模型维度与应用维度落地逻辑全解析

2026年这个节点做技术选型,最魔幻的一件事是:大模型已经多到需要专门建一张Excel台账来管理,但真正推到业务里去用的时候,大部分人还是拿着几个“名气最大”的模型反复做评测,最后又因为效果和预期对不上,灰…

2026/10/20 4:49:50 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →