服务器端使用的是skynet+lua,lua版本是5.3.5,pbc库是前面的教程中编译的。
客户端使用是C++版本的protobuf,也是教程里编译的。
客户端使用的是Qt库QTcpSocket收网络字节流,收到后,根据消息号将经过lua版本的protocal buffer进行encode后的字节流反序列化。
客户端encode的字节流发送到服务器端,服务器收到后可以正常反序列化出来;
自己写的bug是客户端收到服务器端的字节流后反序列化失败,what?
我就开始怀疑是否跟语言有关,还是自己的字节流长度处理,或者编码有问题。开始排查:
排查思路:
第一步,打印出lua版本的pbc的encode后的内容,以16进制逐个字符开始打印;打印出客户端,也就是Qt端收到的字节流,也是逐个字符按16进制打印,比对是否一致。
实验结果:发现是两者的内容是相同的,长度也相同。
第二步,怀疑是自己用QTcpSocket收到的QByteArray的字符数组转成std::string有问题。
参考:https://cloud.tencent.com/developer/ask/32018
从Qt 5.4开始,通过和QByteArray建立了对std::string转换的支持。QByteArray::toStdString()QByteArray::fromStdString()
inline std::string QByteArray::toStdString() const
{ return std::string(constData(), length()); }
inline QByteArray QByteArray::fromStdString(const std::string &s)
{ return QByteArray(s.data(), int(s.size())); }
对于旧版本的也可以自己写:
// std::string => QByteArray
QByteArray byteArray(stdString.c_str(), stdString.length());
// QByteArray => std::string
std::string stdString(byteArray.constData(), byteArray.length());
尽量用Qt库里的,都是inline函数了。
用这个之后,收到后的字节流转成std::string,再用protocal buffer进行反序列化就没问题了。
附上“Lua的十六进制输出字符串”
function ToolUtils.bin2hex(s)
s = string.gsub(s,"(.)",function (x) return string.format("%02X ",string.byte(x)) end)
return s
end
参考:https://www.jianshu.com/p/3b8f72894ac0
Qt中16进制打印出QByteArray
QByteArray buff;
中间省略
QString strHex = QString::number( buff.at(i), 16);
用QString::number,16进制,即可将char转成16进制字符串,只是这个字符串看到会有些不同。
"34"
"30"
"30"
"30"
"36"
"10"
"ffffffffffffffad"
"ffffffffffffffc2"
"fffffffffffffffb"
"ffffffffffffffe4"
"5"
"8"
对于这样的字符串"ffffffffffffffad" ,实际看最后两位,才是char以16进制打印出来的。