用QT网络序列化和用Boost反序列化
serialization with QT network and deserialization with Boost
在第一时间我要感谢HostileFork帮助我解释我的问题。谢谢!
我正在尝试建立一个客户端和服务器谁通过二进制协议发送他们的数据。
我的问题是我想从QT客户端发送一个类到Boost服务器。我的头(一个整数,它是我的类的大小)在套接字上写入。当我想在服务器端读取报头时,我无法得到好的整数(而不是我有一个像-13050660这样的大数字)。我想问题出在服务器上的反序列化,但我不确定。
这是我的Qt客户端代码用于将数字10写入套接字的技术:
QByteArray paquet;
QDataStream out(&paquet, QIODevice::WriteOnly);
out << (quint32) 0;
out.device()->seek(0);
out << (quint32) (10);
cout << "Writing " << sizeof(quint32) << " bytes to socket." << endl;
然后我尝试在服务器进程上读取它,它使用boost的async_read():
this->Iheader.resize(size, ' '); // Iheader is a vector of char
async_read(
this->socket,
buffer(this->Iheader),
bind(
&Client::endRead,
cli,
placeholders::error,
placeholders::bytes_transferred)
);
下面是对字符串结果进行操作的函数:
#ifdef WIN32
#define MYINT INT32
#include <Windows.h>
#else
#define MYINT int
#endif
void Client::endRead(const error_code& error, size_t nbytes)
{
if (!error && nbytes == sizeof(MYINT)) {
cout << "Read " << sizeof(MYINT) << " bytes from a socket." << endl;
istringstream stream(this->connection->getIheader(nbytes));
stream >> this->Isize;
cout << "Integer value read was " << this->Isize << endl;
} else {
cout << "Could not read " << sizeof(MYINT) << " bytes." << endl;
}
}
我确实得到了32位有符号整数(4字节),但它不是10,而是类似于-1163005939。有人知道为什么这不起作用吗?
服务器和客户端都在Windows7 pro上启动,64位。
不用谢…感谢您按照我的建议编辑问题,并做了必要的努力来更清楚地指出问题。现在我可以告诉你怎么了。:)
<<
和>>
在QDataStream
上的行为与在c++标准io流上的行为不同。在像std::stringstream
这样的类的世界中,这些操作符被称为"插入器"/"提取器",用于处理格式化为文本的信息。如果您想要将一定数量的字节读入内存地址,您需要的是:
(注意,如果你想从非字符串流的东西中读取二进制数据,你需要使用ios::binary来防止它干扰行结束转换)
QDataStream
不遵循这种惯例…它是二进制数据的好帮手。这没什么错……因为抽象地说,<<
和>>
操作符在语言中是可以重载的,可以在自己的类层次结构中做任何你想做的事情。Qt可以自由地为自己的流定义自己的语义,他们也这样做了。
一定要听从@vitakot给出的建议,即(如果可能的话)对输入和输出使用相同的方法。另外,请注意我的警告,如果你不小心,就会出现字节排序问题。
(好消息是,如果您使用的是QDataStream
,它会为您解决这个问题。)
请注意,在您编写的代码中,您的stringstream正在复制缓冲区以便从中读取。我没有boost::asio
的经验,也没有async_read
的最佳实践,但我相信你可能会找到更好的方法。
HostileFork是对的,从我们拥有的信息来看,不可能在你的代码中隔离一个bug。
但是,我建议您在Qt客户端中也使用boost序列化。没有理由不把Boost和Qt库结合起来。否则,当您通过网络发送更复杂的类时,您将不得不处理许多麻烦…
- 序列化和反序列化boost共享指针
- 用 Boost 反序列化犰狳 colvec
- 更改命名空间以自定义 Boost XML 的标记名称后的反序列化问题
- static_assert 在使用 boost 反序列化二进制数据时失败"typex::value"失败
- 从 boost::存档:binary_iarchive 反序列化 std::string 时出现错误的分配异常
- 提升序列化:SIGABRT 同时反序列化包含 std::shared_ptr 的对象上的 boost::shared_p
- Boost:当缺少类型时,如何通过基指针序列化/反序列化泛型类型集合
- 使用Boost序列化和反序列化JSON
- 如何使用boost c++反序列化对和对象的向量
- boost::序列化和循环引用反序列化
- Boost:重新使用/清除text_iarchive以从Asio:receive()中反序列化数据
- 使用 boost::serialize (使用 SSCCE) 反序列化多个值
- 如何通过 C++ boost::序列化执行 std::map 的部分反序列化
- c++ boost::archives and mySql BLOBs,反序列化错误
- 如何使用boost::multiprecision::mpq_rational对具有模板类的映射进行反序列化
- 使用Boost:serialize反序列化指向派生类的指针时出现问题
- 是否可以使用Boost.Hana进行反序列化?
- c++ Boost反序列化what():输入流错误
- 用QT网络序列化和用Boost反序列化
- juce::String的boost反序列化问题,带有XML范围的存档