// // async_dccp_echo_server.cpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include #include #include #include #include #include "dccp.hpp" using boost::asio::ip::dccp; using namespace std; class session { public: session(boost::asio::io_service& io_service) : socket_(io_service) { } dccp::socket& socket() { return socket_; } void start() { { boost::asio::dccp_option::cur_mps option; socket_.get_option(option); cout << "got mps: " << option.value() << endl; data_.resize(option.value()); } { boost::asio::dccp_option::service option; socket_.get_option(option); cout << "got service: " << option[0] << endl; } socket_.async_receive(boost::asio::buffer(data_), boost::bind(&session::handle_receive, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } void handle_receive(const boost::system::error_code& error, size_t bytes_transferred) { if (!error) { socket_.async_send(boost::asio::buffer(data_, bytes_transferred), boost::bind(&session::handle_send, this, boost::asio::placeholders::error)); } else delete this; } void handle_send(const boost::system::error_code& error) { if (!error) { socket_.async_receive(boost::asio::buffer(data_), boost::bind(&session::handle_receive, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } else delete this; } private: dccp::socket socket_; vector data_; }; class server { public: server(boost::asio::io_service& io_service, short port, const vector &srv_codes = vector()) : io_service_(io_service), acceptor_(io_service, dccp::endpoint(dccp::v4(), port, srv_codes)) { session *new_session = new session(io_service_); acceptor_.async_accept(new_session->socket(), boost::bind(&server::handle_accept, this, new_session, boost::asio::placeholders::error)); } void handle_accept(session* new_session, const boost::system::error_code& error) { if (!error) { new_session->start(); new_session = new session(io_service_); acceptor_.async_accept(new_session->socket(), boost::bind(&server::handle_accept, this, new_session, boost::asio::placeholders::error)); } else delete new_session; } private: boost::asio::io_service& io_service_; dccp::acceptor acceptor_; }; int main(int argc, char* argv[]) { using namespace boost::program_options; options_description desc; desc.add_options() ("help", "produce help message") ("port", value()->default_value(7777), "Port number to listen on") ("sc", value >(), "Service code(s) to listen on"); variables_map vm; try { store(parse_command_line(argc, argv, desc), vm); } catch (error &err) { cout << err.what() << endl; return 1; } notify(vm); if (vm.count("help")) { cout << desc; return 0; } try { vector s_codes; try { s_codes = vm["sc"].as >(); } catch (boost::bad_any_cast &e) { cerr << e.what() << endl; s_codes.push_back(0x30304953); } boost::asio::io_service io_service; server s(io_service, vm["port"].as(), s_codes); io_service.run(); } catch (std::exception &e) { cerr << "Exception: " << e.what() << "\n"; } return 0; }