【问题标题】:UDP transfer & maintaining network byte orderUDP传输和维护网络字节顺序
【发布时间】:2014-04-02 20:19:23
【问题描述】:

所以我在通过 C++ 中的客户端-服务器程序发送和接收自定义数据包时遇到了一些问题。我使用 TCP 实现了类似的功能,但是在使用 UDP 时将所有内容转换为单个数据报时遇到问题。

目前我的标题由偶数个 uint32_t 字段组成。这些中的每一个都以网络顺序存储在标头结构中:

 uint32_t x = htonl (int y);

...

我正在将报头与数据包中的有效负载结合起来,如下所示:

 typedef struct {
    450Header header; // 512 bytes consisting of the unint32_t like above
    char data[ BLOCKSIZE ];  // 3.5k
    // Total Packet Size = 4k
} Packet;

'

标题部分将包含有关数据包的信息,我的问题是如何处理字符串和有效负载的字节顺序。理想情况下,我想为文件名之类的标头添加一些字符串字段,如果我发送的文件大于数据包中的块大小,我想将其拆分为多个数据包,我需要知道如何拆分文件,因此它可以在接收端以正确的顺序解释。

  1. 我已经成功地独立构建了一个标头(所有字段都按网络字节顺序排列),如果我将它们添加到标头中,是否还需要转换字符串的顺序?我假设如果我将字符串保持在设定的大小,我仍然可以为标题编写校验和函数。

  2. 如果问题 1 中的所有内容都正确排序,我是否需要在接收端再次将它们转换回主机顺序?

  3. 我有一个 mmap 函数,可以将文件加载到 char 缓冲区中,我可以使用 memcpy 之类的方法将其逐个复制到数据包中的数据缓冲区并增加偏移量吗?还是我还需要担心负载数据的网络顺序?

  4. 我需要在负载上使用校验和吗?如果它不使用整个缓冲区并以奇数字节结束,我该怎么做?

最终我希望标头包含序列号,这样我就可以在丢包的情况下练习实施程序(即返回 N),所以我最担心的是标准化从客户端发送所有内容的顺序,所以它可以在服务器端以正确的顺序进行解释。

【问题讨论】:

    标签: c++ sockets networking udp


    【解决方案1】:

    8 位数据(包括 8 位整数、Ansi/UTF-8 字符串等)不受字节顺序问题的影响,因此您可以按原样发送/接收它们。只有多字节数据(如 16 位/32 位整数、16 位 UCS2/UTF-16 字符串等)您必须处理字节顺序。例如,整数应始终按网络字节顺序排列,但 UTF-16 字符串可以自行决定使用 UTF-16LE 或 UTF-16BE(尽管您应该改用 UTF-8)。

    如果你必须将数据拆分成多个包,那么你需要在包头中放入信息来指定包的顺序。 UDP 不保证数据包按照它们发送的顺序到达,甚至不保证它们完全到达。所以接收者需要收集数据包(根据需要请求丢失的数据包),然后在处理数据之前对它们进行相应的重新排序。

    是的,您应该始终在发送数据包之前将其转换为网络字节顺序,并在接收端处理它们时转换回主机字节顺序。转换为网络字节顺序仅用于传输目的,以确保跨平台的格式一致。

    校验和是确保每个数据包数据完整性的好主意,但这不是必需的。你当然可以为任意长度的数据提供一个固定长度的校验和,有很多校验和算法支持它。

    【讨论】:

      猜你喜欢
      • 2014-05-18
      • 2022-01-22
      • 2017-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-30
      • 2013-10-23
      • 1970-01-01
      相关资源
      最近更新 更多