Python 套接字:无法接收 int 数组

Python socket: cannot receive int array

我尝试通过 winsockets 在 Python 和 c 程序之间进行进程间通信。发送一个字符串确实有效,但现在我尝试将一个 int 数组从 c 套接字发送到 python 套接字。

我已经发现我必须使用 htonl() 将 int 数组转换为字节流,因为 winsock2 的发送函数不能直接发送 int 数组。

现在我想在 python 套接字中使用 ntohl() 但接收函数 returns 字节,而 ntohl() 需要一个整数值作为输入。

这是我的代码

C端(仅相关部分):

uint32_t a[1] = {1231};
uint32_t a_converted[1]={0};
a_converted[0] = htonl(a[0]);
iResult = send( ConnectSocket, ( char *)   a_converted, sizeof( a_converted), 0 );

Python 边(仅相关部分):

data = connection.recv(16)
data_i = socket.ntohl(data)

您说您已成功通过连接发送字符串。我假设您发送了一个 char* 并在 python 中收到了它作为一个字符串。你所做的是发送一个字节流。

现在您想发送一个整数数组。在内存中,整数再次存储为字节。 每个整数可能占用 4/8 字节。您可以通过打印

来事先检查
printf("Size of integer is %zu", sizeof(int));

好的,很好,现在我们知道需要发送多少字节了。假设现在是 4。

我们还需要知道整数的字节序,但我们现在假设是大字节序。

这意味着最低有效字节在前,最高有效字节在最后。

所以现在您可以发送整数数组,方法是将数组转换为 char* 并发送 sizeof(array).

虽然在接收端,您只有一个字节流。要将其转换为整数数组,您需要一次获取 4 个字节并将其组合成一个整数。

我们可以这样做。

假设共有 10 个整数。您必须以某种方式单独传递此信息。

bytes = connection.recv(10*4)

array = []
for i in range(10):
    x = ord(bytes[i*4+0])
    x += ord(bytes[i*4+1]) << 8
    x += ord(bytes[i*4+2]) << 16
    x += ord(bytes[i*4+3]) << 24
    array += [x]
print x

您将能够看到整数数组。

此处函数 ord 将一个字符转换为其 ASCII 等效整数。

旁注:

现在,如果您的系统的整数大小为 8 而不是 4,则您需要扩展 python 中的循环体。它将一直持续到 56。此外,每个索引(以字节为单位)将是 i*8+...

同样,如果字节顺序不同,元素的顺序也会改变。基本上 bytes 上的索引将从 i*4+3 变为 i*4+0

你收到的是一串字节,ntohl没有异常吗? 您可以使用 struct 模块解压 - 16 字节

struct.unpack('!4I', data)

含义 - 按网络顺序解压 4 个无符号 32 位整数

RTM

(我无法测试,请自行尝试)

编辑: 哎呀,没看完你的评论。根据 sockets docsrecv 应该 return 类型为 bytes 的对象。如果它 returns 类型为 str 的对象 - 您应该将其转换为 bytes - 在 Python3 中它将是 data.encode()

PS你在哪个Python?