在两个套接字之间传输整数值 C++

Transmitting integer values between two sockets c++

我有一个 C++ 套接字程序,其中有两个进程。服务器进程和客户端进程。客户端向服务器注册并在端口上侦听来自服务器的任何消息。

我已经定义了一个 "char *buffer",它将包含我的消息。消息大小为 59000 字节。现在在传输消息之前,我在缓冲区的开头添加了消息大小,

size=htonl(59000)
Buffer= size + <Actual Message>

以便客户端进程在收到消息时首先读取前两个字节以获得大小,知道传输的消息的大小,然后从套接字读取完整的消息。这是按如下方式完成的

59000 in binary format is          00000000 00000000 11100110 01111000  
htonl(59000) in binary format is   01111000 11100110 00000000 00000000

我使用 memcpy 将此大小复制到字符缓冲区。

memcpy(buffer, &size, 4) <since size of int is 4>

在客户端传输消息后,当我读取前两个字节时,我得到的大小为零。但是如果我读取接下来的两个字节,我会得到正确的大小,即 59000。我在客户端读取消息大小的方式如下所述

int messageSize=0;
memcpy(&messageSize, buffer, 2 );

谁能解释一下为什么消息大小存储在后两个字节而不是前两个字节中。

如果你能帮助我,我将不胜感激。很长一段时间以来,我一直在努力理解这一点。

htonl 将 long(即 4 字节 int)从主机字节顺序转换为网络字节顺序。 Network-byte-order 定义为 big-endian,即多字节数字的最高有效字节在前。 host-byte-order 是 big-endian(在这种情况下 htonl 什么都不做)或 little-endian(在这种情况下 htonl 反转字节)。

在所有情况下,表示59000 的字节将作为0x00 0x00 0xe6 0x78 传输。所以如果你只读前两个字节,你总是会得到0x00 0x00。要在所有系统上正确读取该值,您需要将所有四个字节读入一个 32 位整数,然后调用 ntohl 将数字从网络字节顺序转换为主机字节顺序。

您的解释有一处严重错误:

59000 in binary format is          00000000 00000000 11100110 01111000  
htonl(59000) in binary format is   01111000 11100110 00000000 00000000

是错误的,它确实是另一种方式所以

59000 in binary format is          01111000 11100110 00000000 00000000
htonl(59000) in binary format is   00000000 00000000 11100110 01111000  

这就是 cpu 上的情况,即小端。 因此,由于 int 是 4 个字节,这完美地解释了为什么您首先收到 2 个零字节。

htonl 代表主机到网络的长度。主机顺序是主机上字节的顺序。这在小端和大端机器上可能不同,但网络顺序定义明确,必须如此,否则计算机无法相互通信。

还有htons:简称 htons 和 htonl 的反面是 ntohl 和 ntohs

这些函数做的事情与它们的对应函数完全相同,即在大端系统中它们什么都不做,在小端系统中它们颠倒输入的字节顺序。 htons(htons(x)) 什么都不做。如果值是字节反转的,则无法为计算机检测。当从网络订单到主机订单时使用 ntohl 和 ntohs,当您收到前 4 个字节并想知道长度时,您将需要在客户端使用它。