如何通过USB将Nexus 5的Nexmon CSI实时捕获数据传输至PC?
背景
我正在开展基于手机捕获Wi-Fi信道状态信息(CSI)的手势识别项目,需将Nexus 5设备上通过Nexmon CSI获取的实时网络捕获数据,经USB连接传输至PC。目前我使用tcpdump将捕获数据保存到手机本地文件(非实时),再通过csireadPython包提取CSI幅度和相位信息到Numpy中,用Matplotlib可视化,命令如下:
adb shell "su -c 'tcpdump -i wlan0 -v dst port 5500 -c 50 -w /sdcard/capture.pcap'"
注:Wireshark可正常读取该命令生成的Nexmon捕获文件。
可正常运行的操作
- 本地tcpdump实时流管道至Wireshark:
# '-w -' 将捕获内容写入标准输出 sudo tcpdump -i any -w - | wireshark -k -i -
- 通过ADB在手机上捕获并保存到本地,再pull至PC:
adb shell "su -c 'tcpdump -i wlan0 -vv dst port 5500 -w /sdcard/capture.pcap -c 50'" adb pull /sdcard/capture.pcap ~/Desktop/capture.pcap
生成的文件可被Wireshark和csiread正常读取。
失败的实时传输尝试
参考SSH服务器实时tcpdump流教程,尝试以下命令均失败:
- 尝试将手机tcpdump实时捕获管道至Wireshark:
adb shell "su -c 'tcpdump -i wlan0 -v dst port 5500 -w -'" | wireshark -k -i -
报错:
Unrecognized libpcap format or not libpcap data.
- 尝试将实时流直接写入PC本地文件:
adb shell "su -c 'tcpdump -i wlan0 -v dst port 5500 -c 2 -w -'" > ~/Desktop/adb_direct_capture.pcap
生成的文件无法被Wireshark和csiread读取。
查阅Nexmon CSI官方文档未找到相关解决方案。
排查结果
通过ADB管道传输的数据包含tcpdump的常规输出(如tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes),即使移除这些行,生成的文件仍无效,报错如Not a pcap capture file (bad magic: b'\xef\xbf\xbd\xc3')。用十六进制编辑器对比有效与无效文件,发现有效文件长度更短,推测ADB传输过程中标准输出的二进制数据出现编码或传输混乱。
解决办法
- 禁用tcpdump的冗余输出:在tcpdump命令中添加
-q(安静模式,抑制状态信息输出)和-l(行缓冲,确保实时输出)参数,避免额外文本干扰二进制流:
adb shell "su -c 'tcpdump -i wlan0 -q -l -v dst port 5500 -w -'" | wireshark -k -i -
- 使用ADB的原始二进制传输模式:
adb shell会将标准输出当作文本处理,导致二进制pcap数据损坏。改用adb exec-out命令,它会直接传输原始二进制数据,这是解决问题的核心:
adb exec-out "su -c 'tcpdump -i wlan0 -q -l -v dst port 5500 -w -'" | wireshark -k -i -
若要将实时流保存到PC本地文件,同样使用
exec-out:
adb exec-out "su -c 'tcpdump -i wlan0 -q -l -v dst port 5500 -c 50 -w -'" > ~/Desktop/real_time_capture.pcap
- 验证文件有效性:传输完成后,可使用
capinfos工具检查pcap文件的格式信息,确认数据完整:
capinfos ~/Desktop/real_time_capture.pcap
内容的提问来源于stack exchange,提问作者Ashkan Arabi

