The Boost.Asio library does not manage resources and buffers out of the box. So, if we want some simple interface for reading and writing data, the simplest solution would be to tie together the socket and buffer for sending/receiving data. That's what the connection_with_data class does. It holds a boost::asio::ip::tcp::socket, which is a Boost.Asio wrapper around native sockets and a std::string variable that we use as a buffer.
A constructor of the boost::asio::ip::tcp::socket class accepts boost::asio::io_service as almost all the classes in Boost.Asio. After we create a socket, it must be connected to some remote endpoint:
c->socket.connect(boost::asio::ip::tcp::endpoint( boost::asio::ip::address_v4::from_string(addr), ...