tags:

views:

440

answers:

3

Hi,

i made a socket app that uses boost asio how ever it seems to take a lot of cpu when i try to read any thing from the socket.

Atm i use a wrapper class so i dont have to expose the boost header files in my header file that looks something like this:

class SocketHandle
{
public:
    SocketHandle()
    {
     m_pSocket = NULL;
     m_pService = NULL;
    }

    ~SocketHandle()
    {
     delete m_pSocket;
     delete m_pService;
    }

    void connect(const char* host, const char* port)
    {
     if (m_pSocket || m_pService)
      return;

     m_pService = new boost::asio::io_service();

     tcp::resolver resolver(*m_pService);
     tcp::resolver::query query(tcp::v4(), host, port);
     tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
     tcp::resolver::iterator end;

     m_pSocket = new tcp::socket(*m_pService);

     boost::system::error_code error = boost::asio::error::host_not_found;

     while (error && endpoint_iterator != end)
     {
      (*m_pSocket).close();
      (*m_pSocket).connect(*endpoint_iterator++, error);
     }

     if (error)
      throw ...
    }

    tcp::socket* operator->()
    {
     return m_pSocket;
    }

private:
     tcp::socket *m_pSocket;
     boost::asio::io_service *m_pService;
};

and then im reading from the socket like so:

size_t recv(char *data, size_t size)
{
    boost::system::error_code error;
    size_t len = (*m_pSocket)->read_some(boost::asio::buffer(data, size), error);

    if (error)
               throw ...

    return len;
}

Am i doing something wrong? Is there a better way to read data from the socket?

Boost 1.39.0 visual c++ windows

+1  A: 

You should avoid the tight while loop:

// BAD.
while (error && endpoint_iterator != end)
{
    (*m_pSocket).close();
    (*m_pSocket).connect(*endpoint_iterator++, error);
}

Instead try something like:

try
{
    (*m_pSocket).connect(*endpoint_iterator++, error);
    // ...
}
catch (std::exception& ex)
{
    // Release resources, then try connecting again.
}

Also see these examples at for the right idioms of using Asio.

Vijay Mathew
That was from the boost asio example :P
Lodle
But the problem is with the read not the connect code.
Lodle
A: 

Consider using the free function instead,

size_t len = asio::read(*m_pSocket,asio::buffer(data, size), error);
imran.fanaswala
A: 

A change you may wish to consider (and I highly recommend) is to make your socket calls asynchronous. That way you don't have to worry about threads being blocked or any socket calls spinning internally (which I suspect may be what you're seeing). Instead, you simply provide a callback that will receive any errors and the number of bytes received.

There are plenty of examples in the Boost docs that illustrate how to do this, and I've found that it lends itself to a much more efficient use of threads and processor resources.

Brian