Python 序列化ctype并集
有没有办法序列化ctype联合,以便通过套接字发送它们?我试图通过套接字将union发送到网络服务器,但无法序列化数据,而是将其作为union对象的实例发送。是否可以使用Python Struct()库来实现这一点(我认为它不支持联合)?非常感谢您的帮助 如果在Python 序列化ctype并集,python,networking,serialization,union,ctypes,Python,Networking,Serialization,Union,Ctypes,有没有办法序列化ctype联合,以便通过套接字发送它们?我试图通过套接字将union发送到网络服务器,但无法序列化数据,而是将其作为union对象的实例发送。是否可以使用Python Struct()库来实现这一点(我认为它不支持联合)?非常感谢您的帮助 如果在ctypes.Structure或ctypes.Union上调用bytes(),将获得可通过套接字传输的底层字节字符串。收到后,将该字节字符串复制回原始对象 下面是一个独立的示例。套接字服务器作为线程启动,并将向客户端发送两个对象。然后,
ctypes.Structure
或ctypes.Union
上调用bytes()
,将获得可通过套接字传输的底层字节字符串。收到后,将该字节字符串复制回原始对象
下面是一个独立的示例。套接字服务器作为线程启动,并将向客户端发送两个对象。然后,客户端接收对象并对其进行解释:
import ctypes
import socket
import threading
# Used to indicate what type of field is in the Union.
U32 = 1
DBL = 2
class MyUnion(ctypes.Union):
_fields_ = ('u32',ctypes.c_uint32),('dbl',ctypes.c_double)
class MyStruct(ctypes.Structure):
_pack_ = 1 # define before _fields_ to have an affect.
_fields_ = ('type',ctypes.c_int),('u',MyUnion)
def client():
s = socket.socket()
s.connect(('localhost',5000))
# Wrap the socket in a file-like object so an exact amount of bytes can be read.
r = s.makefile('rb')
# Read two structures from the socket.
ex1 = MyStruct.from_buffer_copy(r.read(ctypes.sizeof(MyStruct)))
ex2 = MyStruct.from_buffer_copy(r.read(ctypes.sizeof(MyStruct)))
s.close()
# display the correct Union field by type.
for ex in (ex1,ex2):
if ex.type == U32:
print(ex.u.u32)
else:
print(ex.u.dbl)
def server():
s = socket.socket()
s.bind(('',5000))
s.listen(1)
c,a = s.accept()
# Prepare two structures
ex1 = MyStruct()
ex1.type = DBL
ex1.u.dbl = 1.234
ex2 = MyStruct()
ex2.type = U32
ex2.u.u32 = 1234
# Send them as bytes
c.sendall(bytes(ex1))
c.sendall(bytes(ex2))
c.close()
s.close()
# spin off the server in a thread so the client can connect to it.
t = threading.Thread(target=server)
t.start()
client()
输出:
1.234
1234
但是,在序列化之前,我尝试在我的结构上调用sys.getsizeof(),返回96,而在对象的byte()序列化上调用sys.getsizeof()返回93。同样,在我的结构上调用getsizeof()返回144,因此是bytes()减少我的结构大小,因为我需要发送的内容准确无误96@John
ctypes.sizeof
notsys.getsizeof
。后者报告完整Python对象的总大小,而不仅仅是它所表示的C结构。@John对于字节字符串结果,请使用len()
@John您的结构未显示,但您可能还需要处理打包对齐。例如,在我的c_uint32
(4字节)和c_double
(8字节)结构中,默认值是在参数之间添加4字节的填充,因此c_double
是8字节对齐的,总大小是16。您可以通过定义\u pack\u=1
将总大小设置为12来避免这种情况。我将把它添加到上面的示例中。