如何使用Python优雅地发送/接收大型C结构?[英] How to elegantly send/receive a large C struct using Python?

本文是小编为大家收集整理的关于如何使用Python优雅地发送/接收大型C结构?的处理方法,想解了如何使用Python优雅地发送/接收大型C结构?的问题怎么解决?如何使用Python优雅地发送/接收大型C结构?问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

我已经开始编写Python 3.x客户端应用程序.服务器应用程序已经存在并写在C中.服务器提供了一个C标头文件,其定义用于通过UDP发送和接收数据的两个结构(我正在使用Python's socket模块). 问题是C结构很大(每个元素约为200个).如果我使用python的struct模块打包/解开数据,则不太重要的解决方案将手动打包/解开200个元素,例如:

struct.pack('H...I', data1, ..., data200)

此外,我希望能够使用类似C的语法访问Python中的接收/发送元素.例如,如果我在C服务器端

send.data.pos = pos;

如果我可以在Python客户端访问pos变量,那将是不错的(最自然的):

pos = recv.data.pos

请注意,问题是不是如何从标题文件中自动编写python的结构,例如 this 线程(我在python中逐一编写一个结构字段没有问题),而是在Python中组织数据的最佳方法(例如,在课堂中,使用字典等)将使我能够利用Python功能并使代码更简单,并且易于访问的数据(我宁愿仅使用Python标准模块,而没有外部软件).实现这一目标的最优雅方法是什么?

推荐答案

尝试一下 - 在2.7和3.2上工作.

脚本:

import struct, collections

class CStruct(object):

    def __init__(self, typename, format_defn, lead_char="!"):
        self.names = []
        fmts = [lead_char]
        for line in format_defn.splitlines():
            name, fmt = line.split()
            self.names.append(name)
            fmts.append(fmt)
        self.formatstr = ''.join(fmts)
        self.struct = struct.Struct(self.formatstr)
        self.named_tuple_class= collections.namedtuple(typename, self.names)

    def object_from_bytes(self, byte_str):
        atuple = self.struct.unpack(byte_str)
        return self.named_tuple_class._make(atuple)

if __name__ == "__main__":
    # do this once
    pkt_def = """\
        u1 B
        u2 H
        u4 I"""
    cs = CStruct("Packet1", pkt_def)
    # do this once per incoming packet
    o = cs.object_from_bytes(b"\xF1\x00\xF2\x00\x00\x00\xF4")
    print(o)
    print(o.u4)

输出:

Packet1(u1=241, u2=242, u4=244)
244

其他推荐答案

您可以编写具有成员函数的类,可以使用struct.pack等.

我建议您研究 struction .但是我认为它还没有移植到python 3.x.构造已经停滞了一段时间,但是最近被新开发人员接收,因此也许很快就可以支持Python 3.x.

其他推荐答案

您也许可以使用 dpkt 作为一种简单的访问方式数据包数据.看看在这里用于使用示例.对于一个简单的示例:

class Foo(dpkt.Packet):
    __hdr__ = (('type', 'B', 0),
               ('size', 'B', 0))

data = get_udp_message()
foo = Foo(data)
if foo.size != len(data):
    print "Bad size in header"
if foo.type == 3:
    parse_payload(foo.data)

本文地址:https://www.itbaoku.cn/post/359427.html