44 static std::shared_ptr<RUDICSConnection>
create(
46 boost::asio::io_service& executor)
48 const boost::asio::ip::tcp::socket::executor_type& executor)
54 boost::asio::ip::tcp::socket&
socket() {
return socket_; }
58 remote_endpoint_str_ = boost::lexical_cast<std::string>(socket_.remote_endpoint());
64 socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
70 boost::asio::async_read_until(socket_, buffer_,
'\r',
71 boost::bind(&RUDICSConnection::handle_read,
this,
72 boost::placeholders::_1,
73 boost::placeholders::_2));
78 boost::asio::async_write(socket_, boost::asio::buffer(data),
79 boost::bind(&RUDICSConnection::handle_write,
this,
80 boost::placeholders::_1, boost::placeholders::_2));
87 glog.
is(DEBUG1) &&
glog <<
"Disconnecting from: " << remote_endpoint_str_ << std::endl;
94 const int max_packet_failures = 3;
95 if (++packet_failures_ >= max_packet_failures)
97 glog.
is(DEBUG1) &&
glog <<
"More than " << max_packet_failures <<
" bad RUDICS packets."
103 boost::signals2::signal<void(
const std::string& line,
104 std::shared_ptr<RUDICSConnection> connection)>
113 boost::asio::io_service& executor)
115 const boost::asio::ip::tcp::socket::executor_type& executor)
117 : socket_(executor), remote_endpoint_str_(
"Unknown"), packet_failures_(0)
121 void handle_write(
const boost::system::error_code& error,
size_t bytes_transferred)
127 glog.
is(WARN) &&
glog <<
"Error writing to TCP connection: " << error << std::endl;
132 void handle_read(
const boost::system::error_code& error,
size_t bytes_transferred)
139 std::istream istrm(&buffer_);
141 std::getline(istrm, line,
'\r');
147 if (error == boost::asio::error::eof)
149 glog.
is(DEBUG1) &&
glog <<
"Connection reached EOF" << std::endl;
151 else if (error == boost::asio::error::operation_aborted)
153 glog.
is(DEBUG1) &&
glog <<
"Read operation aborted (socket closed)" << std::endl;
157 glog.
is(WARN) &&
glog <<
"Error reading from TCP connection: " <<
error
166 boost::asio::ip::tcp::socket socket_;
167 boost::asio::streambuf buffer_;
168 std::string remote_endpoint_str_;
169 int packet_failures_;
176 : acceptor_(io_context,
177 boost::asio::ip::tcp::endpoint(
178 ipv6 ?
boost::asio::ip::tcp::v6() :
boost::asio::ip::tcp::v4(), port))
183 std::set<std::shared_ptr<RUDICSConnection>>&
connections() {
return connections_; }
185 boost::signals2::signal<void(std::shared_ptr<RUDICSConnection> connection)>
connect_signal;
187 void disconnect(std::shared_ptr<RUDICSConnection> connection) { connection->close(); }
192 std::shared_ptr<RUDICSConnection> new_connection =
193#ifdef USE_BOOST_IO_SERVICE
198 acceptor_.async_accept(new_connection->socket(),
199 boost::bind(&RUDICSServer::handle_accept,
this, new_connection,
200 boost::asio::placeholders::error));
203 void handle_accept(std::shared_ptr<RUDICSConnection> new_connection,
204 const boost::system::error_code& error)
211 connections_.insert(new_connection);
213 new_connection->disconnect_signal.connect(
214 boost::bind(&RUDICSServer::handle_disconnect,
this, boost::placeholders::_1));
216 new_connection->start();
217 glog.
is(DEBUG1) &&
glog <<
"Received connection from: "
218 << new_connection->remote_endpoint_str() << std::endl;
224 void handle_disconnect(std::shared_ptr<RUDICSConnection> connection)
229 connections_.erase(connection);
232 glog <<
"Server removing connection: " << connection->remote_endpoint_str()
233 <<
". Remaining connection count: " << connections_.size() << std::endl;
236 std::set<std::shared_ptr<RUDICSConnection>> connections_;
237 boost::asio::ip::tcp::acceptor acceptor_;