Ticket #3131: async_dccp_echo_server.cpp

File async_dccp_echo_server.cpp, 3.7 KB (added by oakad@…, 13 years ago)
Line 
1//
2// async_dccp_echo_server.cpp
3// ~~~~~~~~~~~~~~~~~~~~~~~~~
4//
5// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6//
7// Distributed under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9//
10
11#include <cstdlib>
12#include <iostream>
13#include <boost/bind.hpp>
14#include <boost/asio.hpp>
15#include <boost/program_options.hpp>
16
17#include "dccp.hpp"
18
19using boost::asio::ip::dccp;
20using namespace std;
21
22class session
23{
24public:
25 session(boost::asio::io_service& io_service)
26 : socket_(io_service)
27 {
28 }
29
30 dccp::socket& socket()
31 {
32 return socket_;
33 }
34
35 void start()
36 {
37 {
38 boost::asio::dccp_option::cur_mps option;
39 socket_.get_option(option);
40 cout << "got mps: " << option.value() << endl;
41 data_.resize(option.value());
42 }
43
44 {
45 boost::asio::dccp_option::service option;
46 socket_.get_option(option);
47 cout << "got service: " << option[0] << endl;
48 }
49
50 socket_.async_receive(boost::asio::buffer(data_),
51 boost::bind(&session::handle_receive, this,
52 boost::asio::placeholders::error,
53 boost::asio::placeholders::bytes_transferred));
54 }
55
56 void handle_receive(const boost::system::error_code& error,
57 size_t bytes_transferred)
58 {
59 if (!error) {
60 socket_.async_send(boost::asio::buffer(data_, bytes_transferred),
61 boost::bind(&session::handle_send,
62 this,
63 boost::asio::placeholders::error));
64 } else
65 delete this;
66 }
67
68 void handle_send(const boost::system::error_code& error)
69 {
70 if (!error) {
71 socket_.async_receive(boost::asio::buffer(data_),
72 boost::bind(&session::handle_receive,
73 this,
74 boost::asio::placeholders::error,
75 boost::asio::placeholders::bytes_transferred));
76 } else
77 delete this;
78 }
79
80private:
81 dccp::socket socket_;
82 vector<char> data_;
83};
84
85class server
86{
87public:
88 server(boost::asio::io_service& io_service, short port,
89 const vector<unsigned int> &srv_codes = vector<unsigned int>())
90 : io_service_(io_service),
91 acceptor_(io_service,
92 dccp::endpoint(dccp::v4(), port, srv_codes))
93 {
94 session *new_session = new session(io_service_);
95
96 acceptor_.async_accept(new_session->socket(),
97 boost::bind(&server::handle_accept, this, new_session,
98 boost::asio::placeholders::error));
99 }
100
101 void handle_accept(session* new_session,
102 const boost::system::error_code& error)
103 {
104 if (!error) {
105 new_session->start();
106 new_session = new session(io_service_);
107 acceptor_.async_accept(new_session->socket(),
108 boost::bind(&server::handle_accept,
109 this, new_session,
110 boost::asio::placeholders::error));
111 } else
112 delete new_session;
113 }
114
115private:
116 boost::asio::io_service& io_service_;
117 dccp::acceptor acceptor_;
118};
119
120int main(int argc, char* argv[])
121{
122 using namespace boost::program_options;
123
124 options_description desc;
125 desc.add_options()
126 ("help", "produce help message")
127 ("port", value<unsigned short>()->default_value(7777),
128 "Port number to listen on")
129 ("sc", value<vector<unsigned int> >(),
130 "Service code(s) to listen on");
131
132 variables_map vm;
133
134 try {
135 store(parse_command_line(argc, argv, desc), vm);
136 } catch (error &err) {
137 cout << err.what() << endl;
138 return 1;
139 }
140
141 notify(vm);
142
143 if (vm.count("help")) {
144 cout << desc;
145 return 0;
146 }
147
148 try {
149 vector<unsigned int> s_codes;
150 try {
151 s_codes = vm["sc"].as<vector<unsigned int> >();
152 } catch (boost::bad_any_cast &e) {
153 cerr << e.what() << endl;
154 s_codes.push_back(0x30304953);
155 }
156
157 boost::asio::io_service io_service;
158 server s(io_service, vm["port"].as<unsigned short>(), s_codes);
159
160 io_service.run();
161 } catch (std::exception &e) {
162 cerr << "Exception: " << e.what() << "\n";
163 }
164
165 return 0;
166}