1 | //
|
---|
2 | // 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 <ctime>
|
---|
12 | #include <iostream>
|
---|
13 | #include <string>
|
---|
14 | #include <boost/bind.hpp>
|
---|
15 | #include <boost/shared_ptr.hpp>
|
---|
16 | #include <boost/enable_shared_from_this.hpp>
|
---|
17 | #include <boost/asio.hpp>
|
---|
18 |
|
---|
19 | using boost::asio::ip::tcp;
|
---|
20 |
|
---|
21 | static std::string make_daytime_string()
|
---|
22 | {
|
---|
23 | using namespace std; // For time_t, time and ctime;
|
---|
24 | time_t now = time(0);
|
---|
25 | return ctime(&now);
|
---|
26 | }
|
---|
27 |
|
---|
28 | class tcp_connection
|
---|
29 | : public boost::enable_shared_from_this<tcp_connection>
|
---|
30 | {
|
---|
31 | public:
|
---|
32 | typedef boost::shared_ptr<tcp_connection> pointer;
|
---|
33 |
|
---|
34 | static pointer create(boost::asio::io_service& io_service)
|
---|
35 | {
|
---|
36 | return pointer(new tcp_connection(io_service));
|
---|
37 | }
|
---|
38 |
|
---|
39 | tcp::socket& socket()
|
---|
40 | {
|
---|
41 | return socket_;
|
---|
42 | }
|
---|
43 |
|
---|
44 | void start()
|
---|
45 | {
|
---|
46 | message_ = make_daytime_string();
|
---|
47 |
|
---|
48 | // Make sure the client logged off.
|
---|
49 | sleep(5);
|
---|
50 |
|
---|
51 | for(int i = 0; i < 4; ++i) {
|
---|
52 | boost::asio::async_write(socket_, boost::asio::buffer(message_),
|
---|
53 | boost::bind(&tcp_connection::handle_write, shared_from_this(),
|
---|
54 | boost::asio::placeholders::error,
|
---|
55 | boost::asio::placeholders::bytes_transferred));
|
---|
56 | }
|
---|
57 | }
|
---|
58 |
|
---|
59 | private:
|
---|
60 | tcp_connection(boost::asio::io_service& io_service)
|
---|
61 | : socket_(io_service)
|
---|
62 | {
|
---|
63 | }
|
---|
64 |
|
---|
65 | void handle_write(boost::system::error_code error,
|
---|
66 | size_t /*bytes_transferred*/)
|
---|
67 | {
|
---|
68 | std::cerr << "Transfer status: " << error.message() << ".\n";
|
---|
69 |
|
---|
70 | if(error) {
|
---|
71 | socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, error);
|
---|
72 | socket_.close(error);
|
---|
73 | }
|
---|
74 | }
|
---|
75 |
|
---|
76 | tcp::socket socket_;
|
---|
77 | std::string message_;
|
---|
78 | };
|
---|
79 |
|
---|
80 | class tcp_server
|
---|
81 | {
|
---|
82 | public:
|
---|
83 | tcp_server(boost::asio::io_service& io_service)
|
---|
84 | : acceptor_(io_service, tcp::endpoint(tcp::v4(), 2013))
|
---|
85 | {
|
---|
86 | start_accept();
|
---|
87 | }
|
---|
88 |
|
---|
89 | private:
|
---|
90 | void start_accept()
|
---|
91 | {
|
---|
92 | tcp_connection::pointer new_connection =
|
---|
93 | tcp_connection::create(acceptor_.io_service());
|
---|
94 |
|
---|
95 | acceptor_.async_accept(new_connection->socket(),
|
---|
96 | boost::bind(&tcp_server::handle_accept, this, new_connection,
|
---|
97 | boost::asio::placeholders::error));
|
---|
98 | }
|
---|
99 |
|
---|
100 | void handle_accept(tcp_connection::pointer new_connection,
|
---|
101 | const boost::system::error_code& error)
|
---|
102 | {
|
---|
103 | if (!error)
|
---|
104 | {
|
---|
105 | new_connection->start();
|
---|
106 | start_accept();
|
---|
107 | }
|
---|
108 | }
|
---|
109 |
|
---|
110 | tcp::acceptor acceptor_;
|
---|
111 | };
|
---|
112 |
|
---|
113 | int main()
|
---|
114 | {
|
---|
115 | try
|
---|
116 | {
|
---|
117 | boost::asio::io_service io_service;
|
---|
118 | tcp_server server(io_service);
|
---|
119 | io_service.run();
|
---|
120 | }
|
---|
121 | catch (std::exception& e)
|
---|
122 | {
|
---|
123 | std::cerr << e.what() << std::endl;
|
---|
124 | }
|
---|
125 |
|
---|
126 | return 0;
|
---|
127 | }
|
---|