【问题标题】:Unix sockets between C and PythonC 和 Python 之间的 Unix 套接字
【发布时间】:2017-10-09 12:36:58
【问题描述】:

刚刚制作了一个 Python 程序,它充当 Unix 套接字的服务器,当它接收到连接时,从中读取 4 个字节。

另一方面,我制作了一个连接到服务器并将这 4 个字节发送给它的 C 程序。

文件.py

packet = connection.recv(4, socket.MSG_WAITALL)
for value in packet:
    if value == '\0':
        print 'A none'
    else:
        print value

文件.c

size_t toSend 84; // Char representation \0\0\0T
write(fd, (void *)&toSend, sizeof(toSend));

这使得 python 程序接收到错误的字节顺序。这里是输出

T
A none
A none
A none

我首先想到的是这是字节序的结果,但后来我修改了文件,让它们变成了这样。

文件.c

char abc[16]; 
// setting char abc to be 'ABCDEFGHIJKLMNOP' (without ending \0)
write(fd, (void *)&abc[0], 16);

文件.py

packet = connection.recv(16, socket.MSG_WAITALL)
// everything else, wasn't modified

然后打印出来:

A
B
C
...
P

所以这次它按预期收到了。有人可以指出我做错了什么吗?除非它与size_t 类型有关,否则我想不出别的。

谢谢!

【问题讨论】:

  • 字节顺序与chars 无关,我建议使用固定大小类型,即:uint32_t而不是size_t

标签: python c sockets unix endianness


【解决方案1】:

这实际上与 Python 无关,也与套接字无关,但你是对的,它确实与字节序有关。

测试您的隐含假设:在您运行 C 客户端程序的计算机上,84 真的表示为 0x00 0x00 0x 00 0x54 吗?尝试写入文件而不是套接字,然后二进制编辑结果。我打赌你会看到你的原生架构是 little-endian,写入的数据是 0x54 0x00 0x00 0x00。

您在套接字上看到的只是您发送的内容。

【讨论】:

  • 注意,典型的 windows PC 是 little-endian,所以如果你在 windows 上运行,你可以确定你的数据是以 little-endian 存储的。
  • 我使用的是 Raspberry Pi W,你是对的,它表示为 0x54000000。谢谢!
  • 既然PC是小端(0x54000000),而pi是小端,那么pi不应该和PC一样吗?
  • @KevinDTimm 谢谢。当我写评论时,我的大脑出现了错误接线,我的脑子里忽地忽大忽小。
  • raspberrypi.org/forums/viewtopic.php?f=2&t=531 和 raspberrypi.stackexchange.com/questions/34581/… 都表明树莓派(通常)是小端,所以这是有道理的。
【解决方案2】:

这正是字节顺序。单个字节的位总是相同的顺序,但一个字中的字节顺序可能不同。首先,您发送一个由 4 个字节组成的单词,它们以相反的(即大端)顺序接收,但在第二个示例中,您将逐字节发送消息。

【讨论】:

  • s/opposite order/big endian order/
猜你喜欢
  • 2020-10-13
  • 2020-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-06
  • 1970-01-01
  • 2017-02-12
相关资源
最近更新 更多