我已经使用boost实现了SocketServer。此SocketServer旨在按以下方式工作:

  • 接受一定时间的连接
  • 在达到超时后停止处理套接字

  • 这是我的代码:
    ServerSocket::ServerSocket(unsigned int port)
    {
        _io_service.reset(new boost::asio::io_service()) ;
        _endpoint.reset(new boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port));
        _acceptor.reset(new boost::asio::ip::tcp::acceptor(*_io_service, *_endpoint)) ;
        _newConnection = false;
    }
    
    bool ServerSocket::accept(boost::asio::ip::tcp::socket& socket, int timeout)
    {
        _newConnection = false;
        _acceptor->async_accept(socket, boost::bind(&ServerSocket::handleAccept, this, &socket));
        _io_service->reset();
    
        if (timeout > 0)
        {
            int incrementation = 1;
            int time_spent = 0;
            while (time_spent < timeout && !_io_service->poll_one())
            {
                time_spent += incrementation;
                sleep(incrementation);
            }
        }
        else
        {
            _io_service->run_one();
        }
    
        if (!_newConnection)
        {
            _acceptor->cancel();
        }
    
        return _newConnection;
    
    }
    
    void ServerSocket::handleAccept(boost::asio::ip::tcp::socket* pSocket)
    {
        _newConnection = true;
    };
    

    我的问题如下:当我使用超时和套接字A调用accept()时,如果达到超时,然后使用新的套接字B再次调用它,如果然后accept()起作用,我将处理A而不是B 。

    告诉我是否缺少信息。

    最佳答案

    您可以简单地使用io_service的任务循环,并使用截止时间计时器来取消对接受器的操作。

    Live On Coliru

    #include <boost/asio.hpp>
    #include <boost/bind.hpp>
    
    using namespace boost;
    using asio::ip::tcp;
    
    struct ServerSocket
    {
        asio::io_service _io_service;
        tcp::endpoint _endpoint;
        tcp::acceptor _acceptor;
        asio::deadline_timer _timer;
        bool _newConnection;
    
        ServerSocket(unsigned int port)
            : _io_service(),
              _endpoint(tcp::v4(), port),
              _acceptor(_io_service, _endpoint),
              _timer(_io_service),
              _newConnection(false)
        {
        }
    
        void timer_expired(boost::system::error_code ec)
        {
            if (!ec)
            {
                _acceptor.cancel();
            }
        }
    
        bool accept(boost::asio::ip::tcp::socket& socket, int timeout)
        {
            _newConnection = false;
            _io_service.reset();
            _timer.expires_from_now(boost::posix_time::seconds(timeout));
            _timer.async_wait(boost::bind(&ServerSocket::timer_expired, this, asio::placeholders::error));
            _acceptor.async_accept(socket, boost::bind(&ServerSocket::handleAccept, this, &socket, asio::placeholders::error));
    
            _io_service.run();
    
            return _newConnection;
        }
    
        void handleAccept(boost::asio::ip::tcp::socket* pSocket, boost::system::error_code ec)
        {
            if (!ec)
            {
                _timer.cancel();
                _newConnection = true;
            }
        };
    };
    
    int main()
    {
        ServerSocket s(6767);
    
        tcp::socket socket(s._io_service);
    
        if (s.accept(socket, 3))
            std::cout << "Accepted connection from " << socket.remote_endpoint() << "\n";
        else
            std::cout << "Timeout expired\n";
    }
    

    如果只是执行!ec,则可能应该显式地检查operation_canceled错误代码,但我将其留给读者练习。

    关于c++ - boost::acceptor::cancel无法按预期工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26929506/

    10-11 12:17