简体   繁体   English

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

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

I currently have a very weird problem.我目前有一个非常奇怪的问题。 Sometimes my ::acceptor (using async_accept) doesn't accept a socket (there is no call of the accept function specified in async_accept) but the connector returns true on the connect function (both boost::asio:: classes).有时我的::acceptor(使用 async_accept)不接受套接字(没有调用 async_accept 中指定的接受函数)但连接器在连接函数(boost::asio::类)上返回 true Sometimes all works but sometimes I don't get an acceptor socket.... I really don't know why anymore.有时一切正常,但有时我没有得到一个接受器套接字......我真的不知道为什么了。 I tested everything under Win10 64bit with different listen_ports.我在 Win10 64bit 下使用不同的 listen_ports 测试了所有内容。
My server structure is the following:我的服务器结构如下:
io_service: 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));
                }
            }
        });

acceptor:受体:

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();
            }
        );
    }



My client connector is simple like that:我的客户端连接器很简单:

        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...
        [...]

So... shouldn't everytime when the connector socket succeeds to connect the acceptor socket be created as well?所以......不应该每次当连接器套接字成功连接接受器套接字时也被创建吗? I hope somebody knows what's going wrong here :/我希望有人知道这里出了什么问题:/

Okay I found the answer.... the io_service::run function doesn't work as I expected.好的,我找到了答案...... io_service::run 函数没有按我预期的那样工作。 I thought it will just block forever if io_service::stop is not called.我认为如果不调用 io_service::stop 它将永远阻塞。 Seems like that is wrong.好像那是错的。 Because I break after one ::run call out of my while loop and then the thread is finished the io_service sometimes didn't run anymore when the connector socket connected.因为我在一次 ::run 调用之后中断了我的 while 循环,然后线程完成了 io_service 有时在连接器套接字连接时不再运行。 Have changed the io_service::run -> run_one() and removed the break.更改了 io_service::run -> run_one() 并删除了中断。 Will now add a loop-cancel variable so it's no infinite loop...现在将添加一个循环取消变量,因此它不是无限循环......
Thanks for your answers !感谢您的回答!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 boost :: asio :: ip :: tcp :: acceptor如何与TCP_DEFER_ACCEPT和TCP_FASTOPEN一起使用 - How boost::asio::ip::tcp::acceptor work with TCP_DEFER_ACCEPT and TCP_FASTOPEN boost :: asio :: ip :: tcp :: acceptor上的分段错误 - Segmentation fault on boost::asio::ip::tcp::acceptor boost::asio::ip::tcp::acceptor 在使用 async_accept 接收连接请求时终止应用程序 - boost::asio::ip::tcp::acceptor terminates application when receiving connection request using async_accept 如何使boost :: asio :: ip :: tcp :: acceptor永远永久? - How to make boost::asio::ip::tcp::acceptor block forever? Boost-asio在单个(TCP)接收器上侦听多个IP地址 - Boost-asio listening to multiple IP Addresses on a single (TCP) acceptor boost :: asio :: ip :: tcp :: socket不会读取任何内容 - boost::asio::ip::tcp::socket doesn't read anything 处理套接字提升asio tcp ip - C ++套接字编程 - Handling socket boost asio tcp ip - C++ socket programming boost asio acceptor.accept无效参数 - boost asio acceptor.accept invalid argument 提升Asio tcp :: acceptor访问冲突异常 - Boost Asio tcp::acceptor access violation exception 如何接受 boost::asio::ssl::stream<boost::asio::ip::tcp::socket> 作为 boost::asio::ip::tcp::socket 类型的参数 - How to accept boost::asio::ssl::stream<boost::asio::ip::tcp::socket> as an argument of type boost::asio::ip::tcp::socket
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM