C和Python之间的Unix套接字

C和Python之间的Unix套接字,python,c,sockets,unix,endianness,Python,C,Sockets,Unix,Endianness,刚刚制作了一个Python程序,它充当Unix套接字的服务器,当它接收到连接时,从中读取4个字节 另一方面,我制作了一个C程序,它连接到服务器并将这4个字节发送给它 file.py packet = connection.recv(4, socket.MSG_WAITALL) for value in packet: if value == '\0': print 'A none' else: print value packet = conne

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

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

file.py

packet = connection.recv(4, socket.MSG_WAITALL)
for value in packet:
    if value == '\0':
        print 'A none'
    else:
        print value
packet = connection.recv(16, socket.MSG_WAITALL)
// everything else, wasn't modified
文件.c

size_t toSend 84; // Char representation \0\0\0T
write(fd, (void *)&toSend, sizeof(toSend));
char abc[16]; 
// setting char abc to be 'ABCDEFGHIJKLMNOP' (without ending \0)
write(fd, (void *)&abc[0], 16);
这使得python程序接收到错误的字节顺序。这里是输出

T
A none
A none
A none
我想到的第一件事是,这是endianness的结果,但后来我修改了文件,留下了这样的文件

文件.c

size_t toSend 84; // Char representation \0\0\0T
write(fd, (void *)&toSend, sizeof(toSend));
char abc[16]; 
// setting char abc to be 'ABCDEFGHIJKLMNOP' (without ending \0)
write(fd, (void *)&abc[0], 16);
file.py

packet = connection.recv(4, socket.MSG_WAITALL)
for value in packet:
    if value == '\0':
        print 'A none'
    else:
        print value
packet = connection.recv(16, socket.MSG_WAITALL)
// everything else, wasn't modified
这张纸上写着:

A
B
C
...
P
所以这一次它是按预期的方式收到的。有人能指出我做错了什么吗?除非它与
size\u t
类型有关,否则我想不出其他任何东西


谢谢

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

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

这实际上与Python无关,与套接字无关,但您是对的,它确实与endian有关

测试您的隐式假设:在运行C客户端程序的计算机上,84是否真的表示为
0x000x000x 000x54
?尝试写入文件而不是套接字,然后对结果进行二进制编辑。我打赌您会看到您的本地体系结构是little endian,并且写入的数据是
0x54 0x00 0x00 0x00


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

这实际上与Python无关,也与套接字无关,但您是对的,它确实与endianness有关

测试您的隐式假设:在运行C客户端程序的计算机上,84是否真的表示为
0x000x000x 000x54
?尝试写入文件而不是套接字,然后对结果进行二进制编辑。我打赌您会看到您的本地体系结构是little endian,并且写入的数据是
0x54 0x00 0x00 0x00


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

Endianness与
char
s无关,我建议使用固定大小的类型,即:
uint32\u t
而不是
size\u t
Endianness与
char
s无关,我建议使用固定大小的类型,即:
uint32\u t
而不是
size\u t
s/相反顺序/大端顺序/
s/相反顺序/大端顺序/
注意,典型的windows PC都是小端顺序的,所以如果你在windows上运行,您可以非常确定您的数据存储在little endian中。我使用的是Raspberry Pi W,您是对的,它表示为
0x54000000
。谢谢既然PC是小端数(0x54000000),pi是小端数,pi不应该和PC一样吗?@KevinDTimm谢谢。当我写评论的时候,我的大脑发生了错误,我的脑袋变得越来越大。两者都表明raspberry pi(通常)是小endian,所以这是有意义的。注意,典型的windows PC是小endian,所以如果您在windows上运行,您可以非常确定您的数据是以小endian存储的。我使用的是raspberry pi W,您是对的,它表示为
0x54000000
。谢谢既然PC是小端数(0x54000000),pi是小端数,pi不应该和PC一样吗?@KevinDTimm谢谢。当我写评论的时候,我的大脑发生了错误,我的脑袋变得越来越大。两者都表明覆盆子圆周率(通常)是小端点,所以这是有意义的。