发送固定大小的 UDP 数据包
Sending a fixed size UDP packet
我正在编写一个C++程序来发送10字节的UDP数据包。 数据包由 3 个部分组成:
1 字节 - 0-9 之间的单个数字
1 字节 - 0-2 之间的单个数字
8 字节 - 从 0 到 uint64 最大值的数字
例如,假设数字是 2、0 和 14829735431805717965。 我现在正在做的是将这些数字作为变量发送到 ostringstream,我从这个线程读取应该将值转换为 ASCII 以进行序列化。
ostringstream str1;
uint8_t byte1 = 2;
uint8_t byte2 = 0;
uint64_t bytes = 14829735431805717965;
str1 << byte1<< byte2 << bytes;
string result = str1.str();
const char *pchar = result.c_str();
上面的代码演示了我使其与 sendto(( 方法兼容的过程。然而,当我sizeof(str1)
时,我得到 152,即使单独考虑这些变量加起来为 10 字节 (1+1+8(。当我做sizeof(result)
和sizeof(pchar)
时,我分别得到 28 和 4 - 没有什么与我的 10 个字节相近的。我只能以某种方式发现我这样做的方法是错误的 - 每个数字uint64_t bytes
是否转换为单独的 ASCII,加起来为 150 或其他什么? 我四处寻找类似的问题,但无济于事。
但是当我做 sizeof(str1( 时,我得到 152
这是因为您正在获取ostringstream
对象本身的字节大小。ostringstream
中除了指向字符数据的指针外,还包含许多数据成员。您正在寻找实际字符数据的字节大小。ostringstream
不直接提供该大小。
即使单独考虑这些变量加起来也有 10 个字节 (1+1+8(。
原始变量可以,是的。 但是,通过使用operator<<
,您将它们的值序列化为一个string
,其中每个数字数字在字符串中成为它自己的字符,因此最终字符数据的总字节大小将更像 22,而不是 10。
当我做 sizeof(result( 和 sizeof(pchar( 时,我分别得到 28 和 4
同样,因为您分别获取string
对象本身的字节大小(除了指向字符数据的指针之外,它还具有其他数据成员(和原始指针本身的字节大小。 您正在查找string
内部指向的字符数据的字节大小。
result.c_str()
将返回指向实际字符数据的指针,result.size()
将为您提供该数据的正确字节大小。
只能以某种方式发现我这样做的方法是错误的
在这种情况下,使用operator<<
是完全错误的解决方案。 要将二进制数据放入ostream
,请改用其write()
方法,例如:
uint8_t byte1 = 2;
uint8_t byte2 = 0;
uint64_t bytes = 14829735431805717965;
ostringstream str1;
str1.write(reinterpret_cast<char*>(&byte1), sizeof(byte1));
str1.write(reinterpret_cast<char*>(&byte2), sizeof(byte2));
str1.write(reinterpret_cast<char*>(&bytes), sizeof(bytes));
string result = str1.str();
sendto(..., result.c_str(), result.size(), ...);
就个人而言,我建议改用字节对齐的结构:
#pragma pack(push, 1)
struct packet {
uint8_t byte1;
uint8_t byte2;
uint64_t bytes;
};
#pragma pack(pop)
packet p;
p.byte1 = 2;
p.byte2 = 0;
p.bytes = 14829735431805717965;
sendto(..., reinterpret_cast<char*>(&packet), sizeof(packet), ...);
或者,更糟糕的情况是,只需使用一个简单的字节数组:
char packet[10];
uint8_t byte1 = 2;
uint8_t byte2 = 0;
uint64_t bytes = 14829735431805717965;
memcpy(&packet[0], &byte1, sizeof(byte1));
memcpy(&packet[1], &byte2, sizeof(byte2));
memcpy(&packet[2], &bytes, sizeof(bytes));
/* or:
*reinterpret_cast<uint8_t*>(&packet[0]) = byte1;
*reinterpret_cast<uint8_t*>(&packet[1]) = byte2;
*reinterpret_cast<uint64_t*>(&packet[2]) = bytes;
*/
sendto(..., packet, sizeof(packet), ...);
- 发送固定大小的 UDP 数据包
- 使用C++将UDP数据包存储在Structure中
- 在高数据包速率下最大限度地减少丢弃的 UDP 数据包 (Windows 10)
- Qt 在可预测的秒数后跳过 UDP 数据包
- 高频接收UDP数据包:丢包?
- 为 posix recv 设置超时会导致 udp 数据包丢失吗?
- 了解 UDP 数据包大小限制的 TCP 数据包大小限制以及它在 boost::asio 编程级别的含义
- 获取进入UDP数据包的目标端口
- 操纵Windows Explorer窗口时,UDP数据包会掉落
- C++ 使用 recvmmsg 丢弃 UDP 数据包
- 如何在QT中接收适当的UDP数据包
- 使用ASIO捕获大量UDP数据包
- 如何正确接收多播UDP数据包
- 服务器未收到UDP数据包,花费数小时试图找出问题所在
- 当接收缓冲区几乎满时,阻止UDP数据包被部分截断
- 如何检查UDP数据包是否在发送器上发送
- 使用 QNX 实时操作系统实时接收 UDP 数据包
- 高效地发送UDP数据包流
- 为什么我在使用 winsock 时没有收到 UDP 数据包?
- SDL_net UDP 数据包数据