0

I'm using boost::asio to create a TCP client. I'm testing it out by loading a web site. I can create a connection, read, have my callback fired, etc, no problem. However, at the of every packet, I'm finding this, or something like it:

ýýýý««««««««îþîþ

I'm wondering how I can determine the size of what was actually read. In the code below, assume my socket is set up properly. I've connected to a URL (a plain old web site), sent a request, and have started reading. When I read the data, I get the data back, plus some extra weirdness.

class TcpClient
{
    ...

    boost::asio::streambuf mResponse;
    std::shared_ptr<boost::asio::ip::tcp::socket> mSocket;

    ...

    void read()
    {
        boost::asio::async_read( *mSocket, mResponse, 
            boost::asio::transfer_at_least( 1 ), 
            boost::bind( &TcpClient::onRead, shared_from_this(), 
                boost::asio::placeholders::error, 
                boost::asio::placeholders::bytes_transferred ) );
    }

    void onRead( const boost::system::error_code& err, size_t bytesTransferred )
    {
        if ( err ) {
            if ( err == boost::asio::error::eof ) {
                cout << "Read complete" << endl;
            } else {
                cout << "Error" << endl;
            }
        } else {
            char* data = new char[ bytesTransferred ];
            istream stream( &mResponse );
            stream.read( data, bytesTransferred );

            cout  << data << endl;

            delete [] data;
            read();
        }
        mResponse.consume( mResponse.size() );
    }

    ...

};

Below is the result of the first packet I receive from http://libcinder.org.

HTTP/1.1 200 OK
Server: nginx/0.5.33
Date: Fri, 24 May 2013 01:05:55 GMT
Content-Type: text/html; charset=utf-8
Connection: close
Vary: Cookie

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>Cinder | The library for professional-quality creative coding in C++</title>

    <meta name="Descýýýý««««««««îþîþ
Sam Miller
  • 23,808
  • 4
  • 67
  • 87
BTR
  • 4,880
  • 4
  • 24
  • 21
  • 2
    Try the following: `char* data = new char[ bytesTransferred + 1]; data[bytesTransferred] = 0; //etc...` Does it help? – Igor R. May 24 '13 at 12:39
  • Ding, ding, ding! We have a a winner. Yeah, I've been looking at this code too long to think to initialize the value of the array. I was hoping to be able to reconcile any discrepancy between the response buffer's size and bytesTransferred argument, but alas, that is too much to ask... Thanks so much! – BTR May 24 '13 at 17:31

1 Answers1

0

Answer came via Igor R.

This...

char* data = new char[ bytesTransferred ];

...should be...

char* data = new char[ bytesTransferred + 1 ];
data[ bytesTransferred ] = 0;
BTR
  • 4,880
  • 4
  • 24
  • 21
  • Note that you don't need to read the data from `asio::streambuf` this way. Just access it directly: `const char* data = asio::buffer_cast(mResponse.data());` – Igor R. May 25 '13 at 17:40