Если вы вызовете bytes()
на вашем ctypes.Structure
или ctypes.Union
, вы получите строку байтов, которая может быть передана через сокет. При получении скопируйте эту байтовую строку обратно в исходный объект.
Вот отдельный пример. Сервер сокетов запускается как поток и отправляет два объекта клиенту. Затем клиент получает объект и интерпретирует его:
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