从python到C的固定长度套接字通信



正在更新我的应用程序,该应用程序使用套接字从python到C程序进行通信,以便在发送消息时使用固定长度的标头作为协议。

作为我的 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

我省略了套接字标题和东西以及错误检查以节省本文的空间。

这是使用固定长度标头的安全方法吗?我不希望有大量的流量,我只会在每条消息中发送一两句话的信息。

我的最后一个问题是为什么在 C 中调用 send 时我使用"&test_conv"作为消息参数。这不仅仅是发送test_conv变量的地址值吗?我不需要发送实际消息,而不是地址吗?

感谢您的任何见解,如果我应该使用不同的实现,请提供任何资源链接。

依赖于宣布数字的固定大小整数的解决方案 以下消息中的字节数对我来说似乎是正确的。
只要确保始终如一地使用sizeof和/或strlen()实际程序中的文本消息。
在您的示例中,传输sizeof(text2)字节包括text2末尾的隐式'';然后是 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() 被允许提前返回,而无需传输所有请求的内容 - 这就是它们返回长度的原因。 通常他们会传输您的所有数据并返回完整长度,但不能保证这样做。

对于python,我喜欢我的 http://stromberg.dnsalias.org/~dstromberg/bufsock.html 模块。 它为您负责恢复。

对于 C,我认为人们几乎只是为每个 send() 和 recv() 使用 while 循环。

最新更新