boost asio - 对网络端口的独占绑定

时间:2015-12-05 17:17:27

标签: boost boost-asio

我使用boost asio开发服务器应用程序。应用效果很好。什么不起作用,是对网络端口的独占绑定。

我启动了应用程序的一个实例 - 它开始侦听传入的连接。

我再启动一个实例 - 它也开始侦听同一端口上的传入连接。传递给async_accept的处理程序不会按预期调用错误。

通常我只是尝试获取端口。如果操作失败 - 端口正在使用中。使用Asio这种方法不起作用。如何检查端口的可用性?

void TcpServerFactory::acceptConnectionsOnPort(int serverPort,
                                               boost::shared_ptr<TcpConfigServerReceiver> tcpConfig,
                                               boost::function<void(boost::shared_ptr<TcpServer>)> onSuccessfullyConnectedHandler)
{
    // todo check is port not busy
    FORMATTED_LOG(this->_log, info) << "Start to accept connections on port " << serverPort;
    auto endpoint = boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), serverPort);
    boost::shared_ptr<boost::asio::ip::tcp::acceptor> tcpAcceptor(new boost::asio::ip::tcp::acceptor(this->_ioService, endpoint));

    this->acceptConnections(tcpAcceptor, tcpConfig, onSuccessfullyConnectedHandler);
}

void TcpServerFactory::acceptConnections(boost::shared_ptr<boost::asio::ip::tcp::acceptor> tcpAcceptor,
                                         boost::shared_ptr<TcpConfigServerReceiver> tcpConfig,
                                         boost::function<void(boost::shared_ptr<TcpServer>)> onSuccessfullyConnectedHandler)
{
    boost::shared_ptr<boost::asio::ip::tcp::socket> tcpSocket(new boost::asio::ip::tcp::socket(this->_ioService));
    boost::function<void(const boost::system::error_code &)> onAcceptOperationCompletedHandler =
        boost::bind(&TcpServerFactory::onAcceptOperationCompleted, this->downcasted_shared_from_this<TcpServerFactory>(),
                    _1, tcpAcceptor, tcpSocket, tcpConfig, onSuccessfullyConnectedHandler);

    tcpAcceptor.get()->async_accept(*tcpSocket, onAcceptOperationCompletedHandler);
}

void TcpServerFactory::onAcceptOperationCompleted(const boost::system::error_code & err,
                                                  boost::shared_ptr<boost::asio::ip::tcp::acceptor> tcpAcceptor,
                                                  boost::shared_ptr<boost::asio::ip::tcp::socket> tcpSocket,
                                                  boost::shared_ptr<TcpConfigServerReceiver> tcpConfig,
                                                  boost::function<void(boost::shared_ptr<TcpServer>)> onSuccessfullyConnectedHandler)
{
    if (err)
    {
        FORMATTED_LOG(this->_log, info) << "Failed to accept connections on port " << tcpAcceptor->local_endpoint().port() << "due to error " << BOOST_ERROR_TO_STREAM(err);
        return;
    }
    this->acceptConnections(tcpAcceptor, tcpConfig, onSuccessfullyConnectedHandler);
    this->onConnectionEstablished(tcpSocket, tcpConfig, onSuccessfullyConnectedHandler);
}

更新

我试图在一系列命令上替换acceptor的构造函数。我预计会在tcpAcceptor->bind()异常时提出异常,但事情并没有发生。

// boost::shared_ptr<boost::asio::ip::tcp::acceptor> tcpAcceptor(new boost::asio::ip::tcp::acceptor(this->_ioService, endpoint));


boost::shared_ptr<boost::asio::ip::tcp::acceptor> tcpAcceptor(new boost::asio::ip::tcp::acceptor(this->_ioService));
tcpAcceptor->open(endpoint.protocol());
tcpAcceptor->set_option(boost::asio::socket_base::reuse_address(true));
tcpAcceptor->bind(endpoint);
boost::system::error_code err;
tcpAcceptor->listen(boost::asio::socket_base::max_connections, err);

1 个答案:

答案 0 :(得分:0)

reuse_address不应该这样做。它的意思是在端口被释放后避免“等待”间隔。