-
Notifications
You must be signed in to change notification settings - Fork 10
/
server.cpp
107 lines (88 loc) · 2.64 KB
/
server.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
//
// server.cpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2011 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 "server.hpp"
#include <boost/asio/write.hpp>
#include "yield.hpp"
namespace awesome {
using boost::asio::ip::tcp;
server::server(
const std::string& listen_address, const std::string& listen_port,
const std::string& target_address, const std::string& target_port)
: io_service_(std::make_shared<boost::asio::io_service>()),
resolver_(std::make_shared<tcp::resolver>(*io_service_)),
acceptor_(std::make_shared<tcp::acceptor>(*io_service_,
*resolver_->resolve({listen_address, listen_port}))),
up_endpoint_(*resolver_->resolve({target_address, target_port})),
allocator_(std::make_shared<allocator>())
{
}
server::server(const server& other)
: coroutine(other),
io_service_(other.io_service_),
resolver_(other.resolver_),
acceptor_(other.acceptor_),
up_endpoint_(other.up_endpoint_),
socket1_(other.socket1_),
socket2_(other.socket2_),
buffer_(other.buffer_),
allocator_(other.allocator_)
{
std::cout << "COPY" << std::endl;
}
void server::operator()(boost::system::error_code ec, std::size_t length)
{
reenter (this)
{
fork server(*this)();
if (is_parent())
{
io_service_->run();
return;
}
do
{
socket1_ = std::make_shared<tcp::socket>(*io_service_);
yield acceptor_->async_accept(*socket1_, std::move(*this));
if (!ec) fork server(*this)();
} while (is_parent());
std::cout << "connection::start()" << std::endl;
allocator_ = std::make_shared<allocator>();
socket2_ = std::make_shared<tcp::socket>(*io_service_);
yield socket2_->async_connect(up_endpoint_, std::move(*this));
if (!ec)
{
fork server(*this)();
buffer_ = std::make_shared<std::array<unsigned char, 1024>>();
if (is_child())
{
allocator_ = std::make_shared<allocator>();
std::swap(socket1_, socket2_);
}
while (!ec)
{
yield socket1_->async_read_some(
boost::asio::buffer(*buffer_), std::move(*this));
if (!ec)
{
yield boost::asio::async_write(*socket2_,
boost::asio::buffer(*buffer_, length), std::move(*this));
}
}
}
if (socket1_->is_open() || socket2_->is_open())
{
std::cout << "connection::stop()" << std::endl;
socket1_->close(ec);
socket2_->close(ec);
}
}
}
} // namespace awesome
#include "unyield.hpp"