Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;boost::asio::ip::tcp::acceptor有时不';不接受连接器?_C++_Sockets_Network Programming_Boost Asio - Fatal编程技术网

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

C++ C++;boost::asio::ip::tcp::acceptor有时不';不接受连接器?,c++,sockets,network-programming,boost-asio,C++,Sockets,Network Programming,Boost Asio,我现在有一个很奇怪的问题。有时my::acceptor(使用async_accept)不接受套接字(在async_accept中没有指定接受函数的调用),但连接器在connect函数(两个boost::asio::Class)上返回true。有时所有的工作,但有时我没有得到一个接受插座。。。。我真的不知道为什么了。我使用不同的侦听端口在Win10 64位下测试了所有内容。 我的服务器结构如下: io\U服务: _io_thread = std::make_unique<std::threa

我现在有一个很奇怪的问题。有时my::acceptor(使用async_accept)不接受套接字(在async_accept中没有指定接受函数的调用),但连接器在connect函数(两个boost::asio::Class)上返回true。有时所有的工作,但有时我没有得到一个接受插座。。。。我真的不知道为什么了。我使用不同的侦听端口在Win10 64位下测试了所有内容。
我的服务器结构如下:
io\U服务:

_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();
    }
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();
            }
        );
    }
\u io\u thread=std::使_唯一([this](){
而(1)
{
尝试
{
_io_服务->运行();
打破
}
捕获(常量boost::异常&e)
{
spdlog::错误(“IO_服务_异常:”,boost::诊断_信息(e));
}
}
});
接受者:

_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();
    }
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();
            }
        );
    }
void服务器::初始化(uint16\u t侦听\u端口)
{
//此时io_线程已经在运行
自动端点=ip::tcp::端点(ip::tcp::v4(),侦听端口);
_acceptor=std::make_unique(*_io_服务,endpoint.protocol());
_acceptor->set_选项(boost::asio::ip::tcp::acceptor::reuse_address(false));
_接受者->绑定(端点);
_接受者->倾听();
_侦听端口=侦听端口;
__接受();
}
接受():

_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();
    }
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();
            }
        );
    }
void服务器::\u accept()
{
//为下一个连接创建套接字
_接受者_socket=std::使_唯一(*_io_服务);
_acceptor->async_accept(*_acceptor_socket,[this](const boost::system::error\u code&err)
{
spdlog::info(“接受新套接字…”);//有时不会调用此命令:(
if(err.failed())
{
//接受方关闭
if(err==boost::asio::error::operation\u中止)
{
spdlog::info(“网络服务器停止接受套接字”);
返回;
}
//未知错误
错误(“网络服务器接受套接字失败{}消息{}num{}”,err.failed(),err.message(),err.value());
//接受下一个连接
__接受();
返回;
}
//接受新套接字
_新的\u连接\u互斥锁.lock();
自动连接=uuu创建_u新连接();
con->initialize(+++u连接\ id \计数器,std::move(+u接收器\套接字));
con->set\u handler(\u input\u handler);
con->goto_阶段(初始阶段);
spdlog::info(“来自{}的id为{}的新连接”,con->get_host_name(),con->get_unique_id());
_新建连接[con->get_unique_id()]=std::move(con);
_新的\u连接\u互斥体.unlock();
//等待下一个连接
__接受();
}
);
}


我的客户端连接器很简单,如下所示:

        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...
        [...]
auto socket=std::使_唯一(*_io_服务);
spdlog::info(“尝试连接到{}:{}”,endpoint.address(),to_string(),endpoint.port());
尝试
{
套接字->连接(端点);
}
捕获(常量boost::system::system_error&e)
{
错误(“无法连接到{}:{}”,endpoint.address(),to_string(),endpoint.port());
返回false;
}
//每次都会成功。。。
[...]

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

好的,我找到了答案…io_服务::run函数没有像我预期的那样工作。我想如果不调用io_服务::stop,它将永远阻塞。这似乎是对的ng.因为我在while循环中的one::run调用后中断,然后线程完成,所以当连接器套接字连接时,io_服务有时不再运行。 已更改io_服务::run->run_one()并删除了中断。现在将添加一个循环取消变量,因此它不是无限循环…

谢谢你的回答!

等等,你为什么把地址设为false?我不完全确定它到底是干什么的(它总是一个隐藏的谜)但这可能会导致短时间内无法从同一地址重新打开套接字。所有作用域中都保留了带前导的
\uuu
的标识符;从技术上讲,使用它们是不可能的。代码中有多个日志语句。当遇到问题行为时,您会看到其中哪一个?如果互斥体之间发生异常e> .lock()和
解锁()
您将遇到软锁或死锁。很少需要使用它们,而是使用例外的
std::lock\u guard
std::unique\u lock
std::shared\u lock
safe@sehe:到目前为止,我对私有和受保护的成员函数使用了是的,uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu(如果没有,我必须重新启动服务器,直到它能够接受套接字…)啊,在线程上启动
io\u服务可能是一个微妙的问题。如果在实际发布工作(例如使用异步调用)之前启动它,那么它将返回,因为“没有更多工作”。这意味着在发布第一个工作之前,后台线程已经完成。