MAVConnTCPClient::MAVConnTCPClient(uint8_t system_id, uint8_t component_id, std::string server_host, unsigned short server_port) : MAVConnInterface(system_id, component_id), tx_in_progress(false), tx_q {}, rx_buf {}, io_service(), io_work(new io_service::work(io_service)), socket(io_service) { if (!resolve_address_tcp(io_service, conn_id, server_host, server_port, server_ep)) throw DeviceError("tcp: resolve", "Bind address resolve failed"); logInform(PFXd "Server address: %s", conn_id, to_string_ss(server_ep).c_str()); try { socket.open(tcp::v4()); socket.connect(server_ep); } catch (boost::system::system_error &err) { throw DeviceError("tcp", err); } // give some work to io_service before start io_service.post(std::bind(&MAVConnTCPClient::do_recv, this)); // run io_service for async io io_thread = std::thread([this] () { utils::set_this_thread_name("mtcp%zu", conn_id); io_service.run(); }); }
MAVConnTCPServer::MAVConnTCPServer(uint8_t system_id, uint8_t component_id, std::string server_host, unsigned short server_port) : MAVConnInterface(system_id, component_id), io_service(), acceptor(io_service) { if (!resolve_address_tcp(io_service, conn_id, server_host, server_port, bind_ep)) throw DeviceError("tcp-l: resolve", "Bind address resolve failed"); logInform(PFXd "Bind address: %s", conn_id, to_string_ss(bind_ep).c_str()); try { acceptor.open(tcp::v4()); acceptor.set_option(tcp::acceptor::reuse_address(true)); acceptor.bind(bind_ep); acceptor.listen(); } catch (boost::system::system_error &err) { throw DeviceError("tcp-l", err); } // give some work to io_service before start io_service.post(std::bind(&MAVConnTCPServer::do_accept, this)); // run io_service for async io io_thread = std::thread([this] () { utils::set_this_thread_name("mtcps%zu", conn_id); io_service.run(); }); }
void MAVConnTCPClient::client_connected(size_t server_channel) { logInform(PFXd "Got client, id: %zu, address: %s", server_channel, conn_id, to_string_ss(server_ep).c_str()); // start recv socket.get_io_service().post(std::bind(&MAVConnTCPClient::do_recv, this)); }
void MAVConnTCPServer::client_closed(std::weak_ptr<MAVConnTCPClient> weak_instp) { if (auto instp = weak_instp.lock()) { bool locked = mutex.try_lock(); logInform(PFXd "Client connection closed, id: %p, address: %s", conn_id, instp.get(), to_string_ss(instp->server_ep).c_str()); client_list.remove(instp); if (locked) mutex.unlock(); } }
static bool resolve_address_tcp(io_service &io, size_t chan, std::string host, unsigned short port, tcp::endpoint &ep) { bool result = false; tcp::resolver resolver(io); error_code ec; tcp::resolver::query query(host, ""); std::for_each(resolver.resolve(query, ec), tcp::resolver::iterator(), [&](const tcp::endpoint & q_ep) { ep = q_ep; ep.port(port); result = true; logDebug(PFXd "host %s resolved as %s", chan, host.c_str(), to_string_ss(ep).c_str()); }); if (ec) { logWarn(PFXd "resolve error: %s", chan, ec.message().c_str()); result = false; } return result; }