🎬 第二章 RTSP流媒体协议
📄 一句话概括

Wireshark 本身不抓包,抓包的是驱动(Windows 上是 Npcap,Linux 上是 libpcap)。 所以装的时候不勾 Npcap,装完就是「一块网卡都看不到」。

📝 本节和前面几节的关系

前面七个 Demo 都是自己造报文、自己算字节。这一节开始用工具看真实流量。 2.8.2 讲怎么抓到本机回环的包,2.8.3 讲怎么读。

一、它到底装了什么

一个常见的误解是「Wireshark 是个抓包软件」。 严格说它不做抓包,它做的是「解析 + 显示」。

真正抓包的是底下的驱动: ① Windows:Npcap(Wireshark 安装包里自带,但要手动勾选)。它基于微软的 NDIS 过滤驱动,能拿到进出网卡的原始帧。 ② Linux:libpcap,几乎所有发行版都有,装 Wireshark 时会自动带上。抓包需要 root 权限,或者用 dumpcap 配 setcap。 ③ macOS:也是 libpcap,但新版本要授权「完全磁盘访问」。

所以「装完看不到网卡」这件事,九成是 Npcap 没装或没勾。 重跑安装包,把 Npcap 那一项勾上就行,不用卸载重装。

二、Windows 上装的三步

① 下载:官网 wireshark.org,选 Windows x64 安装包。别去第三方站下,历史上有被捆广告的版本。 ② 安装:一路下一步,但在组件那一页要确认 Npcap 是勾上的。Npcap 自己的安装向导里还有一个选项叫「Support loopback traffic」,这一项必须勾——不然抓不到 127.0.0.1 的包(2.8.2 会用到)。 ③ 验证:打开 Wireshark,首页会列出所有网卡,每一块后面有跳动的小折线。有折线就说明能抓到。 双击任意一块开始抓,界面上开始滚包,就成了。

装完顺手做两件事: 一是把界面语言设成中文(Preferences → Appearance → Language),但建议新手先用英文——网上的教程和协议字段名全是英文,中文界面反而对不上。 二是记住快捷键 Ctrl+E(开始/停止抓包)和 Ctrl+F(查找)。这两个用得最多。

三、Linux 上更简单

sudo apt install wireshark 一句就完事,装的时候会问一句「是否允许非 root 用户抓包」,选是。

如果是服务器(没有图形界面),装 tshark: sudo apt install tshark,然后用 tshark -i eth0 -f "tcp port 554" 直接抓。 tshark 和 Wireshark 是同一套解析引擎,只是没有界面。 这一点在线上排查时特别有用——生产服务器不会给你装图形界面。

抓下来的文件可以用 -w 存成 pcap: tshark -i eth0 -w /tmp/a.pcap,然后拷回本地用 Wireshark 打开。 这是「线上抓、本地看」的标准做法。

四、它解析的到底是什么

前面 2.7 说过:一条 60 字节的 RTSP 请求,在线上是 114 字节。 多出来的 54 字节是三层壳:以太网头 14、IP 头 20、TCP 头 20。

Wireshark 干的事就是把这个嵌套一层层剥开: ① 第一层看以太网帧:源 MAC、目的 MAC、上层是什么协议。 ② 第二层看 IP 头:源 IP、目的 IP、TTL、协议号(TCP 是 6)。 ③ 第三层看 TCP 头:源端口、目的端口、序号、标志位。 ④ 第四层才看 RTSP 文本:OPTIONS rtsp://... RTSP/1.0。

所以「装 Wireshark」本质上只是装了个「解析器 + 抓包驱动」。 它的价值不在抓,而在「把字节流翻译成人能看懂的分层结构」。 理解了这一点,你就知道为什么它有时候会「解析错」——因为它按端口猜协议,猜错了就整段乱码。

五、动手 Demo:抓包文件就是一串带时间戳的帧

不装 Wireshark 也能理解它在干什么:pcap 文件格式简单到可以手写。 下面真造一个三帧的 pcap,再读回来,看里面到底有什么。

import struct

MAGIC, MAJ, MIN, TZ, SIG, SNAP, LINK = 0xA1B2C3D4, 2, 4, 0, 0, 65535, 1

gh = struct.pack("<IHHiIII", MAGIC, MAJ, MIN, TZ, SIG, SNAP, LINK)
print("全局头 %d 字节" % len(gh))

FR = [b"OPTIONS rtsp://x RTSP/1.0\r\n\r\n",
      b"RTSP/1.0 200 OK\r\nCSeq: 1\r\n\r\n",
      b"PLAY rtsp://x RTSP/1.0\r\nCSeq: 2\r\n\r\n"]

