44 static std::shared_ptr<RUDICSConnection>
create(
45 const boost::asio::ip::tcp::socket::executor_type& executor)
50 boost::asio::ip::tcp::socket&
socket() {
return socket_; }
54 remote_endpoint_str_ = boost::lexical_cast<std::string>(socket_.remote_endpoint());
60 socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
66 boost::asio::async_read_until(socket_, buffer_,
'\r',
67 boost::bind(&RUDICSConnection::handle_read,
this,
68 boost::placeholders::_1,
69 boost::placeholders::_2));
74 boost::asio::async_write(socket_, boost::asio::buffer(data),
75 boost::bind(&RUDICSConnection::handle_write,
this,
76 boost::placeholders::_1, boost::placeholders::_2));
83 glog.
is(DEBUG1) &&
glog <<
"Disconnecting from: " << remote_endpoint_str_ << std::endl;
90 const int max_packet_failures = 3;
91 if (++packet_failures_ >= max_packet_failures)
93 glog.
is(DEBUG1) &&
glog <<
"More than " << max_packet_failures <<
" bad RUDICS packets."
99 boost::signals2::signal<void(
const std::string& line,
100 std::shared_ptr<RUDICSConnection> connection)>
108 const boost::asio::ip::tcp::socket::executor_type& executor)
109 : socket_(executor), remote_endpoint_str_(
"Unknown"), packet_failures_(0)
113 void handle_write(
const boost::system::error_code& error,
size_t bytes_transferred)
119 glog.
is(WARN) &&
glog <<
"Error writing to TCP connection: " << error << std::endl;
124 void handle_read(
const boost::system::error_code& error,
size_t bytes_transferred)
131 std::istream istrm(&buffer_);
133 std::getline(istrm, line,
'\r');
139 if (error == boost::asio::error::eof)
141 glog.
is(DEBUG1) &&
glog <<
"Connection reached EOF" << std::endl;
143 else if (error == boost::asio::error::operation_aborted)
145 glog.
is(DEBUG1) &&
glog <<
"Read operation aborted (socket closed)" << std::endl;
149 glog.
is(WARN) &&
glog <<
"Error reading from TCP connection: " <<
error
158 boost::asio::ip::tcp::socket socket_;
159 boost::asio::streambuf buffer_;
160 std::string remote_endpoint_str_;
161 int packet_failures_;
168 : acceptor_(io_context,
169 boost::asio::ip::tcp::endpoint(
170 ipv6 ?
boost::asio::ip::tcp::v6() :
boost::asio::ip::tcp::v4(), port))
175 std::set<std::shared_ptr<RUDICSConnection>>&
connections() {
return connections_; }
177 boost::signals2::signal<void(std::shared_ptr<RUDICSConnection> connection)>
connect_signal;
179 void disconnect(std::shared_ptr<RUDICSConnection> connection) { connection->close(); }
184 std::shared_ptr<RUDICSConnection> new_connection =
186 acceptor_.async_accept(new_connection->socket(),
187 boost::bind(&RUDICSServer::handle_accept,
this, new_connection,
188 boost::asio::placeholders::error));
191 void handle_accept(std::shared_ptr<RUDICSConnection> new_connection,
192 const boost::system::error_code& error)
199 connections_.insert(new_connection);
201 new_connection->disconnect_signal.connect(
202 boost::bind(&RUDICSServer::handle_disconnect,
this, boost::placeholders::_1));
204 new_connection->start();
205 glog.
is(DEBUG1) &&
glog <<
"Received connection from: "
206 << new_connection->remote_endpoint_str() << std::endl;
212 void handle_disconnect(std::shared_ptr<RUDICSConnection> connection)
217 connections_.erase(connection);
220 glog <<
"Server removing connection: " << connection->remote_endpoint_str()
221 <<
". Remaining connection count: " << connections_.size() << std::endl;
224 std::set<std::shared_ptr<RUDICSConnection>> connections_;
225 boost::asio::ip::tcp::acceptor acceptor_;