// required for Solaris to select the std conforming // version of ctime_r #define _POSIX_PTHREAD_SEMANTICS #include #include #include #include #include #include #include /* partly based on an example at * http://www.boost.org/doc/libs/1_46_1/doc/html/boost_asio/tutorial/tutdaytime3/src.html by Christopher M. Kohlhoff */ using boost::asio::ip::tcp; using namespace std; char* cmdname; void usage() { cerr << "Usage: " << cmdname << " port" << endl; exit(1); } class TimeServerSession; typedef boost::shared_ptr TimeServerSessionPtr; class TimeServerSession: public boost::enable_shared_from_this { public: static TimeServerSessionPtr create(boost::asio::io_service& io_service) { return TimeServerSessionPtr(new TimeServerSession(io_service)); } tcp::socket& socket() { return my_socket; } void start() { char timebuf[32]; time_t clock; time(&clock); ctime_r(&clock, timebuf); message = timebuf; boost::asio::async_write(my_socket, boost::asio::buffer(message), boost::bind(&TimeServerSession::handle_write, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } private: TimeServerSession(boost::asio::io_service& io_service) : my_socket(io_service) { } void handle_write(const boost::system::error_code& error, size_t nbytes) { } tcp::socket my_socket; std::string message; }; template class Server { public: template Server(boost::asio::io_service& io_service, Endpoint endpoint) : acceptor(io_service, endpoint) { acceptor.set_option( boost::asio::ip::tcp::acceptor::reuse_address(true)); start_accept(); } private: typedef boost::shared_ptr SessionPtr; void start_accept() { SessionPtr session = Session::create(acceptor.get_io_service()); acceptor.async_accept(session->socket(), boost::bind(&Server::handle_accept, this, session, boost::asio::placeholders::error)); } void handle_accept(SessionPtr session, const boost::system::error_code& error) { if (!error) { session->start(); start_accept(); } } tcp::acceptor acceptor; }; int main(int argc, char* argv[]) { // process command line arguments cmdname = *argv++; --argc; if (argc != 1) usage(); unsigned int port(atoi(argv[0])); try { boost::asio::io_service io_service; Server server(io_service, tcp::endpoint(tcp::v4(), port)); io_service.run(); } catch (exception& e) { cerr << cmdname << ": " << e.what() << endl; } }