[英]Problem with receiving ctypes `c_wchar_p` over python socket (python 3.7.7)
(Windows 10, x64, PyCharm) (Windows 10、x64、PyCharm)
short story: I have a problem with payload_in.event
and payload_out.event
in the python server script.短篇小说:我在 python 服务器脚本中的
payload_in.event
和payload_out.event
有问题。 Both are from type c_wchar_p
which is from ctypes
.两者都来自
ctypes
的c_wchar_p
类型。
long story: I am working on a client and a server in python currently.长话短说:我目前正在 python 的客户端和服务器上工作。 They communicate over TCP/IP sockets on 127.0.01:6666.
它们通过 TCP/IP sockets 在 127.0.01:6666 上进行通信。 I am using the module Ctypes to send and receive a c-like struct.
我正在使用模块 Ctypes 来发送和接收类似 c 的结构。 Everything works perfectly, I can send/recv arrays, integers, floats and work with them on both sides but I found out that there is a bug when printing
payload_in.event
and payload_out.event
in the python server script, both of type c_wchar_p
.一切正常,我可以发送/接收 arrays、整数、浮点数并在两侧使用它们,但我发现在 python 服务器脚本中打印
payload_in.event
和payload_out.event
时存在错误,两者都是c_wchar_p
类型。
In the client script, I can access and print payload_in.event
and payload_out.event
perfectly ***but my server script can not even though the code is the same.在客户端脚本中,我可以完美地访问和打印
payload_in.event
和payload_out.event
***但我的服务器脚本不能,即使代码相同。 . . .
.
In the server script, printing payload_in.event
and payload_out.event
causes both programs to pause for 10 seconds or so and then the client console tells me that the connection to the server was closed.在服务器脚本中,打印
payload_in.event
和payload_out.event
会导致两个程序暂停 10 秒左右,然后客户端控制台告诉我与服务器的连接已关闭。
Everything works fine if I comment out the printing of payload_in.event
and payload_out.event
in the python server script.如果我在 python 服务器脚本中注释掉
payload_in.event
和payload_out.event
的打印,一切正常。 I don't know how to fix this behaviour and would be glad if someone could help me out.我不知道如何解决这种行为,如果有人可以帮助我,我会很高兴。
beagleServer.py比格服务器.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 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
is a pointer. Struct.event
是一个指针。 A pointer transmitted between two processes is just an address that has no meaning in the other process.在两个进程之间传输的指针只是一个地址,在另一个进程中没有任何意义。 Use an array instead:
改用数组:
("event", c_wchar * 80)
It can still be initialized the same way, but you can't exceed the array size for the string transmitted.它仍然可以以相同的方式初始化,但不能超过传输字符串的数组大小。 Also
c_wchar
size varies between architectures, so you may want to use c_char * 80
instead, and then encode/decode the string, eg payload.event = 'some string'.encode()
(or just use a byte string: b'some string'
). c_wchar
大小也因架构而异,因此您可能希望使用c_char * 80
代替,然后对字符串进行编码/解码,例如payload.event = 'some string'.encode()
(或仅使用字节字符串: b'some string'
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.