UDP传输&维护网络字节顺序

时间:2014-04-02 20:19:24

标签: c++ sockets networking udp

所以我在通过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;

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

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

  2. 如果从问题1中正确订购了所有内容,我是否需要在接收端将它们再次转换回主机订单?

  3. 我有一个mmap函数将文件加载到char缓冲区中,我可以简单地使用memcpy和增量偏移量这样一块一块地复制到数据包中的数据缓冲区吗?或者我是否还要担心有效载荷数据的网络顺序?

  4. 我是否需要对有效负载使用校验和?如果它不使用整个缓冲区并以奇数个字节结束,我该怎么办呢?

  5. 最终我希望标题包含序列号,这样我就可以在丢弃数据包时练习实现程序(即返回N),所以我最担心的是标准化从客户端发送所有内容的顺序,以便它可以在服务器端以正确的顺序解释。

1 个答案:

答案 0 :(得分:5)

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

如果必须将数据拆分为多个包,则需要在数据包标头中放入信息以指定数据包的顺序。 UDP不保证数据包的到达顺序与它们发送的顺序相同,甚至不保证数据包到达。因此,接收方需要收集数据包(根据需要请求丢失数据包),然后在处理数据之前对其进行相应的重新排序。

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

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