Python UDP Socket接收未知格式数据(二进制/十六进制)如何读取?
如何解析UDP Socket收到的二进制数据?
看起来你收到的是二进制格式的数据,不是普通的文本字符串,所以直接print会出现一堆乱码(那些???、��都是无法转成ASCII/UTF-8的字节)。咱们一步步来解决这个问题:
第一步:先看数据的「真面目」
别直接把二进制数据当字符串打印,先转成十六进制格式,这样能看到每个字节的真实值,完全避免乱码干扰。修改你的代码:
while True: data, addr = sock.recvfrom(1024) print("Raw hex data:", data.hex()) # 也可以按字节拆分看,更清晰: print("Byte breakdown:", [hex(b) for b in data])
这样你就能看到类似eb200318151c000000...的完整十六进制序列,那些之前乱码的部分也会变成明确的字节值,方便后续分析。
第二步:搞清楚数据的协议格式
这种UDP传来的二进制数据,基本都是自定义二进制协议(常见于工控设备、传感器、嵌入式设备),或者是某种标准协议(比如Modbus UDP、SNMP)。你需要:
- 优先找发送端的设备/程序文档:里面会明确告诉你每个字节代表什么(比如帧头、设备ID、时间戳、传感器数值、校验位等)。比如你看到的
EB可能是帧头标识,200318可能是BCD格式的日期(2020年3月18日),151C是时间(15点28分),后面的字节可能是具体的测量值。 - 如果没有文档,就多抓几组数据对比:比如改变发送端的状态(比如调整传感器数值),看哪几个字节跟着变化,以此推断字段的含义和长度。
第三步:用Python解析二进制数据
当你搞清楚协议格式后,用Python的struct模块来解析是最方便的——它专门用来处理C语言风格的二进制数据。举个简单例子:
假设你分析出协议是:
- 1字节帧头(比如
0xEB) - 3字节BCD格式日期(年、月、日)
- 2字节BCD格式时间(时、分)
- 4字节无符号整数(传感器数值)
那解析代码可以写成:
import struct # 假设data是你收到的二进制数据 frame_header, year, month, day, hour_min, sensor_value = struct.unpack('B3BH I', data[:10]) # 把BCD格式的时间转成十进制 hour = (hour_min >> 4) & 0x0F minute = hour_min & 0x0F print(f"日期:20{year:02d}年{month:02d}月{day:02d}日") print(f"时间:{hour:02d}:{minute:02d}") print(f"传感器值:{sensor_value}")
注意struct.unpack的格式符要和协议完全匹配(比如B是无符号字节,H是无符号短整数,I是无符号整数),具体可以查Python官方的struct文档。
如果是标准协议(比如Modbus),那直接用现成的库(比如pymodbus)会更省心,不用自己写解析逻辑。
内容的提问来源于stack exchange,提问作者eso
相关产品推荐
相关产品推荐

