Boost Asio многопоточный TCP-синхронный сервер

#c #multithreading #boost #boost-asio

#c #многопоточность #boost #boost-asio

Вопрос:

Я пытаюсь создать tcp-синхронный сервер. Мой основной поток создал бы прослушивание порта, и входящее соединение было бы обработано потоком.

Мой код:

 void WorkerThread(boost::shared_ptr< boost::asio::io_service >  io_service)
{
    io_service->run();
}

void Application::server()
{
        boost::shared_ptr< boost::asio::io_service > io(
            new boost::asio::io_service()
            );
        boost::shared_ptr< boost::asio::io_service::work > work(
            new boost::asio::io_service::work(*io)
            );
        // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR
        boost::asio::ip::tcp::acceptor acceptor(*io);
        boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 2198);
        acceptor.open(endpoint.protocol());
        acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
        acceptor.bind(endpoint);
        acceptor.listen();              

        // pool of threads
        boost::thread_group worker_threads;
        for(int x = 0; x < 5;   x)
        {
            worker_threads.create_thread(boost::bind(amp;WorkerThread, io));
        }

        while(true)
        {
            boost::shared_ptr< boost::asio::ip::tcp::socket > socket(
                new boost::asio::ip::tcp::socket( *io )
                );
            acceptor.accept(*socket);
            processConnection(*socket);
            socket->close();
        }

        io->stop();
        worker_threads.join_all();

}

void Application::processConnection(boost::asio::ip::tcp::socket amp; socket)
{
    boost::asio::streambuf request_buffer;
    std::istream request_stream(amp;request_buffer);
    // repsonse buffer
    boost::asio::streambuf response_buffer;
    std::ostream response_stream(amp;response_buffer); 
    boost::asio::read_until(socket, request_buffer, "</message>"); 

    // process request_buffer into response_buffer

    boost::asio::write(socket, response_buffer);

}
  

Следующее работает с несколькими клиентами, подключающимися к серверу; однако это также сработает, если я удалю пул потоков. Кто-нибудь может объяснить мне, почему это так? Нужен ли мне вообще пул потоков?

Ответ №1:

однако это также сработает, если я удалю пул потоков. Кто-нибудь может объяснить мне, почему это так? Нужен ли мне вообще пул потоков?

Вам не нужен пул потоков, учитывая ваш пример кода. Нет необходимости вызывать io_service::run() в вашем контексте, смотрите документацию

run() Функция блокируется до тех пор, пока не будет завершена вся работа и больше не будут отправлены обработчики, или пока io_service не будет остановлена.

Вы не добавили никаких обработчиков к io_service , поэтому нет необходимости вызывать run() . Если вы используете асинхронные методы, такие как async_accept() , то вам потребуется run() io_service .

Комментарии:

1. есть ли ситуация, когда мне нужно было бы использовать run () на синхронном сервере?

Ответ №2:

возможно, вам будет легче читать ваш код, если вы введете команду boost

пример

 typedef boost::asio::ip::tcp::socket TSocket;
  

Напрямую это не помогает, но поможет