1

将结构头与 vec<char> 相互转换

我试图用较小的 char* 消息打包一个消息缓冲区向量,这些消息与它们各自的标头一起交错。这些标头从结构中转换为 char*。接收器通过从头跳到头来解包缓冲区。使用标头,他们可以识别相应消息的大小以及下一个标头从哪个位置开始。

 struct header_t { uint64_t src : 16; uint64_t dst : 16; uint64_t len : 32; } __attribute__((packed));

这是一个固定大小的标头结构。它们使用 using 转换为向量:

 std::vector<char> pack_header(int src, int dest, int data_size){ header_t hdr_struct{(uint64_t)src, (uint64_t)dest, (uint64_t)data_size}; char* ptr = reinterpret_cast<char*>(&hdr_struct); std::vector<char> hdr = std::vector<char>(ptr, ptr + sizeof(header_t)); return hdr; }

主要通过将它们附加到缓冲区来打包 3 条消息以及它们各自的标头。为简单起见,我也在这里调用解包函数,但在实际应用程序中,缓冲区在其他一些进程中解包。

 int main() { auto header1 = pack_header(2, 4, 43); auto header2 = pack_header(2, 4, 29); auto header3 = pack_header(2, 4, 23); //Test messages of the given sizes char* data1 = new char[43](); char* data2 = new char[29](); char* data3 = new char[23](); //messages interleaved with headers std::vector<char> buffer; buffer.insert(buffer.end(), header1.begin(),header1.end()); buffer.insert(buffer.end(), data1, data1+43); buffer.insert(buffer.end(), header2.begin(),header2.end()); buffer.insert(buffer.end(), data2, data2+29); buffer.insert(buffer.end(), header3.begin(),header3.end()); buffer.insert(buffer.end(), data3, data3+23); unpack(buffer); return 0; }

此解包函数通过以标头长度(8 字节)+ 消息长度的大小进行迭代来遍历缓冲区。

 void unpack(std::vector<char> &stream) { char* bitr = &stream[0]; int step =0; std::vector<header_t*> hdr_stream; while(step <= stream.size()) { std::cout<<"\nstep: "<<step; header_t header; memcpy(&header, bitr, sizeof(header_t)); std::cout<<"\nlen_after : "<<header.len<<"\n"; step+=header.len + sizeof(header_t); bitr+=step; } }

unpack 函数正确地遍历前 2 条消息,但在此之后迷路并且不推断标题。输出如下所示:

 step: 0 message length : 43 step: 51 message length : 29 step: 88 message length : 0 step: 96 message length : 0 step: 104 message length : 0 step: 112 message length : 0

无法从第二条消息后的标头正确推断大小的任何原因。它只是将大小读取为 0 并跳过标题而不是标题 + 消息。

已提交 July 24th 2021 通過 Admin

答案
0

每次迭代时,您都会step增加当前数据包的大小。它是下一个数据包开始位置的stream但是,您bitr ,导致未定义行为,因为bitr已增加超过缓冲区的末尾。

你得到的是:

 start of 1st loop: bitr = 0 start of 2nd loop: bitr = 51 (size of first packet) start of 3rd loop: bitr = 139 (51 + 51 + 37, 2 * size of first packet + size of second packet)

您想要做的是将bitr增加与增加step相同的数量( bitr+=header.len + sizeof(header_t); ),或者将 set bitr设置为新计算的索引( bitr = &stream[step]; )。

Admin | 1个月前



枪支相关