File: networking.C

package info (click to toggle)
ball 1.5.0%2Bgit20180813.37fc53c-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 239,848 kB
  • sloc: cpp: 326,149; ansic: 4,208; python: 2,303; yacc: 1,778; lex: 1,099; xml: 958; sh: 322; makefile: 93
file content (142 lines) | stat: -rw-r--r-- 2,513 bytes parent folder | download | duplicates (4)
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//

#include <boost/bind.hpp>
#include <BALL/SYSTEM/networking.h>

namespace BALL
{
	TCPServer::~TCPServer()
	{
	}

	void TCPServer::activate()
	{
		acceptor_.open(boost::asio::ip::tcp::v4());
		acceptor_.bind(boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port_));

		if (port_ == 0)
			port_ = acceptor_.local_endpoint().port();

		acceptor_.listen();
		startAccepting();

		// when the first accept returned, we have to decide whether
		// to keep accepting connections
		while (restart_)
			startAccepting();
	}

	void TCPServer::deactivate()
	{
		acceptor_.close();
	}

	void TCPServer::startAccepting()
	{
		connected_stream_.close();
		acceptor_.accept(*connected_stream_.rdbuf());

		handleConnection();
	}

	void TCPServer::handleConnection()
	{
	}

	// not needed as long as we do this synchronously
	void TCPServer::connectionRequested()
	{
		if (restart_)
			startAccepting();
	}

	void TCPServer::setPort(Size port)
	{
		port_ = port;
	}

	Size TCPServer::getPort() const
	{
		return port_;
	}

	TCPServerThread::TCPServerThread(Size port, bool asynchronous, bool restart)
		: QThread(),
			TCPServer(port, restart),
			use_async_io_(asynchronous),
			is_running_(false)
	{
	}

	void TCPServerThread::run()
	{
		if (!use_async_io_)
			activate();
		else
		{
			try 
			{
				acceptor_.open(boost::asio::ip::tcp::v4());
				acceptor_.bind(boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port_));

				if (port_ == 0)
					port_ = acceptor_.local_endpoint().port();

				acceptor_.listen();

				is_running_ = true;

				activate_async();

				while (restart_ && is_running_)
				{
					activate_async();
				}
			} 
			catch (std::exception& e)
			{
				Log.error() << "Could not start server!" << std::endl;
				Log.error() << "Reason given was " << e.what() << std::endl;

				is_running_ = false;
			}
		}
	}

	void TCPServerThread::deactivate()
	{
		is_running_ = false;
		io_service_.post(boost::bind(&TCPServerThread::handleClose, this));
	}

	void TCPServerThread::handleClose()
	{
		acceptor_.close();
		connected_stream_.close();
		io_service_.stop();
	}

	void TCPServerThread::activate_async()
	{
		connected_stream_.close();

		acceptor_.async_accept(*connected_stream_.rdbuf(),
			boost::bind(&TCPServerThread::handleAsyncConnection, this));

		io_service_.run();
		io_service_.reset();
	}

	void TCPServerThread::handleAsyncConnection()
	{
	}

	bool TCPServerThread::isRunning()
	{
		return is_running_;
	}
}