获取packetLength后如何正确遍历数据包?C++代码问题排查
问题描述
给定包头结构示意图如下:
我尝试用以下C++代码遍历二进制文件,打印每个包的Length和Num Market Updates字段:
std::ifstream fileOpener(m_rawInputFileName, std::ios::binary); if (!fileOpener.is_open()) { std::cout << "Error: could not open file" << std::endl; fileOpener.close(); return; } short int packetLength; short int numOfMarketUpdates; while (fileOpener.read((char *)&packetLength, 2) && fileOpener.read((char *)&numOfMarketUpdates, 2)) { cout << packetLength << ":" << numOfMarketUpdates << endl; fileOpener.seekg(-4, std::ios::cur); fileOpener.seekg(packetLength, std::ios::cur); }
请问这段代码存在什么问题,还是数据本身不准确?
代码问题分析
- 字节序不匹配:二进制文件的包头大概率是大端字节序(网络传输数据的通用格式),而当前代码用
short int直接读取,若你的机器是小端字节序,读取的数值会完全颠倒。比如文件里的Length是0x0010(十进制16),小端机器读出来会变成0x1000(十进制4096),直接导致后续包位置跳转错误。 - 跳转逻辑存在歧义且冗余:代码先回退4字节再跳转
packetLength,等价于从当前位置跳过packetLength -4字节。但要注意packetLength的定义:如果它是整个包的总长度(包含包头4字节),这个计算是对的;如果它是包头之后的数据长度,那应该直接跳过packetLength字节,不需要回退,否则会跳过错误的长度,导致下一个包读取出错。 - 未处理部分读取的情况:
read操作可能在文件末尾只读取了部分字节(比如只读了1个字节),但代码直接用逻辑与判断,会导致变量值异常,进入错误的循环流程。 - 命名空间缺失:代码中使用
cout但未添加std::前缀,编译时会报错。
如果修正以上代码问题后依然无法正确读取,再考虑数据本身的问题:比如文件是否损坏、是否从正确的起始位置开始读取、文件格式是否与给定的包头结构一致。
内容的提问来源于stack exchange,提问作者User010000100110100101110010
相关产品推荐
相关产品推荐

