如何使用Python结合Sniff获取WiFi的SNR(信噪比)?
解决方法
0bda:b711(RTL8188CUS)这类低成本USB网卡的硬件或驱动通常不支持暴露噪声数据,所以scapy无法获取dBm_AntNoise值。以下是几种可行的替代方案:
1. 用经验值估算近似SNR
如果能正常获取信号强度(pkg.dBm_AntSignal),可以基于室内WiFi环境的典型噪声值估算SNR。一般室内背景噪声大致在-95~-100dBm之间,可根据实际环境调整经验值:
from scapy.all import sniff from scapy.layers.dot11 import Dot11 def callBack(pkg): if hasattr(pkg, 'dBm_AntSignal') and pkg.dBm_AntSignal is not None: estimated_noise = -98 # 可根据实际环境微调 snr = pkg.dBm_AntSignal - estimated_noise print(f"信号强度: {pkg.dBm_AntSignal} dBm, 估算SNR: {snr} dB") print("-----------------") sniff(iface='wlp1s1', prn=callBack)
2. 调用系统iw工具解析噪声数据
Linux下的iw工具能直接从网卡驱动读取底层信息,部分网卡即使scapy拿不到噪声,iw也能输出有效数据。用Python的subprocess调用命令并解析结果:
import subprocess import re import time def get_wifi_snr(iface): # 执行iw命令获取survey数据 result = subprocess.run(['iw', 'dev', iface, 'survey', 'dump'], capture_output=True, text=True) output = result.stdout # 匹配信号和噪声值 pattern = re.compile(r'signal: (-?\d+) dBm.*noise: (-?\d+) dBm', re.DOTALL) matches = pattern.findall(output) if matches: signal, noise = map(int, matches[-1]) snr = signal - noise return signal, noise, snr return None, None, None if __name__ == '__main__': while True: signal, noise, snr = get_wifi_snr('wlp1s1') if snr is not None: print(f"信号强度: {signal} dBm, 噪声: {noise} dBm, SNR: {snr} dB") else: print("无法获取噪声数据") time.sleep(1)
如果iw survey dump无噪声输出,可尝试iw dev <iface> station dump(针对已连接的AP),解析对应AP的signal和noise字段。
3. 更换支持噪声捕获的网卡
RTL8188CUS芯片的驱动对噪声数据的支持有限,若需要精准的噪声值,可更换为Intel AX200/AX210、Atheros AR9271这类驱动完善、支持完整802.11监控数据的网卡,更换后scapy的pkg.dBm_AntNoise即可正常返回数值。
内容的提问来源于stack exchange,提问作者chowhao
相关产品推荐
相关产品推荐

