Сериализация с сетью QT и десериализация с Boost

В первый раз я хочу поблагодарить HostileFork, чтобы помочь мне объяснить мою проблему. Спасибо вам!

Я пытаюсь создать клиент и сервер, которые отправляют свои данные через двоичный протокол.

Моя проблема в том, что я хочу отправить класс от клиента QT на Boost Server. Мой заголовок (одно целое число размером с мой класс) записывает в сокет. Когда я хочу прочитать заголовок на стороне сервера, я не могу получить хорошее целое число (вместо этого у меня есть большое число, например -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;

Затем я пытаюсь прочитать его на серверном процессе, который использует метод 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 байта), но это не десять, а что-то вроде -1163005939. У кого-нибудь есть и идеи, почему это не работает?

Сервер и клиент одновременно запускаются на 64-битной Windows7 pro.

2 ответа

Решение

Не за что... и спасибо за то, что следовали моим предложениям по редактированию вопроса и приложили необходимые усилия для более четкого определения проблемы. Так что теперь я могу сказать вам, что не так.:)

Поведение << а также >> разные по QDataStream чем на C++ стандартных IOstreams. В мире таких классов, как std::stringstream Эти операторы называются "вставками"/"экстракторами" и предназначены для работы с информацией, отформатированной в виде текста. Если вы хотите прочитать определенное количество байтов в адрес памяти, вам нужно:

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

(Обратите внимание, что если вы хотите читать двоичные данные из чего-то, что не является потоком строк, вам нужно использовать ios::binary, чтобы не допустить путаницы с преобразованиями, заканчивающимися на конец строки)

QDataStream не следует этому соглашению... это хороший помощник для двоичных данных. Ничего плохого в этом нет... так как << а также >> операторы доступны на языке, который может быть перегружен, чтобы делать все, что вы хотите в вашей собственной иерархии классов. Qt был свободен в определении собственной семантики для своих потоков, и они это сделали.

Прислушайтесь к совету, данному @vitakot (если возможно), используя одну и ту же методологию для ввода и вывода. Также обратите внимание на мое предупреждение о проблемах с порядком байтов, которые начинают появляться, если вы не будете осторожны.

(Хорошая новость в том, что если вы используете QDataStream это решает эту проблему, заботясь об этом для вас.)

Имейте в виду, что в вашем написанном коде ваш поток строк создает копию буфера для чтения из него. Я не опытный с boost::asio или лучшие практики async_read, но я уверен, что есть лучшие способы, которые вы можете найти и найти.

HostileFork прав, из имеющейся у нас информации невозможно выделить ошибку в вашем коде.

Однако я бы посоветовал вам также использовать сериализацию Boost в вашем Qt-клиенте. Нет причин не объединять библиотеки Boost и Qt. В противном случае вам придется столкнуться с множеством проблем при отправке более сложных классов по сети...

Другие вопросы по тегам