OSI定义分析
首先开始抓了一个WLAN的包,随便点开一个开始说明。


- 物理层
Frame 175371: Packet, 134 bytes on wire (1072 bits), 134 bytes captured (1072 bits) on interface \Device\NPF_{22328337-C80E-46DA-82B3-4F8B5A6EFE66}, id 0
这一行是 Wireshark 对捕获到的原始比特流的总结。
Frame 175371: 这个包在当前抓包文件中的序号。
134 bytes on wire: 在网线(物理介质)上传输的原始大小(包括了所有报头)。
1072 bits: 134 字节换算成二进制位数(134 \\times 8 = 1072)。
captured (1072 bits): 实际抓取到的长度。有时为了节省空间只抓取头部,这里是全量抓取。
interface...: 抓包所使用的网卡标识符(Windows 的网卡 GUID)。

2.数据链路层
Ethernet II, Src: Intel_02:00:30 (08:9d:f4:02:00:30), Dst: NewH3CTechno_0e:06:01 (70:c6:dd:0e:06:01)
负责局域网内"下一跳"的定位,依靠 MAC 地址。
Ethernet II: 以太网第二代标准帧格式。
Src (Source): 源 MAC 地址 (
08:9d:f4:02:00:30)。前三位Intel_02代表网卡制造商是英特尔。Dst (Destination): 目的 MAC 地址 (
70:c6:dd:0e:06:01)。这里通常是局域网网关(路由器)的地址。

3.网络层
Internet Protocol Version 4, Src: 192.168.247.20, Dst: 112.19.197.63
负责在复杂的互联网中进行路径选择,依靠 IP 地址。
Version 4: 使用的是 IPv4 协议。
Src (Source): 源 IP 地址 (
192.168.247.20)。这台电脑的内网 IP。Dst (Destination): 目的 IP 地址 (
112.19.197.63)。这是远程服务器的公网 IP。

4.传输层
Transmission Control Protocol, Src Port: 7926, Dst Port: 443, Seq: 2127, Ack: 255, Len: 80
负责端到端的数据传输质量、顺序和端口定位。
Src Port: 源端口 (
7926)。这台电脑上随机分配的临时端口,用于接收服务器的回包。Dst Port: 目的端口 (
443)。服务器的 HTTPS 端口。Seq (Sequence Number): 序列号 (
2127)。表示这段数据在整个发送流中的位置,用于拼装碎片。Ack (Acknowledgment Number): 确认号 (
255)。告诉对方:"我已收到你发来的 254 号及之前的数据,请发 255 号给我"。Len: 数据净荷长度 (
80)。指 TCP 头部之后,实际承载的载荷(即 TLS 数据)的大小。

5.表示层&会话层
Transport Layer Security
这是最核心的内容,但由于它被加密了,Wireshark 只能识别出它的协议。
作用: 在 TCP 之上建立加密通道。
含义: 这里的 80 字节数据不是明文,而是经过加密的 TLS 记录(Record)。它可能是一个加密的应用数据包,或者是握手过程中的加密确认。

一、物理层

二、数据传输层

三、网络层

四、传输层 TCP数据包头(Transmission Control Protocol)


1.source port
告诉接收方:这个数据是从哪个应用程序发出来的。

2.destination port
决定了数据包进入对方电脑后交给哪个程序。

3.sequence number
保证了数据的有序性。

4.acknowledge number
确认对方发来的数据已经被成功接收。

5.data offset
这个值表示TCP报文段的数据起始处距离报文段的起始处的距离,也就是TCP头的长度。

6.reserved
无,为之后使用保留的6位,全部为0。
7.URG ACK PSH RST SYN FIN
控制标志位 (Flags):
URG (Urgent): 紧急指针有效,告诉系统此报文段中有紧急数据。
ACK (Acknowledgment): 确认序号有效。TCP 规定连接建立后,所有报文的 ACK 必须置为 1。
PSH (Push): 接收方应尽快将这个报文段交给应用层,而不是在缓冲区排队。
RST (Reset): 重置连接。如果连接乱了或者出错了,用它来强行断开。
SYN (Synchronize): 在连接建立时用来同步序号。看到它,说明正在"握手"。
FIN (Finish): 发送方任务已完成,准备释放连接。

