【问题标题】:C++ Boost async server handler being called with no connection在没有连接的情况下调用 C++ Boost 异步服务器处理程序
【发布时间】:2015-12-01 00:14:56
【问题描述】:

我正在编写我的第一个 boost::asio 异步服务器,这是我放在一起的代码:

SocketServer.hpp

    class SocketServer {

        public:
            SocketServer(boost::asio::io_service& ioService);
            virtual ~SocketServer();

            void StartAsync(int port);
            void StopAsync();

        private:
            void StartAccept();
            void HandleAccept();

            boost::asio::ip::tcp::acceptor acceptor;
            std::shared_ptr<boost::asio::ip::tcp::socket> socket;
    };

SocketServer.cpp

    SocketServer::SocketServer(boost::asio::io_service &ioService) :
        acceptor(ioService),
        socket(new boost::asio::ip::tcp::socket(ioService)) {}

    SocketServer::~SocketServer() {}

    void SocketServer::StartAsync(int port)
    {
        boost::asio::ip::tcp::endpoint ep(boost::asio::ip::tcp::v4(), port);
        acceptor.open(ep.protocol());
        StartAccept();
    }

    void SocketServer::StopAsync()
    {
        acceptor.cancel();
    }

    void SocketServer::StartAccept()
    {
        acceptor.async_accept(*socket, std::bind(&SocketServer::HandleAccept, this));
    }

    void SocketServer::HandleAccept()
    {

        std::cout << "Connection accepted." << std::endl;
        std::cout << "Connection accepted from " << socket->remote_endpoint().address().to_string() << std::endl;

       // Will create a new thread here to process this connection

        StartAccept();
    }

这个想法是在给定的port 上接收多个连接请求,并为每个连接打开一个线程来处理。

问题是,即使没有连接,HandleAccept 也会被调用,并且 remote_endpoint 会抛出异常:

remote_endpoint: Bad file desciptor

我对发生的事情有点困惑。

我需要为每个连接调用一次,以便我可以使用给定的连接套接字启动一个线程。

一个附带问题:只使用一个套接字进行所有连接是正确的做法吗?

感谢您的帮助。

【问题讨论】:

    标签: c++ multithreading sockets boost


    【解决方案1】:

    首先,您错过了对listen 的呼叫;这是实际监听传入连接的内容。这应该在调用async_accept 之前在你的acceptor 上调用:

    ip::tcp::endpoint ep(boost::asio::ip::tcp::v4(), port);
    acceptor.listen();
    acceptor.async_accept(...);
    

    请注意,传递给async_accept 的函数/函数对象也应该接受boost::system::system_error 作为参数:

    acceptor.async_accept(
        *socket, 
        std::bind(&SocketServer::HandleAccept, this, boost::asio::placeholders::error)
    );
    

    最后,您不能将同一个套接字用于多个(同时)连接。

    【讨论】:

    • 感谢 Yuushi 的帮助....至于同时连接,我应该为每个请求创建一个带有新套接字的新接受器,还是每次我得到 HandleAccept 被解雇时我调用 StartAccept并在那里创建一个新的套接字?
    • 通过建议的更改,代码可以正常工作,但客户端会收到connection refused。我现在有acceptor.listen(),然后是acceptor.async_accept。服务器上没有错误消息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-19
    • 1970-01-01
    • 2015-04-03
    • 1970-01-01
    • 2012-08-30
    • 2023-02-15
    • 1970-01-01
    相关资源
    最近更新 更多