C++ boost::asio::ip::tcp::acceptor 有时不接受连接器?

C++ boost::asio::ip::tcp::acceptor sometimes doesn't accept connector?

本文关键字:不接受 连接器 tcp boost asio ip C++ acceptor      更新时间:2023-10-16

我目前有一个非常奇怪的问题。有时我的 ::acceptor(使用 async_accept(不接受套接字(没有调用 async_accept 中指定的 accept 函数(,但连接器在连接函数上返回 true(两个 boost::asio::类(。有时一切正常,但有时我没有得到接受器插座......我真的不知道为什么了。我用不同的listen_ports测试了 Win10 64 位下的所有内容。
我的服务器结构如下:
io_service:

_io_thread = std::make_unique<std::thread>([this]() {
while (1)
{
try
{
_io_service->run();
break;
}
catch (const boost::exception& e)
{
spdlog::error("IO_SERVICE_EXCEPTION: ", boost::diagnostic_information(e));
}
}
});

受主:

void Server::initialize(uint16_t listen_port)
{
// at this point the io_thread is running already
auto endpoint = ip::tcp::endpoint(ip::tcp::v4(), listen_port);
_acceptor = std::make_unique<boost::asio::ip::tcp::acceptor>(*_io_service, endpoint.protocol());
_acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(false));
_acceptor->bind(endpoint);
_acceptor->listen();
_listen_port = listen_port;
__accept();
}

__accept((:

void Server::__accept()
{
// create socket for next connection
_acceptor_socket = std::make_unique<ip::tcp::socket>(*_io_service);
_acceptor->async_accept(*_acceptor_socket, [this](const boost::system::error_code& err)
{
spdlog::info("Accept new socket..."); // this sometimes doesn't get called :(
if (err.failed())
{
// acceptor closed
if (err == boost::asio::error::operation_aborted)
{
spdlog::info("network server stopped accepting sockets");
return;
}
// unknown error
spdlog::error("network server accepting socket failed {} message {} num {}", err.failed(), err.message(), err.value());
// accept next connection
__accept();
return;
}
// accept new socket
_new_connections_mutex.lock();
auto con = __create_new_connection();
con->initialize(++_connection_id_counter, std::move(_acceptor_socket));
con->set_handler(_input_handler);
con->goto_phase(_initial_phase);
spdlog::info("new connection from {} with id {}", con->get_host_name(), con->get_unique_id());
_new_connections[con->get_unique_id()] = std::move(con);
_new_connections_mutex.unlock();
// wait for next connection
__accept();
}
);
}



我的客户端连接器是这样的简单:

auto socket = std::make_unique<boost::asio::ip::tcp::socket>(*_io_service);
spdlog::info("try to connect to {}:{}", endpoint.address().to_string(), endpoint.port());
try
{
socket->connect(endpoint);
}
catch (const boost::system::system_error & e)
{
spdlog::error("cannot connect to {}:{}", endpoint.address().to_string(), endpoint.port());
return false;
}
// this succeeds everytime...
[...]

那么......每次连接器插座成功连接时,是否也应该创建接受器插座?我希望有人知道这里出了什么问题:/

好的,我找到了答案....io_service::run 函数没有按我的预期工作。我以为如果不调用 io_service::stop,它会永远阻塞。看来这是错误的。因为我在 while 循环中发出一个 ::run 调用后中断,然后线程完成,所以当连接器插座连接时,io_service有时不再运行。 更改了 io_service::run -> run_one(( 并删除了中断。现在将添加一个循环取消变量,所以它不是无限循环......
感谢您的回答!