在线游戏数据包查看器丢包求助:捕获数据包缺失最后6字节
问题原因与修复方案
嘿,我来帮你揪出这个数据包丢字节的问题!你的代码里有几个关键问题,其中最核心的就是二进制数据的处理逻辑错误:
1. 二进制数据被字符串构造函数截断(核心原因)
你把buf直接传给string构造函数string(buf),但这个构造函数是给文本字符串设计的——它会从指针位置开始读,直到碰到第一个\0(也就是0x00字节)就立刻停止。而你丢失的那6字节正好以00开头,所以构造string的时候,读到这个0x00就直接停了,后面的04 FF FF FF FF全被丢了,自然输出的十六进制就少了一截。
数据包是二进制数据,里面出现0x00太正常了,绝对不能用默认的字符串构造函数处理,必须把实际的数据包长度len传进去,告诉构造函数要读多少字节。
2. 文件打开模式用错了运算符
你写的std::ios_base::app || std::ios_base::ate这里,逻辑或||是错的,应该用位或运算符|。逻辑或返回的是布尔值,会被转成整数,导致文件打开模式乱掉,可能引发写入失败或者奇怪的文件行为。
3. 变量名拼写错误
代码里的tesfile.close();少打了个t,应该是testfile.close();,这个错误轻则编译失败,重则运行时出问题,得赶紧改。
修复后的代码
我帮你把这些问题都修正了,你可以试试:
int WINAPI SendHook(SOCKET s, const char* buf, int len, int flags) { if (buf[0] == 0x03) { ofstream testfile; // 用位或指定正确的打开模式 testfile.open("C:/test.txt", std::ios_base::app | std::ios_base::ate); if (testfile.is_open()) { // 先检查文件是否成功打开,避免白忙活 // 传入buf的实际长度len,彻底解决0x00截断问题 string hex = Hex::ToUtf8Hex(string(buf, len)); testfile << hex << "\n"; // 加个换行,方便每次的数据包分开看 testfile.close(); } } return pSend(s, buf, len, flags); }
额外小建议
- 处理二进制数据包的时候,一定要时刻记住传递数据长度,别依赖字符串的自动截断逻辑,这是新手常踩的坑。
- 每次打开文件后最好检查一下
is_open(),万一路径不对或者没权限,也能及时发现问题。 - 可以在输出的时候加上数据包长度的日志,比如
testfile << "数据包长度: " << len << " 十六进制: " << hex << "\n";,这样你能直接对比Wireshark的长度和代码捕获的长度,更容易排查问题。
内容的提问来源于stack exchange,提问作者user9242661
相关产品推荐
相关产品推荐

