Ich versuche einige Funktionstests in einigen API auszuführen.Boost.asio Client/Server TIME_WAIT warum?
Meine API hat eine Client- und eine Serverseite. Die Client-Seite verbindet und setzt eine Flagge. Der Server akzeptiert nur Verbindungen.
Dies ist ein Testfall habe ich:
BOOST_AUTO_TEST_CASE(client_can_connect_to_server) {
boost::asio::io_service serverService;
std::thread serverLoop([&serverService] { serverService.run(); });
boost::asio::io_service clientService;
std::thread clientLoop([&clientService] { clientService.run(); });
// std::this_thread::sleep_for(10ms); Maybe wait for server loop to start...?
auto connectionSuccess = connectTo("127.0.0.1", "54321", kAuthData, ioService);
BOOST_REQUIRE(blockForDurationOrWhile
(timeout,
[&] { return connectionSuccess.wait_for(0s) != std::future_status::ready; }) == ExitStatus::ConditionSatisfied);
serverService.stop();
clientLoop.join();
serverService.join();
}
Ich habe Probleme mit 2 Dinge hier:
- Die Verbindung ist zeitlich mehr als die Hälfte der Zeit, aber manchmal funktioniert.
Beim Beenden des Programms durch den erfolgreichen Pfad bis zum Ende des Tests scheint Netstat eine Art Socket-Lecks mit dem Zustand
TIME_WAIT
zeigt. Ich schließe und schließe die Steckdosen. Ich kann einfach nicht herausfinden, was falsch ist.tcp 0 0 ip6-localhost: 52256 ip6-localhost: 54321 TIME_WAIT
tcp 0 0 ip6-localhost: 54321 ip6-localhost: Dies wird für etwa 30-45 Sekunden, nachdem die App verlässt gezeigt 52256 TIME_WAIT
-Code für die Client- und Server-Code ist unten:
std::future<bool> connectTo(std::string const & host,
std::string const & port,
std::string const & authData,
boost::asio::io_service & s,
std::chrono::high_resolution_clock::duration timeout = kCortexTryConnectTimeout) {
using namespace boost::asio;
using boost::asio::ip::tcp;
std::promise<bool> p;
auto res = p.get_future();
spawn
(s,
[&s, host, port, p = std::move(p)](yield_context yield) mutable {
tcp::socket socket(s);
BOOST_SCOPE_EXIT(&socket) {
std::cout << "Closing client socket\n";
if (socket.is_open()) {
boost::system::error_code ec{};
socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
socket.close();
std::cout << "Client socket closed\n";
}
} BOOST_SCOPE_EXIT_END
std::cout << "Client trying to connect\n";
tcp::resolver resolver(s);
boost::system::error_code ec{boost::asio::error::operation_aborted};
boost::asio::async_connect(socket, resolver.resolve({host, port}), yield[ec]);
std::cout << "Client Connected\n";
if (!ec) p.set_value(true);
else p.set_value(false);
});
return res;
}
Der Server verarbeitet Verbindungen:
class ConnectionsAcceptorTask {
public:
//Session handling for Cortex. Will move out of here
class Session : public std::enable_shared_from_this<Session> {
public:
explicit Session(boost::asio::ip::tcp::socket socket) : _socket(std::move(socket)) {}
void start() {}
~Session() {
if (_socket.is_open()) {
boost::system::error_code ec{};
_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
_socket.close();
}
}
private:
boost::asio::ip::tcp::socket _socket;
};
ConnectionsAcceptorTask(unsigned int port,
io_service & s)
: _port(port),
_ioService(&s)
{}
void operator()() {
namespace ba = boost::asio;
using boost::asio::ip::tcp;
ba::spawn
(*_ioService,
[s = _ioService, port = this->_port](ba::yield_context yield) {
tcp::acceptor acceptor
(*s,
tcp::endpoint(tcp::v4(), port));
acceptor.set_option(boost::asio::socket_base::reuse_address(true));
BOOST_SCOPE_EXIT(&acceptor) {
std::cout << "Closing acceptor\n";
if (acceptor.is_open()) {
acceptor.close();
std::cout << "Acceptor closed\n";
}
} BOOST_SCOPE_EXIT_END
for (;;) {
boost::system::error_code ec{};
tcp::socket socket(*s);
acceptor.async_accept(socket, yield[ec]);
if (!ec) std::make_shared<Session>(std::move(socket))->start();
}
});
}
private:
unsigned int _port = 0;
boost::asio::io_service * _ioService;
};
Warum die negativen Stimmen? –
Ich sehe, dass wenn ich eine synchrone ConnectTo es funktioniert. Wenn ich eine asynchrone Verbindung zu ihm mache, funktioniert das überhaupt nicht. Aber ich verwende zwei verschiedene io_service-Schleifen in verschiedenen Threads. Obwohl ich in demselben Prozess bin, könnte das ein Problem sein? –