如何在Python 3.2中解包C结构体?

0 投票
2 回答
2161 浏览
提问于 2025-04-17 13:38

我正在开发一个应用程序,服务器用Python写,客户端用C语言写。

我想在服务器端(Python)使用struct模块来解析从C客户端收到的原始字节。

这是我在C客户端定义的结构:

typedef struct lokesh{
    int command;

     union 
     {
        struct{
            int data[100];
            int ttl[100];
        };

        struct{
            char config[256];

        };   
     };
} mystructdata;

在服务器端(Python)解析的代码是:

import struct

data,address=socket.recvfrom(1024)
result=struct.unpack('<i 2048s',data)
print(result[0])

但是我遇到了一个错误:

struct.error: unpack require object of size 2052  

我觉得问题出在我解析方法的格式字符串'<i 2048s'这个参数上。

编辑:

现在,我把格式字符串'<i 2048s'换成了'<i 256s'

2 个回答

2

这里有两个问题:

  • .recvfrom() 这个方法会返回一个包含 (数据, 地址) 的元组,你只需要把数据部分传给 struct.unpack()

  • 你从套接字中读取的最多是1024个字节,但解包的格式需要2052个字节。你需要先从套接字中读取足够的数据。

2

Lokesh,我不是Python专家,但我觉得你在告诉Python的struct模块,你有:

  • 一个小端整数,后面跟着
  • 2048个字符数组

(这基于http://docs.python.org/2/library/struct.html#format-characters

但是,看你的C语言结构定义,其实并不是这样。你有:

  • 一个整数,后面跟着其中之一:
    • 两个各有100个元素的整数数组
    • 一个有256个元素的字符数组

现在,不看把结构体发送出去的C代码,很难知道整数的字节顺序(网络字节顺序是大端)。不过,抛开这个不谈,你给struct的数据显示是错误的。

我猜测C结构体中的联合体的解释会依赖于command的内容。因此,似乎你需要先检查command,然后根据它来制定一个合适的struct格式字符串。需要注意的是,在数据/ttl的情况下,你可能会遇到结构体填充的问题,因为客户端的编译器可能会在datattl数组之间插入一些填充,以满足对齐要求等等。

撰写回答