【问题标题】:Transmitting integer values between two sockets c++在两个套接字c ++之间传输整数值
【发布时间】:2015-03-25 04:10:51
【问题描述】:

我有一个 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 );

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

如果您能帮助我,我将不胜感激。很长一段时间以来,我一直试图理解这一点。

【问题讨论】:

  • 也许你应该发送整个int
  • 我喜欢你的解释方式。但是,我仍然需要查看实际的源代码,否则我无法发现错误。对不起。只需将其粘贴并用 标记将其包围,或者将其缩进四个空格。
  • 或者,哈哈,你可以按照其他评论者所说的去做。 sizeof(int) 是什么?
  • 你实际上在准备发送时 memcpy 四个字节 - 所以似乎知道 htonl 返回多少字节 - 但你说只读取 2 个字节......!
  • 为什么要关心单个字节和两字节块?你有整数。使用 int 和 sizeof(int) 大小的块(不要使用 4 或 2 或其他任何值,使用 sizeof(yourtype))。

标签: c++ c sockets tcp


【解决方案1】:

你的解释有一个严重错误:

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 个字节并想知道长度时,您需要在客户端使用它。

【讨论】:

    【解决方案2】:

    htonl 将 long(表示 4 字节 int)从主机字节顺序转换为网络字节顺序。网络字节序定义为大端序,即多字节数的最高有效字节在前。主机字节顺序要么是大端(在这种情况下 htonl 什么都不做)要么是小端(在这种情况下 htonl 反转字节)。

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

    【讨论】:

      猜你喜欢
      • 2012-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-12
      • 1970-01-01
      相关资源
      最近更新 更多