Skip to content

Instantly share code, notes, and snippets.

@cyberinferno
Created November 25, 2021 04:54
Show Gist options
  • Save cyberinferno/0cba1d6937ce8923a77b92e455ea0df5 to your computer and use it in GitHub Desktop.
Save cyberinferno/0cba1d6937ce8923a77b92e455ea0df5 to your computer and use it in GitHub Desktop.
Boost Asio TCP server and client
#include <boost/asio.hpp>
class TcpServer
{
public:
TcpServer(boost::asio::io_service& io_service, short port)
: acceptor_(io_service, tcp::endpoint(tcp::v4(), port))
{
StartAccept();
}
void StartAccept()
{
TcpConnection::pointer new_connection = TcpConnection::Create(acceptor_.get_io_service());
acceptor_.async_accept(new_connection->Socket(),
boost::bind(&TcpServer::HandleAccept, this, new_connection,
boost::asio::placeholders::error));
}
void HandleAccept(TcpConnection::pointer new_connection,
const boost::system::error_code& error)
{
if (!error)
{
new_connection->Start();
}
StartAccept();
}
tcp::acceptor acceptor_;
};
class TcpConnection
{
public:
static TcpConnection::pointer Create(boost::asio::io_service& io_service)
{
return TcpConnection::pointer(new TcpConnection(io_service));
}
void Start()
{
boost::asio::async_read(Socket(),
boost::asio::buffer(data_, max_length),
boost::bind(&TcpConnection::HandleRead, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void HandleRead(const boost::system::error_code& error,
size_t bytes_transferred)
{
if (!error)
{
boost::asio::async_write(Socket(),
boost::asio::buffer(data_, bytes_transferred),
boost::bind(&TcpConnection::HandleWrite, this,
boost::asio::placeholders::error));
}
else
{
delete this;
}
}
void HandleWrite(const boost::system::error_code& error)
{
if (!error)
{
Start();
}
else
{
delete this;
}
}
tcp::socket Socket()
{
return socket_;
}
enum { max_length = 1024 };
char data_[max_length];
TcpConnection(boost::asio::io_service& io_service)
: socket_(io_service)
{
}
tcp::socket socket_;
};
class TcpClient
{
public:
TcpClient(boost::asio::io_service& io_service, const std::string& server, short port)
: io_service_(io_service),
socket_(io_service)
{
tcp::resolver resolver(io_service);
tcp::resolver::query query(server, boost::lexical_cast<std::string>(port));
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
boost::asio::connect(socket_, endpoint_iterator);
Start();
}
void Start()
{
boost::asio::async_write(socket_,
boost::asio::buffer(request_),
boost::bind(&TcpClient::HandleWrite, this,
boost::asio::placeholders::error));
}
void HandleWrite(const boost::system::error_code& error)
{
if (!error)
{
boost::asio::async_read(socket_,
boost::asio::buffer(reply_),
boost::bind(&TcpClient::HandleRead, this,
boost::asio::placeholders::error));
}
}
void HandleRead(const boost::system::error_code& error)
{
if (!error)
{
std::cout.write(reply_.data(), reply_.size());
std::cout << std::endl;
}
}
boost::asio::io_service& io_service_;
tcp::socket socket_;
std::string request_;
boost::array<char, 1024> reply_;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment