Как использовать выделенный поток для получения данных UDP? - PullRequest
0 голосов
/ 09 апреля 2019

Я хотел бы использовать выделенный поток для получения данных udp с использованием библиотеки asio. Пример кода приведен ниже.

#define ASIO_STANDALONE // we are using the stand aloe version of ASIO and Not Boost::ASIO


#include <iostream>
#include "include/asio.hpp"
#include <array>
#include <thread>


class UDPServer
{

public:
    UDPServer( asio::io_service& ioService): m_socket(ioService)
    {}
    ~UDPServer(){}

    void listen(const int& port)
    {
        m_socket.open(asio::ip::udp::v4());
        m_socket.bind(asio::ip::udp::endpoint(asio::ip::udp::v4(), port));

#define DEDICATED_THREAD_FLAG  1

#if DEDICATED_THREAD_FLAG
        m_thread = std::thread( &UDPServer::receive, this);
        std::cout<<"Thead Id in listen:"<<std::this_thread::get_id()<<std::endl;
        m_thread.join();
#else
        receive();
#endif
    }

    template<std::size_t SIZE>
    void processReceivedData(const std::array<char, SIZE>& rcvdMessage,
                             const int& rcvdMessageSizeInBytes,
                             const std::error_code& error)
    {

        std::cout<<"Rcvd Message: "<<rcvdMessage.data()<<std::endl;
        receive();

    }
    void receive()
    {
        std::cout<<"Thead Id in receive0:"<<std::this_thread::get_id()<<std::endl;

        asio::ip::udp::endpoint m_udpRemoteEndpoint;

        m_socket.async_receive_from(asio::buffer(recv_buffer, recv_buffer.size()/*NetworkBufferSize*/), m_udpRemoteEndpoint,
                                    [this](std::error_code ec, std::size_t bytesReceived)
        {
            std::cout<<"Thead Id in receive1:"<<std::this_thread::get_id()<<std::endl;

            processReceivedData(recv_buffer, bytesReceived, ec);
        });

    }

private:
    asio::ip::udp::socket m_socket;
    std::thread m_thread;
    static const int NetworkBufferSize = 9000;
    std::array<char, NetworkBufferSize> recv_buffer;

};


int main()
{

    std::cout<<"Main Thead Id:"<<std::this_thread::get_id()<<std::endl;
    asio::io_service m_ioService;


    UDPServer myServer( m_ioService);
    myServer.listen(12345); // starting the UDP server

    std::cout<<"Program waiting.."<<std::endl;

    m_ioService.run();


    std::cout<<"Program ending.."<<std::endl;
}

Неназначенную версию потока можно включить, изменив DEDICATED_THREAD_FLAG на 0, что работает, как и ожидалось.

Однако, когда для DEDICATED_THREAD_FLAG установлено значение 1, новый поток запускается и входит в функцию «получения». Но когда приходит пакет udp, он обрабатывается только основным потоком, а не выделенным потоком.

Что здесь не так?

1 Ответ

2 голосов
/ 09 апреля 2019

Весь цикл обработки событий, который обрабатывает асинхронные вызовы, выполняется с помощью io_server, который вы запускаете в главном потоке.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...