I'm new in coding boost asio and asynchronous TCP socket data transfer.
I've been stopped in sending multiple messages from client to server because my server accepts only one message. I tried to follow solution here to call another async_read_some
in my handler_read
method but still cannot get second message from a client to get accepted by server.
I provided some server side code here. Of course some unnecessary parts have been removed.
class ConnectionHandler : public boost::enable_shared_from_this<ConnectionHandler> {
private:
tcp::socket _Socket;
string _Message = "Message From Server!\n";
char _Data[1024];
public:
typedef boost::shared_ptr<ConnectionHandler> pointer;
ConnectionHandler(boost::asio::io_service& io_service)
:
_Socket { io_service }, _Data { 0 }
{}
static pointer Create(boost::asio::io_service& io_service)
{
return pointer(new ConnectionHandler(io_service));
}
tcp::socket& Socket()
{
return _Socket;
}
void Start()
{
_Socket.async_read_some(boost::asio::buffer(_Data, 1024),boost::bind(&ConnectionHandler::handle_read,shared_from_this(),boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
_Socket.async_write_some(boost::asio::buffer(_Message, 1024),boost::bind(&ConnectionHandler::handle_write,shared_from_this(),boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
}
void handle_read(const boost::system::error_code& error, std::size_t bytes_transferred)
{
if (!error)
{
cout << _Data << endl;
_Socket.async_read_some(boost::asio::buffer(_Data, 1024),boost::bind(&ConnectionHandler::handle_read,shared_from_this(),boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
}
}
class Server {
private:
tcp::acceptor Acceptor;
void StartAccept()
{
// socket
ConnectionHandler::pointer connection = ConnectionHandler::Create((boost::asio::io_context&)(Acceptor).get_executor().context());
// asynchronous accept operation
Acceptor.async_accept(connection->Socket(), boost::bind(&Server::handle_accept, this, connection, boost::asio::placeholders::error));
}
public:
// constructor for accepting connection from client
Server(boost::asio::io_service& io_service)
:
Acceptor{ io_service, tcp::endpoint(tcp::v4(), 1234) }
{
StartAccept();
}
void handle_accept(ConnectionHandler::pointer connection, const boost::system::error_code& error)
{
if (!error)
connection->Start();
StartAccept();
}
};
int main()
{
try
{
boost::asio::io_service io_service;
Server server(io_service);
io_service.run();
}
catch(exception& e)
{
cerr << e.what() << endl;
}
return 0;
}