c++ - 如何使用专用线程接收 UDP 数据?
问题描述
我想使用专用线程使用 asio 库接收 udp 数据。下面给出了一个示例代码。
#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
.
推荐阅读
- r - 列中从小到大的订单号 (R)
- node.js - 保护 Javascript
- python - 我是 python 新手,正在寻求帮助。我正在尝试为 10 种不同的共同基金经营 Fama-French 并坚持下去
- reactjs - 未捕获的 FirebaseError:函数 CollectionReference.doc() 要求其第一个参数为非空字符串类型
- c# - 如何从流程中获取“项目名称”列表(不是流程名称或窗口标题)
- asp.net - 如何在 ASP.NET 中重置 Request.ServerVariables("SERVER_NAME")?
- javascript - 说明在一个参数和一个操作数(除法或乘法)的情况下如何使用 RPN 计算器
- ios - 如何使用 section 参数遍历集合内的每个文档以访问子集合的计数?
- prolog - 在 prolog 中使用 abs() 构建列表
- tensorflow - ai-platform + gsutil 权限错误:AttributeError:“GFile”对象没有“可读”属性