UDP接收32位无符号整数写入CSV遇字节拆分与端序问题求助
解决UDP接收32位无符号整数的CSV输出与大小端问题
我来帮你搞定这两个问题——让Python正确解析FPGA发送的32位无符号整数,同时处理大小端差异:
问题根源分析
- 8位数据输出问题:你当前的代码直接把UDP收到的字节串
data传给csv_writer.writerow(),而writerow()会把字节串的每个单独字节作为CSV的一列写入,所以一个4字节的32位整数会被拆成4个0-255的8位值,就出现了你看到的0,0,0,4这种输出。 - 大小端问题:FPGA通过
XIo_In32读取的32位值,其内存字节序和Python主机的字节序可能不一致,需要明确指定解析时的字节序来完成转换。
解决方案:使用struct模块解析字节数据
Python的struct模块可以完美处理二进制数据的解析,我们用它把4字节的块转换成对应的32位无符号整数,同时指定字节序解决大小端问题。
修改后的完整代码如下:
import socket import csv import struct import traceback # 假设你已经完成了socket的初始化(示例配置) # s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # s.bind(('0.0.0.0', 1234)) # s.settimeout(5) # buf = 4096 # 建议设置为4的倍数,适配32位整数的字节长度 with open(csvf, 'w', newline='', encoding='ascii') as csv_handle: csv_writer = csv.writer(csv_handle, delimiter=',') while True: try: data, addr = s.recvfrom(buf) # 检查数据长度是否为4的倍数,避免解析不完整的数据包 if len(data) % 4 != 0: print(f"Warning: Received {len(data)} bytes (not multiple of 4), skipping this packet") continue # 解析字节串为32位无符号整数列表 # 格式符说明: # >I 表示大端字节序(高位字节在前),对应你示例中的数据格式;如果是小端则改成 <I # len(data)//4 自动计算要解析的整数个数 u32_values = struct.unpack(f'>{len(data)//4}I', data) # 写入CSV,此时是完整的32位整数列表 csv_writer.writerow(u32_values) except (socket.timeout, KeyboardInterrupt, SystemExit): raise except Exception: traceback.print_exc()
关键细节说明
- 字节序选择:根据你提供的例子,收到的字节
0,0,0,4对应期望的整数4,这说明FPGA发送的是大端字节序(高位字节在前),所以用>I。如果后续发现解析结果不对(比如收到4,0,0,0对应整数4),就换成<I(小端字节序)。 - 数据包完整性检查:加入长度检查是为了避免网络丢包导致的不完整数据(比如只收到3字节),防止
struct.unpack抛出异常。 - 效率优化:
struct.unpack可以一次性解析整个数据包里的所有32位整数,比手动循环拆分字节块效率更高。
这样修改后,CSV文件里就会输出你期望的4,4,8,12,16这类32位整数了,同时也解决了大小端问题。
内容的提问来源于stack exchange,提问作者kvantum.nuly
相关产品推荐
相关产品推荐