recs = []
for i, fr in enumerate(FR):
    hdr = struct.pack("<IIII", 1700000000, i * 1000, len(fr), len(fr))
    recs.append(hdr + fr)
    print("记录 %d:头 16 字节 + 数据 %d 字节" % (i + 1, len(fr)))

data = gh + b"".join(recs)
print("文件总长 %d 字节" % len(data))

m, a, b, tz, sig, snap, link = struct.unpack("<IHHiIII", data[:24])
print("读回:magic=0x%08X 版本=%d.%d snaplen=%d 链路=%d" % (m, a, b, snap, link))

off = 24
while off < len(data):
    sec, usec, cap, orig = struct.unpack("<IIII", data[off:off + 16])
    body = data[off + 16:off + 16 + cap]
    print("  %d.%06d 抓到 %d 字节 | %s"
          % (sec, usec, cap, body[:26].decode("ascii", "replace")))
    off += 16 + cap

实跑输出:

--------------------------------------------------------------------
抓包文件——pcap 就是一串带时间戳的帧
--------------------------------------------------------------------
① Wireshark 装好之后你会看到什么

  📋 **安装**:官网 wireshark.org 下载安装包,**安装时勾上 Npcap(抓包驱动),否则看不到网卡。**
  📋 **验证**:打开后选一块网卡,界面上开始滚包,就说明装好了。
  📋 **只抓本机回环**:Windows 上要选 `Npcap Loopback Adapter`,**Linux 上选 `lo`。**
  **抓不到 localhost 的包,九成是选错了网卡。**

② 抓包文件的结构:先自己造一个

  **pcap 文件 = 24 字节全局头 + 一串「16 字节记录头 + 帧数据」。**
**下面真写一个三帧的 pcap,再读回来。**

  **文件头 24 字节拆开:**
  字段         值             意思
  ------------------------------------------------------------
  magic        0xA1B2C3D4     字节序标记,反了就说明是大端
  版本         2.4            pcap 格式版本
  snaplen      65535          每帧最多抓多少字节
  链路类型     1              1 = 以太网

  **接着是一串记录,每条 16 字节头 + 数据本体:**

  #     秒             微秒     抓到     原始     内容前 26 字节
  -----------------------------------------------------------------------------
  1     1700000000     0        29       29       OPTIONS rtsp://x RTSP/1.0
  2     1700000000     1000     28       28       RTSP/1.0 200 OK CSeq: 1
  3     1700000000     2000     48       48       PLAY rtsp://x RTSP/1.0 CS

  **真实抓包里,每条记录的数据部分是以太网帧开头,里面套 IP 头、TCP 头,最后才是 RTSP 文本。**
  **Wireshark 干的事就是把这个嵌套一层层拆开给你看。**
**所以「装 Wireshark」这件事,本质上只是装了个解析器 + 抓包驱动。**

全局头只有 24 字节,里面最关键是 magic(字节序)和链路类型(1=以太网)。 每条记录的前 16 字节是「秒 + 微秒 + 抓到多少 + 原始多长」,后面才是帧数据。两个长度不一样,说明抓的时候被 snaplen 截断了。 这就是 Wireshark 打开一个 pcap 时读的全部结构。剩下的分层解析,全是它自己按协议规范加的。

30 秒实验

  1. 把 magic 改成 0xD4C3B2A1(字节序反过来),看 struct.unpack 读出来的版本号是不是变成 1024。这就是大端小端的坑。
  2. 把 snaplen 改成 20 再跑一笔,体会「抓到 20、原始 56」的意思。
  3. 给记录头的时间戳加 1000 微秒递增,这就是 Wireshark 里「时间列」的来源。

常见误区

  1. 「Wireshark 自己抓包」——抓包是 Npcap/libpcap 干的,Wireshark 只是解析加显示。
  2. 「装完就能抓 localhost」——必须勾 Npcap 的「Support loopback traffic」,否则回环适配器根本不出现。
  3. 「中文界面更好用」——协议字段名和网上教程全是英文,新手先用英文界面反而对得上。
自测三问(点开对答案) 1. Wireshark 装完看不到网卡,最可能是什么原因? —— **Npcap 没装或没勾。**它是抓包驱动,Wireshark 自己不会抓。 2. pcap 文件的全局头有多少字节? —— **24 字节。**后面每条记录是 16 字节头加帧数据。 3. 为什么一条 60 字节的 RTSP 请求在线上是 114 字节? —— **多了以太网头 14、IP 头 20、TCP 头 20,共 54 字节。**

相关笔记