Я хотел бы использовать выделенный поток для получения данных 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, он обрабатывается только основным потоком, а не выделенным потоком.
Что здесь происходит не так?
Весь цикл обработки событий, который обрабатывает асинхронные вызовы, выполняется io_server
, который вы запускаете в основном потоке.
Вместо того, чтобы запускать функцию receive
в потоке (она все равно вернется немедленно), вы должны запустить io_service::run
.
@Сам самый простой способ? Как насчет std::thread th(&asio::io_service::run, m_ioService);
?
Приведенный выше код привел к ошибке: нет подходящей функции для вызова ‘std::thread::thread(<тип неразрешенной перегруженной функции>, asio::io_service&)’ ^
@Soo Ах, да, у него есть перегрузки. Так что просто используйте лямбду, которая захватывает сервис и вызывает его функцию run
?
Не могли бы вы предоставить кусок рабочего кода для того же?
@Soo Вы уже используете лямбда-выражения с захватами в коде, который вы показываете. Разве ты не написал это? Ты просто скопировал это? Пожалуйста, не попадайтесь в ловушку культовое программирование карго.
О, я думал о чем-то сложном, и оказалось, что простая лямбда-функция для вызова «m_ioService.run()» решила проблему. Спасибо
Не могли бы вы помочь с измененным кодом, чтобы я мог его попробовать? Мои усилия к этому не работают!