Skip to content

Instantly share code, notes, and snippets.

@malustewart
Created April 9, 2020 02:20
Show Gist options
  • Save malustewart/fb1b7c93dc3a240e0faf32872f97c1d8 to your computer and use it in GitHub Desktop.
Save malustewart/fb1b7c93dc3a240e0faf32872f97c1d8 to your computer and use it in GitHub Desktop.
Asynchronous Daytime Server using boost-asio

Asynchronous TCP Daytime Server

Based on this asynchronous daytime server example from the Boost-Asio documentation.

Example use:

    	try
	{
		boost::asio::io_context io_context;
		AsyncDaytimeServer s(io_context);
		s.start();
		io_context.run();
	}
	catch (std::exception& e)
	{
		std::cerr << e.what() << std::endl;
	}

Example tested with this daytime client example from the Boost-Asio documentation, using localhost and private IP.

#include "AsyncDaytimeServer.h"
#include <iostream>
#include <string>
#include <boost\bind.hpp>
using boost::asio::ip::tcp;
std::string make_daytime_string();
AsyncDaytimeServer::AsyncDaytimeServer(boost::asio::io_context& io_context)
: context_(io_context),
acceptor_(io_context, tcp::endpoint(tcp::v4(), 13)),
socket_(io_context)
{
}
AsyncDaytimeServer::~AsyncDaytimeServer()
{
}
void AsyncDaytimeServer::start()
{
if (socket_.is_open())
{
socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
socket_.close();
}
wait_connection();
}
void AsyncDaytimeServer::wait_connection()
{
std::cout << "wait_connection()" << std::endl;
if (socket_.is_open())
{
std::cout << "Error: Can't accept new connection from an open socket" << std::endl;
return;
}
acceptor_.async_accept(
socket_,
boost::bind(
&AsyncDaytimeServer::connection_received_cb,
this,
boost::asio::placeholders::error
)
);
}
void AsyncDaytimeServer::answer()
{
std::cout << "answer()" << std::endl;
msg = make_daytime_string();
boost::asio::async_write(
socket_,
boost::asio::buffer(msg),
boost::bind(
&AsyncDaytimeServer::response_sent_cb,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
socket_.close();
}
void AsyncDaytimeServer::connection_received_cb(const boost::system::error_code& error)
{
std::cout << "connection_received_cb()" << std::endl;
if (!error) {
answer();
wait_connection();
}
else {
std::cout << error.message() << std::endl;
}
}
void AsyncDaytimeServer::response_sent_cb(const boost::system::error_code& error,
size_t bytes_sent)
{
std::cout << "response_sent_cb()" << std::endl;
if (!error) {
std::cout << "Response sent. " << bytes_sent << " bytes." << std::endl;
}
}
std::string make_daytime_string()
{
#pragma warning(disable : 4996)
using namespace std; // For time_t, time and ctime;
time_t now = time(0);
return ctime(&now);
}
#pragma once
/*
Asynchronous TCP Daytime Server
Based on:
https://www.boost.org/doc/libs/1_72_0/doc/html/boost_asio/tutorial/tutdaytime3/src.html
Example use:
boost::asio::io_context io_context;
AsyncDaytimeServer s(io_context);
s.start();
io_context.run();
Tested with client from:
https://www.boost.org/doc/libs/1_72_0/doc/html/boost_asio/tutorial/tutdaytime1/src.html
*/
#include <boost\asio.hpp>
#include <string>
class AsyncDaytimeServer
{
public:
AsyncDaytimeServer(boost::asio::io_context& context);
~AsyncDaytimeServer();
void start();
private:
void wait_connection();
void answer();
void connection_received_cb(const boost::system::error_code& error);
void response_sent_cb(const boost::system::error_code& error, size_t bytes_sent);
std::string msg;
boost::asio::io_context& context_;
boost::asio::ip::tcp::socket socket_;
boost::asio::ip::tcp::acceptor acceptor_;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment