簡體   English   中英

如何使用Python優雅地發送/接收大型C結構?

[英]How to elegantly send/receive a large C struct using Python?

我已經開始編寫Python 3.x客戶端應用程序了。 服務器應用程序已經存在並且用C語言編寫。服務器提供了一個C頭文件,其中包含用於通過UDP發送和接收數據的兩種結構的定義(我正在使用Python的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結構,就像在這個線程中一樣(我在Python中逐個編寫每個結構字段都沒有問題),而是最好的組織方式Python中的數據(例如,在類中,使用字典等),這將允許我利用Python功能,使代碼更簡單,數據易於訪問(我寧願只使用Python標准模塊,也不使用外部軟件)。 實現這一目標最優雅的方法是什么?

您可以編寫一個具有成員函數的類,使用struct.pack等將數據打包/解包到類屬性中。

我建議看看Construct 但我認為它還沒有被移植到Python 3.x. 構造已經中斷了一段時間,但最近被新開發人員接受了,所以也許很快就可以支持Python 3.x.

試試這個 - 適用於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

您可以使用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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM