0
votes

I try to use the iostream class from boost ASIO to read binary data from a TCP socket. I use the standard extraction operator (operator>>) to read data from the stream. The environment I use is Visual Studio 2010. The problem is that when I read the stream it seems that the stream tries to parse the binary data as a string. At least this is what I have seens as I have debugged into the code.

Is there a way that I could use the iostream to read it as a binary stream and not as a string stream?

boost::asio::io_service dataServer;

boost::asio::ip::tcp::endpoint dataServerEndpoint(boost::asio::ip::tcp::v4(), dataServerPort);
boost::asio::ip::tcp::acceptor acceptor(dataServer, dataServerEndpoint);

boost::asio::ip::tcp::iostream dataServerStream;
acceptor.accept(*dataServerStream.rdbuf());

try
{
    vector<char> lineBuffer;

    while (!dataServerStream.eof())
    {

        bool eof = dataServerStream.eof();
        bool bad = dataServerStream.bad();
        bool fail = dataServerStream.fail();
        bool good = dataServerStream.good();

        uint64_t magic;
        dataServerStream >> magic;

So instead of just taking 8 bytes from stream and move it into the "magic" variable, it tries to parse the stream to get a valid stringified number. This of course fails and the fail bit will be set.

1

1 Answers

3
votes

The input operator >> is expecting the input to be text, that is then converted to the correct data-type. As you can expect this will not work well with binary data.

You should be using read instead:

uint64_t magic;
dataServerStream.read(reinterpret_cast<char*>(&magic), sizeof(magic));

You also make a very common beginner mistake, in that you loop while (!eof). This will not work as the eof flag is not set until after you try an input operation. This means you will iterate once to many.

Instead do e.g.

uint64_t magic;
while (dataServerStream.read(reinterpret_cast<char*>(&magic), sizeof(magic)))
{
    // Read the rest
}