我想在一些API中運行一些功能測試。Boost.asio客戶端/服務器TIME_WAIT爲什麼?
我的API有一個客戶端和一個服務器端。 客戶端只連接並設置一個標誌。服務器只接受連接。
這是一個測試情況下,我有:
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();
}
我有兩件事情在這裏的麻煩:
- 的連接超時超過一半的時間,但有時工作。
當通過成功通過測試結束的程序完成程序時,似乎netstat顯示某種類型的套接字泄漏,狀態爲
TIME_WAIT
。我正在關閉並關閉插座。我無法弄清楚什麼是錯的。這被示爲應用程序退出後周圍30-45秒:TCP 0 0 IP6-本地主機:52256的IP6-本地主機:54321 TIME_WAIT
TCP 0 0 IP6-本地主機:54321的IP6-本地主機:52256 TIME_WAIT
代碼客戶端和服務器的代碼如下:
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;
}
服務器處理連接:
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;
};
爲什麼是負面投票? –
我看到,當我做一個同步ConnectTo它的作品。當我進行異步連接時,根本不起作用。但是我在不同的線程中使用了兩個不同的io_service循環。雖然,我在同一個過程中,這可能是一個問題嗎? –