8.Window
用于防止发送方发得太快,接收方处理不过来(流量控制)

9.Checksum
检查报文段在传输过程中是否被损坏。如果校验失败,包会被丢弃。

10.Urgent Pointer
只有当 URG 标志位为 1 时才有效,指出紧急数据的末尾在报文段中的位置。

11.options
常见的如最大报文段长度 (MSS)、窗口扩大因子等。
如果这个特定的包没有携带额外的选项信息(比如握手已经完成,不再需要交换 MSS 等信息),那么 Options 和 Padding 字段就不会出现。
12.padding
确保 TCP 头部长度是 32 位的整数倍。
13.data
实际要传输的内容(图中显示 TCP payload (80 bytes)

五、表示层&会话层 数据包:Transport Layer Security(TLS)

1.第一个记录:Change Cipher Spec (更改密码规范)
Content Type: Change Cipher Spec (20): 这是记录类型的标识。
20代表这是一个"更改密码规范"的消息。Version: TLS 1.2 (0x0303): * 注意: 虽然顶层显示是 TLS 1.3,但这里显示 1.2 是为了向后兼容性(Middlebox Compatibility Mode)。很多老旧的网络设备不认识 1.3,所以 TLS 1.3 会在这里伪装成 1.2 的版本号。
Length: 1: 表示这个消息的内容非常短,只有一个字节。
作用: 在 TLS 1.3 中,这个包通常是一个"信号",告诉对方:"从现在开始,我后续发出的所有数据都会按照我们刚才协商好的加密算法进行加密了"。

2.第二个记录:Application Data (应用数据)
这是真正的业务数据所在,但已经被加密了。
Opaque Type: Application Data (23):
23代表这层封装的是应用层数据。在 TLS 1.3 中,为了隐藏真实的数据类型,它被称为"不透明类型(Opaque Type)"。Version: TLS 1.2 (0x0303): 同样是出于兼容性考虑,填写的版本号。
Length: 69: 表示加密后的数据长度为 69 字节。
Encrypted Application Data: 这是核心部分,显示为一串十六进制长字符串(以
94f9609a...开头)。
现状: 它是加密的。这意味着任何中间人(包括 Wireshark 默认情况下)都无法直接看到里面的内容。
真实身份: 下面一行
[Application Data Protocol: Hypertext Transfer Protocol]提示了 Wireshark 认为这里面封装的是 HTTP 协议数据。

TCP心跳解包
使用tcp.analysis.keep_alive过滤,可以得到心跳大概是15秒一次。注意IP的地址,直接看相邻的两个包来计算差值是不对的。

查看其中一个

Wireshark 的内置算法通过比对序列号发现:这个包的 Sequence Number (2564) 刚好比之前收到的正常包的序列号预期小了1, 这个包只带了1个字节的数据(十六进制数据区最后的 00)。
这正是典型的 TCP 心跳策略:发送一个已经确认过的序列号位置的"垃圾数据",强迫接收方回一个确认包(ACK)。
使用tcp.analysis.keep_alive || tcp.analysis.keep_alive_ack指令可以同时看到TCP keep-alive 和 TCP keep-alive ACK成对出现。帧序号没有紧挨着的原因是,WLAN不仅进行TCP通信。

rk3588 视频流 RTSP包
rk3588推流命令,同时需要PC端VLC播放器拉流播放配合:
gst-launch-1.0 v4l2src device=/dev/video22 ! video/x-raw,width=1920,height=1080,framerate=15/1 ! mpph264enc ! h264parse / ! rtspclientsink location=rtsp://192.168.137.10:8554/cam protocols=tcp
成功推流、拉流之后

Channel 0x00 是 RTSP 协议中默认的视频 RTP 通道。
在 GStreamer 命令里写的是 framerate=15/1(15帧),但抓包底层的物理传输却显示出30 FPS的时间特征。
这说明摄像头硬件底层的出图帧率是 30fps,或者编码器(mpph264enc)并没有严格按照 15fps 进行抽帧,而是以 30fps 的节奏在吐出数据。如果在工业识别中算法吃不消,这是一个极其重要的性能优化排查点。根本原因是RK3588搭配的MIPI 摄像头 IMX 415无法修改参数。
视频大多是由1514 bytes 和 1400 bytes发送的,明显小于的是画面帧末尾。这里可以计算输出一帧画面是11帧TCP通信,下图是两帧画面的TCP通信。
就第10个frame而言,数据是578字节,点开查看发现PSH=1,说明该帧画面发送结束。
第一帧画面,就Frame 2 数据包头 = 1458(length)- 1400 (实际数据)- 4(RTSP包头)= 54字节
Frame 3 的ACK包 length 就可以佐证这一点。

54字节 内容如下:
-
14字节:Ethernet II, Src: HP_70:fd:23 (e0:73:e7:70:fd:23), Dst: e6:f5:93:40:e2:02 (e6:f5:93:40:e2:02)
-
20字节:I nternet P rotocol V ersion 4, Src: 192.168.137.1, Dst: 192.168.137.10
-
20字节:T ransmission C ontrol Protocol, Src Port: 7826, Dst Port: 8554, Seq: 1, Ack: 1423, Len: 0
这一帧的画面真正数据大小是9025 - 1 (seq = 1) = 9024字节。
数据大小是72 + 1458 + 1514 + 1402 + 1514 + 1514 + 1514 + 468 + 54*3 = 9618字节

如何判断帧的属性,是I帧 P帧 还是B帧。
首先需要重新抓包,先断开gst - launch指令,重新抓包,键入指令,同时vlc播放器拉流。右键列表,decode as ,进入选择h264。



马上就看到了变化。
FU-A Start: non-IDR-Slice 指的是P帧
FU-A Start: IDR-Slice 指的是关键帧I帧,可以看得出来I帧的数据比P帧大了很多倍
Mark FU-A End指的是一帧画面传输的结束
|-------------------|----------------------------------------------------------|
| nal_unit_type | NAL 单元和 RBSP 语法结构的内容 |
| 0 | 未指定 |
| 1 | 一个非IDR图像的编码条带 slice_layer_without_partitioning_rbsp( ) |
| 2 | 编码条带数据分割块A slice_data_partition_a_layer_rbsp( ) |
| 3 | 编码条带数据分割块B slice_data_partition_b_layer_rbsp( ) |
| 4 | 编码条带数据分割块C slice_data_partition_c_layer_rbsp( ) |
| 5 | IDR图像的编码条带 slice_layer_without_partitioning_rbsp( ) |
| 6 | 辅助增强信息 (SEI) sei_rbsp( ) |
| 7 | 序列参数集 seq_parameter_set_rbsp( ) |
| 8 | 图像参数集 pic_parameter_set_rbsp( ) |
| 9 | 访问单元分隔符 access_unit_delimiter_rbsp( ) |
| 10 | 序列结尾 end_of_seq_rbsp( ) |
| 11 | 流结尾 end_of_stream_rbsp( ) |
| 12 | 填充数据 filler_data_rbsp( ) |
| 13 | 序列参数集扩展 seq_parameter_set_extension_rbsp( ) |
| 14...18 | 保留 |
| 19 | 未分割的辅助编码图像的编码条带 slice_layer_without_partitioning_rbsp( ) |
| 20...23 | 保留 |
| 24...31 | 未指定 |
过滤栏使用这个指令可以快速查看 I P帧的比例,这里我的结果是1:14,每15帧一张I帧,可以下降到一秒一张I帧,在推流的时候设置gop = 30 和摄像头帧率一样即可。
((h264.nal_unit_type == 5) || (h264.nal_unit_type == 1) ) && (h264.start.bit == True)
