通过 python 套接字接收 ctypes `c_wchar_p` 时出现问题 (python 3.7.7)

Problem with receiving ctypes `c_wchar_p` over python socket (python 3.7.7)

(Windows 10, x64, PyCharm)

简短的故事:python 服务器脚本中的 payload_in.eventpayload_out.event 有问题。两者都来自 c_wchar_p 类型,后者来自 ctypes.

长话短说: 我目前正在 python 中的客户端和服务器上工作。他们通过 127.0.01:6666 上的 TCP/IP 套接字进行通信。我正在使用模块 Ctypes 来发送和接收类似 C 的结构。一切正常,我可以 send/recv 数组、整数、浮点数并在两侧使用它们,但我发现在 [=52] 中打印 payload_in.eventpayload_out.event 时存在错误=] 服务器脚本,都是 c_wchar_p.

类型

在客户端脚本中,我可以完美地访问和打印 payload_in.eventpayload_out.event ***但是我的服务器脚本不能,即使代码是相同的。 . .

在服务器脚本中,打印 payload_in.eventpayload_out.event 导致两个程序暂停 10 秒左右,然后客户端控制台告诉我与服务器的连接已关闭。

如果我在 python 服务器脚本中注释掉 payload_in.eventpayload_out.event 的打印,一切正常。我不知道如何解决此问题,如果有人能帮助我,我会很高兴。

beagleServer.py

import socket
from ctypes import *


class Struct(Structure):
    _fields_ = [("id", c_uint32),  # 4B
                ("prio", c_uint32),  # 4B
                ("event", c_wchar_p),  # 8B
                ("data", c_float * 10)]  # 40B


def main():
    BUFFSIZE = sizeof(Struct)
    host = '127.0.0.1'
    port = 6666

    beagleServer = socket.socket()
    beagleServer.bind((host, port))
    beagleServer.listen(1)

    print("Server is listening on " + host + ":" + str(port) + "!")
    client, clientAddress = beagleServer.accept()
    print("Connection from: " + str(clientAddress[0]) + ":" + str(clientAddress[1]))

    # receiving payload
    buffer = client.recv(BUFFSIZE)
    payload_in = Struct.from_buffer_copy(buffer)
    print("\nPayload of ", sizeof(payload_in), " Bytes has been received successfully: ", payload_in,
          "\nPayload.id: ", payload_in.id,
          "\nPayload.prio: ", payload_in.prio,
          "\nPayload.event: ", payload_in.event,
          "\nPayload.data: ", list(payload_in.data),
          "\nReceived buffer: ", buffer)

    # sending back payload
    payload_out = payload_in
    transferredBytes = client.send(payload_out)
    print("\nPayload of ", transferredBytes, " Bytes has been sent successfully: ", payload_out,
          "\nPayload.id: ", payload_out.id,
          "\nPayload.prio: ", payload_out.prio,
          "\nPayload.event: ", payload_out.event,
          "\nPayload.data: ", list(payload_out.data))

    print("Closing server socket!")
    client.close()

if __name__ == '__main__':
    main()

beagleClient.py

import socket
from ctypes import *


class Struct(Structure):
    _fields_ = [("id", c_uint32),  # 4B
                ("prio", c_uint32),  # 4B
                ("event", c_wchar_p),  # 8B
                ("data", c_float * 10)]  # 40B


beagleServer = ('127.0.0.1', 6666)
beagleClient = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
beagleClient.connect(beagleServer)
print("Connection with server has been established!")

# Creating the Struct
payload_out = Struct(390897,
                     0,
                     "activateMode1",
                     (3.12, 4.21, 1.23))
print("\nPayload of ", sizeof(payload_out), " Bytes has been created successfully: ", payload_out,
      "\nPayload.id: ", payload_out.id,
      "\nPayload.prio: ", payload_out.prio,
      "\nPayload.event: ", payload_out.event,
      "\nPayload.data: ", list(payload_out.data))

# Sending
bytesTransferred = beagleClient.send(payload_out)
print("\nPayload of ", bytesTransferred, " Bytes has been sent!")

# Receiving
BUFFSIZE = sizeof(Struct)
buffer = beagleClient.recv(BUFFSIZE)
payload_in = Struct.from_buffer_copy(buffer)
print("\nPayload of ", sizeof(payload_in), " Bytes has been received successfully: ", payload_in,
      "\nPayload.id: ", payload_in.id,
      "\nPayload.prio: ", payload_in.prio,
      "\nPayload.event: ", payload_in.event,
      "\nPayload.data: ", list(payload_in.data))

print("Closing the connection to ", beagleServer, "!")
beagleClient.close()

Struct.event 是一个指针。两个进程之间传输的指针只是一个地址,在另一个进程中没有任何意义。改用数组:

("event", c_wchar * 80)

仍然可以用同样的方式初始化,但是不能超过传输字符串的数组大小。此外 c_wchar 大小因体系结构而异,因此您可能希望改用 c_char * 80,然后 encode/decode 字符串,例如payload.event = 'some string'.encode()(或者只使用一个字节串:b'some string')。