BOOST ASIO - How to write console server

不羁的心 提交于 2019-11-27 09:10:54

The problem is: How can I attach (or write) console, which can calls above functionalities. This console have to be a client? Should I run this console client as a sepearate thread?

You don't need a separate thread, use a posix::stream_descriptor and assign STDIN_FILENO to it. Use async_read and handle the requests in the read handlers.

#include <boost/asio.hpp>

#include <boost/bind.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>

#include <iostream>

using namespace boost::asio;

class Input : public boost::enable_shared_from_this<Input>
{
public:
    typedef boost::shared_ptr<Input> Ptr;

public:
    static void create(
            io_service& io_service
            )
    {
        Ptr input(
                new Input( io_service )
                );
        input->read();
    }

private:
    explicit Input(
            io_service& io_service
         ) :
        _input( io_service )
    {
        _input.assign( STDIN_FILENO );
    }

    void read()
    {
        async_read(
                _input,
                boost::asio::buffer( &_command, sizeof(_command) ),
                boost::bind(
                    &Input::read_handler,
                    shared_from_this(),
                    placeholders::error,
                    placeholders::bytes_transferred
                    )
                );
    }

    void read_handler(
            const boost::system::error_code& error,
            size_t bytes_transferred
            )
    {
        if ( error ) {
            std::cerr << "read error: " << boost::system::system_error(error).what() << std::endl;
            return;
        }

        if ( _command != '\n' ) {
            std::cout << "command: " << _command << std::endl;
        }

        this->read();
    }

private:
    posix::stream_descriptor _input;
    char _command;
};

int
main()
{
    io_service io_service;
    Input::create( io_service );
    io_service.run();
}

If I understand the OP correctly, he/she wants to run an async TCP server that is controlled via a console i.e console is used as user interface. In that case you don't need a separate client application to query the server for connected clients, etc.:

  • You need to spawn a thread that somehow calls the io_service::run method. Currently you are calling this from main. Since your server will probably be scoped in main, you need do something like pass a ref to the server to the new thread. The io_service could e.g be a member of the server class (unless your application has other requirements in which case pass both the server and the io_service to the new thread).
  • add the corresponding methods such as showClients, closeServer, etc. to your server class
  • make sure that these calls which are triggered via the console are thread-safe
  • in your closeServer method you could for instance call io_service::stop which would result in the server ending.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!