1

我第一次要感谢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, '\0'); // 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 位上启动。

4

2 回答 2

1

不客气……感谢您遵循我关于编辑问题的建议,并尽一切努力更清楚地查明问题。所以现在我可以告诉你出了什么问题。:)

和的行为与<<C ++ 标准 IO 流>>不同QDataStream。在类的世界中,std::stringstream这些运算符被称为“插入器”/“提取器”,旨在处理格式化为 text的信息。如果您想将一定数量的字节读入内存地址,您需要的是:

http://www.cplusplus.com/reference/iostream/istream/read/

(请注意,如果您希望从非字符串流中读取二进制数据,则需要使用 ios::binary以防止其与行尾转换混淆)

QDataStream不遵循该约定...它是二进制数据的好帮手。这并没有错……因为抽象地说,<<and>>运算符可以在语言中被重载以在你自己的类层次结构中做任何你想做的事情。Qt 可以自由地为自己的流定义自己的语义,而且他们确实做到了。

请注意@vitakot 给出的关于(如果可能的话)对输入和输出使用相同方法的建议。如果您不小心,请注意我对开始出现的字节排序问题的警告。

(好消息是,如果您使用它,可以通过为您处理它来QDataStream解决这个问题。)

请注意,在您编写的代码中,您的 stringstream 正在制作缓冲区的副本以便从中读取。我没有经验boost::asio或最佳实践async_read,但我相信你可以挖掘并找到更好的方法。

于 2011-11-21T21:56:47.373 回答
0

HostileFork 是对的,从我们掌握的信息来看,不可能在您的代码中找出错误。

但是,我建议您在 Qt 客户端中也使用 boost 序列化。没有理由不结合 Boost 和 Qt 库。否则在通过网络发送更复杂的类时,您将不得不处理很多麻烦......

于 2011-11-21T22:13:59.973 回答