C++ BOOST ASIO-如何编写控制台服务器

C++ BOOST ASIO-如何编写控制台服务器,c++,boost,tcp,boost-asio,C++,Boost,Tcp,Boost Asio,我必须编写异步TCP服务器。 TCP服务器必须由控制台管理 例如:删除客户端,显示所有已连接客户端的列表,etcc 问题是:如何连接或编写控制台,它可以调用上述功能。 这个控制台必须是客户端吗?我应该作为一个单独的线程运行这个控制台客户端吗 我读了很多教程,但都找不到解决问题的方法 服务器TCP代码 主要功能: try { boost::asio::io_service ioService; ServerTCP server(ioService);

我必须编写异步TCP服务器。 TCP服务器必须由控制台管理 例如:删除客户端,显示所有已连接客户端的列表,etcc

问题是:如何连接或编写控制台,它可以调用上述功能。 这个控制台必须是客户端吗?我应该作为一个单独的线程运行这个控制台客户端吗

我读了很多教程,但都找不到解决问题的方法

服务器TCP代码

主要功能:

   try
   {
      boost::asio::io_service ioService;

      ServerTCP server(ioService);
      ioService.run();  
   }
   catch (std::exception& e)
   {
      std::cerr << "Exception: " << e.what() << "\n";
   }
你好,山姆。谢谢你的回复。你能不能给我看一段代码或者一些与这个问题相关的例子的链接? 很可能,我没有正确理解。。。单线程服务器

事实上,在我想要管理服务器操作的控制台中,我需要smt,如下所示:

main()

cout << "Options: q - close server, s - show clients";
while(1)
{
  char key = _getch();
  switch( key )
  {
      case 'q':
         closeServer();
      break
      case 's':
         showClients();
      break
  } 
}
问题是:如何连接或删除 写控制台,可以在上面调用 功能。这个控制台必须 你是客户吗?我应该运行这个控制台吗 客户端作为一个单独的线程

您不需要单独的线程,可以使用posix::stream_描述符和STDIN_FILENO来创建它。使用async_read并在读取处理程序中处理请求

#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();
}
问题是:如何连接或删除 写控制台,可以在上面调用 功能。这个控制台必须 你是客户吗?我应该运行这个控制台吗 客户端作为一个单独的线程

您不需要单独的线程,可以使用posix::stream_描述符和STDIN_FILENO来创建它。使用async_read并在读取处理程序中处理请求

#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();
}

如果我正确理解OP,他/她希望运行通过控制台控制的异步TCP服务器,即控制台用作用户界面。 在这种情况下,您不需要单独的客户端应用程序来查询服务器上连接的客户端等:

您需要生成一个线程,以某种方式调用io_service::run方法。目前您正在从main调用此功能。由于服务器的作用域可能在main中,因此需要执行一些操作,例如将服务器的ref传递给新线程。例如,io_服务可以是服务器类的成员,除非应用程序有其他要求,在这种情况下,将服务器和io_服务都传递给新线程。 将相应的方法(如ShowClient、closeServer等)添加到服务器类中 确保通过控制台触发的这些调用是线程安全的 例如,在closeServer方法中,您可以调用io_service::stop,这将导致服务器结束。
如果我正确理解OP,他/她希望运行通过控制台控制的异步TCP服务器,即控制台用作用户界面。 在这种情况下,您不需要单独的客户端应用程序来查询服务器上连接的客户端等:

您需要生成一个线程,以某种方式调用io_service::run方法。目前您正在从main调用此功能。由于服务器的作用域可能在main中,因此需要执行一些操作,例如将服务器的ref传递给新线程。例如,io_服务可以是服务器类的成员,除非应用程序有其他要求,在这种情况下,将服务器和io_服务都传递给新线程。 将相应的方法(如ShowClient、closeServer等)添加到服务器类中 确保通过控制台触发的这些调用是线程安全的 例如,在closeServer方法中,您可以调用io_service::stop,这将导致服务器结束。
谢谢你的回复。你有一些例子的链接吗?事实上,在控制台中,我需要smth,如下所示:coutSam,我认为OP实际上不想编写单独的控制台应用程序来控制服务器,而只是想通过控制台与服务器交互。@Ralf,在再次阅读OP的问题后,我相信你是对的。我已经更新了我的答案。@Sam,+1是一个优雅而简单的解决方案。我不知道可以使用posix::stream_描述符在asio中处理控制台输入。在Windows下也可以吗?谢谢Sam。我可以在Windows中使用posix::stream_描述符吗?谢谢回复。你有一些例子的链接吗?事实上,在控制台中,我需要smth,如下所示:coutSam,我认为OP实际上不想编写单独的控制台应用程序来控制服务器,而只是想通过控制台与服务器交互。@Ralf,在再次阅读OP的问题后,我相信你是对的。我已经更新了我的答案。@Sam,+1是一个优雅而简单的解决方案。我不知道可以使用posix::stream_描述符在asio中处理控制台输入。在Windows下也可以吗?谢谢Sam。我可以在Windows中使用posix::stream_描述符吗?你好Ralf。这正是我需要的。但我有很多问题,因为我必须在服务器运行后从控制台读取keycommand。现在我让smth变得棘手,我的服务器有2个端口。一个端口用于客户端,一个仅用于控制台。。。。这是可行的,但我的知识还不够,可能一些问题会很快出现…+1不错的细节
我没有回答。不过,我不认为你需要一个单独的线程。您可以使用单个线程来调用io_service::run。看,你好,拉尔夫。这正是我需要的。但我有很多问题,因为我必须在服务器运行后从控制台读取keycommand。现在我让smth变得棘手,我的服务器有2个端口。一个端口用于客户端,一个仅用于控制台。。。。它是有效的,但我的知识还不够,可能一些问题会很快出现…+1个很好的详细答案。不过,我不认为你需要一个单独的线程。您可以使用单个线程来调用io_service::run。看见