从 python 到 C 的固定长度套接字通信
Fixed Length Socket communication from python to C
正在更新我的应用程序,该应用程序使用套接字从 python 到 C 程序进行通信,以便在发送消息时使用固定长度 headers 作为协议。
作为我的 C 客户端代码的测试示例:
/*
Socket definition code put inside here
*/
char test2[] = "hello this is a test";
uint32_t test = sizeof(test2); //Get size of message and store in 32bit int
uint32_t test_conv = htonl(test); //Convert to network byte order
header = send(ConnectSocket, &test_conv, sizeof(uint32_t), 0); //Send size of message
body = send(ConnectSocket, test2, sizeof(test2), 0); //Send the actual message
这里是 python 服务器代码的摘录:
msg = clientsocket.recv(4)
msg_length = int.from_bytes(msg, sys.byteorder) //Get the header with the message length
msg_length = socket.ntohl(msg_length)
if len(msg) > 0:
print(f"This message length: {test} ")
msg = clientsocket.recv(msg_length) //Get the message
if len(msg)>0:
print(f'Message is: {msg.decode("utf-8")}')
Server.py 输出:
The message length: 21
Message is: hello this is a test
我省略了套接字 headers 和其他东西以及错误检查以在这个 post 中保存 space。
这是使用固定长度 headers 的安全方法吗?我预计不会有大量流量,我只会在每条消息中发送一两句话的信息。
我的最后一个问题是为什么在 C 中调用 send 时我要使用“&test_conv”作为消息参数。那不只是发送 test_conv 变量的地址值吗?我不需要发送实际消息,而不是地址吗?
感谢您的任何见解,如果我应该使用不同的实现,请提供任何资源链接。
你的解决方案依赖于一个固定大小的整数来宣布数字
以下消息中的字节数对我来说似乎是正确的。
请务必始终如一地使用 sizeof
and/or strlen()
您实际程序中的文本消息。
在您的示例中,传输 sizeof(text2)
字节包括
text2
末尾隐含 '[=13=]'
;然后 python 字符串
这是在接待处建造的,包含这个无用的(看不见的
但仍然存在)空字节作为最后一个字符。
关于send()
中的&test_conv
,你需要明白
此系统调用仅考虑字节序列。
它不知道这些字节包含一个整数。
这就是为什么您提供要发送的第一个字节的地址
(&test_conv
) 和要发送的字节数
(sizeof(uint32_t)
) 从这个地址开始。
接收方将获得完全相同的字节序列
将它们解释为 32 位整数的内存表示
(当然要考虑字节顺序)。
请注意 python 中的 struct
包可以帮助处理
具有整数和字节顺序的内存表示。
在我看来你应该使用网络字节顺序,而不是主机字节顺序。
- https://pythontic.com/modules/socket/byteordering-coversion-functions
- https://www.ibm.com/support/knowledgecenter/en/SSB27U_6.4.0/com.ibm.zvm.v640.kiml0/asonetw.htm
此外,我相信 send() 和 recv() 可以提前 return,无需传输所有请求的内容 - 这就是它们 return 长度的原因。通常他们会传输您的所有数据和 return 完整长度,但不保证他们会这样做。
对于python,我喜欢我的http://stromberg.dnsalias.org/~dstromberg/bufsock.html模块。它负责为您恢复。
对于 C,我认为人们几乎只对每个 send() 和 recv() 使用一个 while 循环。
正在更新我的应用程序,该应用程序使用套接字从 python 到 C 程序进行通信,以便在发送消息时使用固定长度 headers 作为协议。
作为我的 C 客户端代码的测试示例:
/*
Socket definition code put inside here
*/
char test2[] = "hello this is a test";
uint32_t test = sizeof(test2); //Get size of message and store in 32bit int
uint32_t test_conv = htonl(test); //Convert to network byte order
header = send(ConnectSocket, &test_conv, sizeof(uint32_t), 0); //Send size of message
body = send(ConnectSocket, test2, sizeof(test2), 0); //Send the actual message
这里是 python 服务器代码的摘录:
msg = clientsocket.recv(4)
msg_length = int.from_bytes(msg, sys.byteorder) //Get the header with the message length
msg_length = socket.ntohl(msg_length)
if len(msg) > 0:
print(f"This message length: {test} ")
msg = clientsocket.recv(msg_length) //Get the message
if len(msg)>0:
print(f'Message is: {msg.decode("utf-8")}')
Server.py 输出:
The message length: 21
Message is: hello this is a test
我省略了套接字 headers 和其他东西以及错误检查以在这个 post 中保存 space。
这是使用固定长度 headers 的安全方法吗?我预计不会有大量流量,我只会在每条消息中发送一两句话的信息。
我的最后一个问题是为什么在 C 中调用 send 时我要使用“&test_conv”作为消息参数。那不只是发送 test_conv 变量的地址值吗?我不需要发送实际消息,而不是地址吗?
感谢您的任何见解,如果我应该使用不同的实现,请提供任何资源链接。
你的解决方案依赖于一个固定大小的整数来宣布数字
以下消息中的字节数对我来说似乎是正确的。
请务必始终如一地使用 sizeof
and/or strlen()
您实际程序中的文本消息。
在您的示例中,传输 sizeof(text2)
字节包括
text2
末尾隐含 '[=13=]'
;然后 python 字符串
这是在接待处建造的,包含这个无用的(看不见的
但仍然存在)空字节作为最后一个字符。
关于send()
中的&test_conv
,你需要明白
此系统调用仅考虑字节序列。
它不知道这些字节包含一个整数。
这就是为什么您提供要发送的第一个字节的地址
(&test_conv
) 和要发送的字节数
(sizeof(uint32_t)
) 从这个地址开始。
接收方将获得完全相同的字节序列
将它们解释为 32 位整数的内存表示
(当然要考虑字节顺序)。
请注意 python 中的 struct
包可以帮助处理
具有整数和字节顺序的内存表示。
在我看来你应该使用网络字节顺序,而不是主机字节顺序。
- https://pythontic.com/modules/socket/byteordering-coversion-functions
- https://www.ibm.com/support/knowledgecenter/en/SSB27U_6.4.0/com.ibm.zvm.v640.kiml0/asonetw.htm
此外,我相信 send() 和 recv() 可以提前 return,无需传输所有请求的内容 - 这就是它们 return 长度的原因。通常他们会传输您的所有数据和 return 完整长度,但不保证他们会这样做。
对于python,我喜欢我的http://stromberg.dnsalias.org/~dstromberg/bufsock.html模块。它负责为您恢复。
对于 C,我认为人们几乎只对每个 send() 和 recv() 使用一个 while 循环。