如何创建特定大小的消息以通过 C++ 中的 UDP 套接字发送?

How to create specific size message to send via UDP socket in C++?

我正在尝试编写一个小型应用程序,它将 "concatenate" 一堆不同大小的整数变量(uint8、uint16、uint32)转换为将通过 UDP 套接字发送的 128 字节消息。

在接收方,我想将消息拆分回单个整数并存储它们以供进一步处理。现在我假设字节顺序不会成为问题。

我能得到一些关于如何连接 int 变量并随后从 128 字节消息中提取它们的提示吗?

您可以创建一个字符缓冲区前缀,该前缀将在每个整数之前定义要读取的整数类型,这样您就可以读取所定义整数的正确大小。

例如:在每个整数前面加上一个代表整数的字符。第一个字节将包含您将解释为 an 的字符,它可以是任何表示整数的 ascii 字符。

array == [byte][byte-8bit][byte][2 byte-16bit][byte][4 byte -32bit]...

UINT8 = 'a' UINT16 = 'b' UINT32 = 'c' 或者任何你想要的 ascii 代码...我使用 a,b,c 所以它是一个你可以在调试器中读取的可读字符

然后您必须构建要使用前缀发送的数组,以便您知道下一次读取的大小。

array = [a0b00c0000a0b00c0000]等,可以使用memcpy

构建数组

然后您可以发送整个 128 字节的数据包

确保你读到的正好是128个字节,然后你就可以解构了,记住读的时候一定要检查从socket中读到的量,继续读直到收到正确的量。 -- 有时读取不会 return 您期望的正确字节数。

当您收到数据包时,您可以使用 header 解构数据包,并且根据您收到的 header,您可以删除正确的整数和大小,以及 header正确大小的应该很容易解构。

还要记住 UDP 是有损的,因此您可能会丢失数据包

现在还请记住,如果您构造的数据包每次都不完全等于 128 个字节,您将需要添加另一个字节,该字节相当于一个整数,它会告诉您确切发送了多少字节...122。 .126..127 等,并将其作为另一边的第一个 header 阅读。

那么,假设您希望按以下顺序接收数据:

int32_t header; int8_t opcode; int16_t args[32]; int32_t clients[2]; ...

这只是一个示例,参数可以是您实际任务中的任何参数。

您可以将这些参数包装到 structclass 中。我更喜欢这里的 struct,因为看起来您并不真的需要创建构造函数、访问说明符或 class 可以提供的任何其他花哨的东西。所以,类似的东西:

#pragma pack(push, 1)
struct DataFromMyHardware {
    int32_t header;
    int8_t opcode;
    int16_t args[32];
    int32_t clients[2];
    ...

};
#pragma pack(pop)

pragma这里用来告诉编译器不要优化结构中变量的放置或对齐,所以它会按原样存储在内存中。

这样,您可以在发件人上使用它:

DataFromMyHardware buffer;
buffer.header = 0xDEADBEEF;
buffer.opcode = 42;
...
send(socket, &buffer, sizeof(buffer), 0);

接收方:

DataFromMyHardware buffer;
recv(socket, (void*)&buffer, sizeof(buffer), 0);

旁注:您的设备很可能使用网络字节顺序,因此您可能希望在接收方使用 nhohl/ntohs 并在发送方使用 htonl/htons