tcpdump 和 Wireshark 就是最常用的网络抓包和分析工具,更是分析网络性能必不可少的利器。tcpdump 仅支持命令行格式使用,常用在服务器中抓取和分析网络包。Wireshark 除了可以抓包外,还提供了强大的图形界面和汇总分析工具,在分析复杂的网络情景时,尤为简单和实用。因而,在实际分析网络性能时,先用 tcpdump 抓包,后用 Wireshark 分析,也是一种常用的方法。
你一定遇到过这种情况:
线上服务突然挂了。日志翻遍了,就是找不到原因。
这时候如果有人问一句:"你抓包看了吗?"
大概率你会愣住。
不会?没抓过?不知道从哪下手?
但抓包这事,真没有那么神秘。只需要两样东西:tcpdump 和 Wireshark。
一个在命令行里抓取数据,一个在图形界面里帮你分析数据。配合好了,等于给网络装了个 X 光机。
tcpdump 是什么?一个命令行抓包工具。当前已经是Linux 系统的标配,安装上就能用。
它的设计很简单:就是把你机器上经过指定网卡的所有数据包给截下来,可以保留到本地进行分析。
# Ubuntu/Debiansudo apt install tcpdump# CentOS/RHELsudo yum install tcpdump# macOS 自带装完了试试:
sudo tcpdump -i any -c 5这行命令的意思是:监听所有网络接口,抓到 5 个包就停。
你会看到类似这样的输出:
13:42:15.123456IP 192.168.1.100.54321 > 93.184.216.34.80: Flags[S], seq 1234567890, ...13:42:15.234567IP 93.184.216.34.80 > 192.168.1.100.54321: Flags[S.], seq 987654321, ...13:42:15.345678IP 192.168.1.100.54321 > 93.184.216.34.80: Flags[.], ack 1, ...常用的几个参数如下:
-i any | |
-n | |
-c N | |
-s 0 | |
-w file.pcap | |
-A | |
-X |
来说两个实际的例子。
sudo tcpdump -i any port 22 -nn然后另开一个终端 SSH 到这台机器。你会看到三次握手:
→ Flags [S] # 客户端发 SYN← Flags [S.] # 服务端回 SYN-ACK→ Flags [.] # 客户端回 ACK[S] 就是 SYN,[.] 就是 ACK,[F] 是 FIN,[R] 是 RST。
三个包,一次 TCP 连接建立。最好的学习方式就是亲自试试。
sudo tcpdump -i any port 80 -A然后用 curl 或者浏览器访问一个 http 网站。你会直接看到 HTTP 请求的内容:
GET / HTTP/1.1Host: example.comUser-Agent: curl/7.68.0你在浏览器地址栏打了什么、提交了什么表单数据,全都看得一清二楚。
这就是为什么现在绝大部分网站都要求用 HTTPS。
但是,有个问题
用 tcpdump 直接在终端看,数据一多就懵了。满屏的十六进制,看起来非常费劲。
那怎么办?
这时候就需要更专业的工具了。
Wireshark 是 tcpdump 的"可视化升级版"。同一个底层原理——libpcap,同一个数据格式——pcap 文件。
区别在于:tcpdump 给了你一堆的数字,Wireshark 给了你一张地图。
安装也非常简单:
# Ubuntusudo apt install wireshark# macOSbrew install --cask wireshark最经典的用法就三步:
第一步,远程用 tcpdump 抓包存文件。
ssh user@your-server "sudo tcpdump -i any -w /tmp/dump.pcap -c 10000"第二步,把文件拷到本地。
scp user@your-server:/tmp/dump.pcap .第三步,用 Wireshark 打开。
双击 dump.pcap,或者:
wireshark dump.pcap这时候你看到的就是一个结构化的界面:上面是数据包列表,中间是协议详情,下面是一堆十六进制数据。
其实有三个真正非常有用的功能:
Wireshark 最强大的地方,就是它的过滤语法。
想只看 HTTP 流量?输入 http。
想看某个 IP 到 80 端口的 TCP 包?输入 ip.addr == 192.168.1.1 && tcp.port == 80。
想知道哪些包有重传?输入 tcp.analysis.retransmission。
这个过滤器语法有一整套体系,你不需要全记——记住一个核心原则就行:点号层进。
比如你想过滤 IP 层的 TTL 值:ip.ttl < 64想过滤 TCP 层的窗口大小:tcp.window_size < 1024
看着复杂,用多了就会越来越顺手。
在任意一个数据包上右键 → Follow → TCP Stream。
Wireshark 会自动帮你把整个 TCP 会话的数据"拼"出来。
你看到的就不是散落的数据包了,而是一段完整的对话:
GET /api/users HTTP/1.1Host: example.com→HTTP/1.1 200 OKContent-Type: application/json{"users": [...]}前后端联调的时候,参数传没传对、返回数据格式对不对,一眼就能看穿。
说实话,这个功能用顺手了,debug 效率至少翻一倍。
菜单栏 → Statistics → Protocol Hierarchy。
这个功能会告诉你:抓到的这些包,各层协议的占比是多少。
如果 ARP 包占比超过 50%,说明局域网有问题。如果 TCP 重传占比高,说明网络质量差。
这些数据比任何监控报警都来得更加直观。
现在你应该明白了:
最佳实践就一句话:服务器上用 tcpdump 收集,本地用 Wireshark 分析。
想更进一步?用管道直接把远程数据流拉到本地 Wireshark:
ssh user@server "sudo tcpdump -i any -l -w -" | wireshark -k -i -这行命令的意思是:在远程服务器上运行 tcpdump,把抓到的数据通过 SSH 管道源源不断地送到本机的 Wireshark 里实时显示。
不用下载文件,不用反复 scp。
按 Ctrl+C 就停。适合排查间歇性故障。
远程服务器上环境复杂,别什么都不加就 tcpdump -i any——服务器流量一大,光抓包就能把磁盘写满。
基本的过滤思路:
# 只抓某个 IPtcpdump -i any host 10.0.0.1# 只抓某个端口的 TCP 包tcpdump -i any tcp port 443# 只抓某个网段tcpdump -i any net 10.0.0.0/8生产环境抓包,一定要加 -c 或者 -C(按文件大小轮转)。
# 抓 10000 个包自动退出tcpdump -i any -c 10000 -w dump.pcap# 每个文件 100MB,最多 10 个文件轮转tcpdump -i any -C 100 -W 10 -w dump.pcap要特别注意不加限制就抓包,非常容易把磁盘打满。
如果你正在学 Linux 的网络性能分析,抓包是绕不开的。
等到哪一天,你再遇到线上问题,第一反应不是翻日志,而是:
"先抓个包看看。"
那就算入门了。
Linux性能调优系列
- CPU篇
- 内存篇
- 磁盘篇
- 网络篇
Linux性能优化:网络排查命令ss、ip、tc、ethtool 实战拆解
如果您有更好的理解和建议,可以免费加入知识星球,留言探讨~
