【问题标题】:Reading a C-struct via sockets into python通过套接字将 C-struct 读入 python
【发布时间】:2018-07-27 02:42:57
【问题描述】:

在运行 C 应用程序的嵌入式设备上,我定义了这个结构:

struct TestStruct
{
    float first;
    int second;
    char third;
};

根据要求,我通过套接字发送此结构:

else if(strcmp(str, "Get Stru") == 0)
{
    TestStruct testStruct;
    testStruct.first = 1.2;
    testStruct.second = 42;
    testStruct.third = 'A';

    INT32 sendDataLength = send(m_Socket, (char *)(&testStruct), sizeof(testStruct), 0);
}

并从我桌面上的 Python 脚本中读取它:

import struct
import socket  
from ctypes import *

class YourStruct(Structure):
    _fields_ = [('v', c_float),
                ('t', c_int),
                ('c', c_char)]

s = socket.socket()
host = '127.0.0.1'
port = 1234

s.connect((host, port))

s.send('Get Stru'.encode())
data = s.recv(20)
print(data)

x = YourStruct()

这是打印到我桌面上控制台的数据:

如何将data 重新组装成YourStruct

请注意,嵌入式设备使用小端序,因此我不得不使用struct.unpack("<" + "f" * 2048, data) 重新组装浮点数组。

【问题讨论】:

    标签: python c struct


    【解决方案1】:

    [Python.Docs]: struct - Interpret bytes as packed binary data 包含所有需要的情报。

    code00.py

    #!/usr/bin/env python
    
    import sys
    import ctypes
    import struct
    
    
    class YourStruct(ctypes.Structure):
        _fields_ = [
            ("v", ctypes.c_float),
            ("t", ctypes.c_int),
            ("c", ctypes.c_char),
        ]
    
    
    def main(*argv):
        data = b"\x9a\x99\x99?*\x00\x00\x00A\xbe\xad\xde"
        x = YourStruct()
        fmt = "<fic"
        fmt_size = struct.calcsize(fmt)
        x.v, x.t, x.c = struct.unpack(fmt, data[:fmt_size])
        print("Fields\n  v: {:f}\n  t: {:d}\n  c: {:s}".format(x.v, x.t, x.c.decode()))
    
    
    if __name__ == "__main__":
        print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
        main(*sys.argv[1:])
        print("\nDone.")
    

    注意事项

    • 从从套接字接收数据 (data) 的点开始
    • 传递给 struct.unpack (fmt arg) 的格式告诉它数据是如何组织的:在我们的例子中是"&lt;fic" : float, int, char (前面是 little endian 标记)
    • 还计算格式所需的数据大小(以字节为单位):它是 9 (4 + 4 + 1)。 data 有 12 个字节,所以忽略最后 3 个字节,否则 struct.unpack 会吐出 struct.error
    • 查看[SO]: Python struct.pack() behavior 了解有关 struct.pack 的更多详细信息

    输出

    [cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q048822543]> "e:\Work\Dev\VEnvs\py_pc064_03.07.09_test0\Scripts\python.exe" code00.py
    Python 3.7.9 (tags/v3.7.9:13c94747c7, Aug 17 2020, 18:58:18) [MSC v.1900 64 bit (AMD64)] 64bit on win32
    
    Fields
      v: 1.200000
      t: 42
      c: A
    
    Done.
    

    【讨论】:

    • 太棒了。但是当我使用struct.decode() 解码我收到的数据时:b'\x00\x01\x00\x00\x00\x02\x00\x00\x07\xd0\x00\x00',python 无法将其解码为 (1,2,2000)。有什么猜测吗?我还用fmt = "iii" 交换了"&lt;fic" `
    • @PeDro:在这种情况下,您需要struct.unpack_from("&gt;HII", b)(请注意,最右边的 2 个字节将被忽略)。
    猜你喜欢
    • 1970-01-01
    • 2017-08-26
    • 2018-06-04
    • 2023-03-02
    • 1970-01-01
    • 2017-07-22
    • 1970-01-01
    • 2021-06-24
    • 2016-12-10
    相关资源
    最近更新 更多