我必须编写异步TCP服务器。 TCP服务器必须由控制台管理 (例如:删除客户端,显示所有连接客户端的列表,等等。)
问题是:如何连接(或写入)控制台,它可以调用以上功能。 这个控制台必须是客户端?我应该将此控制台客户端作为一个单独的线程运行吗?
我已经阅读了很多教程,但我找不到解决问题的方法。
ServerTCP代码
class ServerTCP
{
public:
ServerTCP(boost::asio::io_service& A_ioService, unsigned short A_uPortNumber = 13)
: m_tcpAcceptor(A_ioService, tcp::endpoint(tcp::v4(), A_uPortNumber)), m_ioService (A_ioService)
{
start();
}
private:
void start()
{
ClientSessionPtr spClient(new ClientSession(m_tcpAcceptor.io_service(), m_connectedClients));
m_tcpAcceptor.async_accept(spClient->getSocket(),
boost::bind(&ServerTCP::handleAccept, this, spClient,
boost::asio::placeholders::error));
}
void handleAccept(ClientSessionPtr A_spNewClient, const boost::system::error_code& A_nError)
{
if ( !A_nError )
{
A_spNewClient->start();
start();
}
}
boost::asio::io_service& m_ioService;
tcp::acceptor m_tcpAcceptor;
Clients m_connectedClients;
};
主要功能:
try
{
boost::asio::io_service ioService;
ServerTCP server(ioService);
ioService.run();
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
Sam先生。谢谢你的答复。你能这么善良并向我展示一些代码或一些涉及这个问题的例子的链接吗? 可能,我不能正确理解“...单线程服务器......”
事实上在我想要管理服务器操作的“控制台”中,我需要像下面这样的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
}
}
答案 0 :(得分:3)
问题是:我如何附加(或 写)控制台,可以调用上面 功能。这个控制台必须 成为客户?我应该运行这个控制台吗? 客户端作为一个单独的线程?
您不需要单独的主题,请使用posix::stream_descriptor
和assign 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();
}
答案 1 :(得分:1)
如果我正确理解OP,他/她想要运行通过控制台控制的异步TCP服务器,即控制台用作用户界面。 在这种情况下,您不需要单独的客户端应用程序来查询服务器的连接客户端等: