C ++ Boost异步服务器处理程序在没有连接的情况下被调用

时间:2015-12-01 00:14:57

标签: c++ multithreading sockets boost

我正在编写我的第一个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

我在这里有点困惑。

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

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

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

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

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

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