【问题标题】:How to divide int64_t to two int32_t and send it over the network?如何将 int64_t 分成两个 int32_t 并通过网络发送?
【发布时间】:2013-06-11 10:42:50
【问题描述】:

我想通过 UDP 发送两个 int64_t。为此,我将它们存储在一个四元素数组中,其中:

  • [0] - 第一个 int64_t 的低 32 个
  • [1] - 第一个 int64_t 的高 32 位
  • [2] - 第二个低 32 位 int64_t
  • [3] - 如果是第二个 int64_t,则高 32 位

我的发送代码:

int64_t from, to;

/* some logic here */

data[0] = htonl((int32_t) from);
data[1] = htonl((int32_t) (from >> 32));
data[2] = htonl((int32_t) to);
data[3] = htonl((int32_t) (to >> 32));

/* sending via UDP here */

我在通过 UDP 接收到data 后将int32_t 组合回int64_t 的代码:

int64_t from, to;
from = (int64_t) ntohl(data[1]);
from = (from << 32);
from = from | (int64_t) ntohl(data[0]);
to = (int64_t) ntohl(data[3]);
to = (to << 32);
to = from | (int64_t) ntohl(data[2]);

printf("received from = %" PRId64 "\n", from);
printf("received to = %" PRId64 "\n", to);

第一个数字 (from) 始终正确。但是,我从第二个printf 得到的信息是不正确的。更重要的是,它似乎依赖于第一个数字。示例:

发送:

  • from = 125,
  • to = 20。

收到:

  • from = 125,
  • to = 125。

发送:

  • from = 1252,
  • to = 20。

收到:

  • from = 1252,
  • to = 1268。

我做错了什么?是转换的问题还是网络发送的问题?

【问题讨论】:

  • 我不确定,但是用有符号的数字而不是无符号的数字来做这种事情可以吗?例如。 (int32_t) from 是签名溢出,对吧?这不是未指明的行为吗? en.wikipedia.org/wiki/Integer_overflow "在 C 编程语言中,有符号整数溢出导致未定义行为"

标签: c unix udp posix int64


【解决方案1】:

您的接收方代码中有错字:

to = from | (int64_t) ntohl(data[2]);

应该是

to = to | (int64_t) ntohl(data[2]);

【讨论】:

  • +1。这就是为什么重复代码(或复制粘贴)是不好的,你应该把那种东西放到方法/宏中——一旦大脑关闭,你的手指就会开始输入垃圾。
【解决方案2】:

请注意,您正在向后发送 64 位值。 htonl() 确保 int32 以正确的顺序发送,但 RFC 1700 定义首先传输字段的最重要八位字节:

当传输多字节数量时,最重要的八位字节是 先传送。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 2015-04-03
    • 1970-01-01
    • 1970-01-01
    • 2011-04-05
    • 2021-02-24
    • 1970-01-01
    相关资源
    最近更新 更多