python - 在 Python 中序列化 C 结构并通过套接字发送

标签 python c sockets serialization ctypes

我正在尝试序列化以下 C 结构

struct packet
{
    int id;
    unsigned char *ce;
    unsigned char *syms;
};

在 Python 中并通过套接字发送它。 cesyms 指向的元素数量已知为N。目前我正在这样做。首先,我使用 ctypes 将结构包装到

class Packet(Structure):
    _fields_ = [("id",  c_int),
                ("ce", POINTER(c_ubyte)),
                ("syms", POINTER(c_ubyte))]

然后,我使用 ctypes.POINTER(Packet) 中的 fill_data 函数填充以下类的对象:

class DataLoad:
    def __init__(self):
        self.id = -1
        self.ce = []
        self.syms = []

    def fill_data(self, pkt_p):
        """ pkt_p is POINTER(Packet)
        """
        self.id = pkt_p.contents.id
        self.ce = []
        for i in range(N):
            self.ce.append(pkt_p.contents.ce[i])
        self.syms = []
        for i in range(N):
            self.syms.append(pkt_p.contents.syms[i])

最后,我简单地使用pickle.dumps(DataLoad)生成字节流并发送。

这种方法效果很好。但是,它似乎很慢。我能看到的一个原因是 pickle.dumps 带来了很多开销。例如,如果 C 结构只有 1024 个字节,我可能必须使用 pickle 为每个结构发送近 4000 个字节。此外,打包/填充 DataLoad 也需要时间。

所以我的问题是,我是否有其他更好的选择来在 python 中序列化此 C 结构并发送?我宁愿避免 pickle 并填充一个单独的类实例。谢谢。

最佳答案

最后我想出了下面的方法来手动序列化 `Packet' 实例而不使用 pickle。

def serialize(pkt_p, size_g, size_p):
    """ Serialize Packet instance
        size_g - number of elements pointed by ce
        size_p - number of elements pointed by syms
        Return a byte stream
    """ 
    pktstr = b''
    pktstr += struct.pack('i', pkt_p.contents.id)
    pktstr += string_at(pkt_p.contents.ce, size_g)
    pktstr += string_at(pkt_p.contents.syms, size_p)
    return pktstr

def deserialize(pkt_p, pktstr, size_g, size_p):
    """ De-serialize pktstr and fill a POINTER(Packet)
    """
    pkt_p.contents.id = struct.unpack('i', pktstr[0:4])[0]
    ce = (c_ubyte * size_g).from_buffer_copy(pktstr[4:4+size_g])
    pkt_p.contents.ce = cast(ce, POINTER(c_ubyte))
    syms = (c_ubyte * size_p).from_buffer_copy(pktstr[-size_p:])
    pkt_p.contents.syms = cast(syms, POINTER(c_ubyte))

string_at()from_buffer_copy() 函数是关键。

关于python - 在 Python 中序列化 C 结构并通过套接字发送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34533409/

相关文章:

python - 发送附件 'file'时Django 1.5错误对象没有属性 '__getitem__'

python - 使用unittest时不理解python中的作用域

c - 从float转换为double会产生不同的结果-相同的代码,相同的编译器,相同的OS

java - 从服务器向所有客户端发送消息

ios - 按时从 GCDAsyncSocket 读取响应(iOS)

python - 多处理远程服务器和套接字错误

python - 在python中匹配两个列表

c - 从specman执行perl

c - GDB:有没有一个命令可以让你看到一个函数被调用了多少次?

python - 从 pandas 数据帧着色时间序列数据