Question

In a first time i want to thanks HostileFork to help me to explain my problem. Thanks you !

i'm trying to build a client and a server who send their data through a binary protocol.

my problem is i want to send a class from a QT client to a Boost Server. My header(one integer who is the size of my class) is writting on the socket. When i want to read the header on the server side, i can't get the good integer(instead of that i have an big number like -13050660). I think that the problem come to the deserialization on the server but i am not sure.

This is the technique that my Qt client code uses to write the number 10 to onto a socket:

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;

Then I try to read it on a server process, which uses boost's 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)
);

Here's the function that operates on the string result:

#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;
    }
}

I do get the 32-bit signed integer (4 bytes), but it is not ten, instead it is something like -1163005939. Anyone have and ideas why this is not working?

The server and the client are both on launching on Windows7 pro, 64-bit.

Was it helpful?

Solution

You're welcome...and thanks for following my suggestions on editing the question, and doing the requisite effort to pinpoint the problem more clearly. So now I can tell you what's wrong. :)

The behavior of the << and >> are different on QDataStream than on C++ standard IOstreams. In the world of classes like std::stringstream these operators are called "inserters"/"extractors" and are intended for dealing with information formatted as text. If you want to read a certain number of bytes into a memory address, what you'll want is:

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

(Note that if you wish to read binary data out of something that is not a stringstream, you need to be using ios::binary to keep it from messing with line ending conversions)

QDataStream doesn't follow that convention...it's a good helper for binary data. Nothing wrong with that...since abstractly speaking the << and >> operators are available in the language to be overloaded to do whatever you want within your own class hierarchies. Qt was free to define its own semantics for its own streams, and they did.

Do heed the advice given by @vitakot about (if possible) using the same methodology for both input and output. Also heed my warning about byte-ordering issues that start to come up if you aren't careful.

(Good news is that if you are using QDataStream it finesses this issue by taking care of it for you.)

Be aware that in your code as written, your stringstream is making a copy of the buffer in order to read from it. I'm not experienced with boost::asio or the best practices of async_read, but I'm sure there are better ways you might dig around and find.

OTHER TIPS

HostileFork is right, from the information we have it is not possible to isolate a bug in your code.

However, I would suggest you to use boost serialization in your Qt client as well. There is no reason to not combine Boost and Qt libraries. Otherwise you will have to deal with a lot of troubles when sending more complicated classes over the network...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top