QT在使用protocal的问题解决记录之std :: string和QByteArray之间的无损转换

服务器端使用的是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

参考:https://www.baidu.com/link?url=4mVLRkMqkntr8LKbjebDmzN-psdUpYfyLi3AgHU7VY6g_zZ3sZkUzJf688ZwwUKjDfWq28_pCAWZZ6aNcBZ-a_&wd=&eqid=b77dcc4600015dde000000055c9ee066

	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进制打印出来的。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值