gpt4 book ai didi

c++ - Boost UDP async_receive_from 不等待超时或接收

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:47:23 31 4
gpt4 key购买 nike

我尝试使用 async_receive_from 方法来获取数据。但是当我开始时,程序不会等待超时或正在读取某些内容。我知道数据正在端口(wireshark)上传入。这可能是什么原因。我尝试使用来自 boost website 的不同示例.当我调试代码时,我总是得到错误代码 125 (operation_aborted)。这是我的代码的相关部分:

UDPCommunication::UDPCommunication(){
m_portReceive = 2041;
m_byteArrayLen = 0;
m_lengthReceive = 0;
m_dataReceived = false;
}

void UDPCommunication::openSocketReceive(){
try{
m_socketReceive = shared_ptr<udp::socket>(
new udp::socket(m_ioService,
udp::endpoint(udp::v4(), m_portReceive)));

m_receiveTimeout = shared_ptr<boost::asio::deadline_timer>(
new boost::asio::deadline_timer(m_ioService));

m_receiveTimeout->async_wait(
boost::bind(&UDPCommunication::udpReceiveTimeoutHandler, this,
boost::asio::placeholders::error, 0));

m_dataReceived = false;

} catch(std::exception& e){
std::cerr << e.what() << std::endl;
ErrorLogging::log(e);
}
}

void UDPCommunication::udpReceiveWithTimeout(long time){
try{
boost::system::error_code ec;
m_receiveTimeout->expires_from_now(boost::posix_time::seconds(time));
ec = boost::asio::error::would_block;
m_lengthReceive = 0;
m_socketReceive->async_receive_from(buffer(m_bufferReceive),
m_endpointReceive,
boost::bind(&UDPCommunication::udpReceiveTimeoutHandler, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
do{
m_ioService.run_one();
}while(ec == boost::asio::error::would_block);

} catch(std::exception& e){
std::cerr << e.what() << std::endl;
ErrorLogging::log(e);
}
}

bool UDPCommunication::udpReceiveTimeoutHandler(
const boost::system::error_code& ec, size_t size){
try{
m_socketReceive->cancel();
m_receiveTimeout->cancel();
if(ec != boost::asio::error::would_block){

m_dataReceived = false;
return false;
}else{
m_lengthReceive = sizeof(m_bufferReceive);
m_vectorBuffer.resize(m_lengthReceive);
int i = 0;
for(std::vector<unsigned char>::iterator it =
m_vectorBuffer.begin(); it != m_vectorBuffer.end(); ++it){
*it = m_bufferReceive[i];
++i;
}
m_dataReceived = true;
return true;
}
} catch(std::exception& e){
std::cerr << e.what() << std::endl;
ErrorLogging::log(e);
return false;
}
return false;
}

bool UDPCommunication::dataReceived(){
return m_dataReceived;
}

void main(){
udpCommunication = shared_ptr<UDPCommunication>(new UDPCommunication());
udpCommunication->openSocketReceive();
udpCommunication->udpReceiveWithTimeout(5);
bool dataReceived = udpCommunication->dataReceived();

std::cout<< dataReceived << std::endl; //is data coming?
}

上层问题的解。此代码工作正常:

int m_portReceive;
int m_byteArrayLen;
io_service m_ioService;
udp::endpoint m_endpointReceive;
shared_ptr<udp::socket> m_socketReceive;
shared_ptr<boost::asio::deadline_timer> m_receiveTimeout;
std::vector<unsigned char> m_vectorBuffer;
unsigned char m_bufferReceive[128];
size_t m_lengthReceive;
bool m_dataReceived;
bool m_timeoutFired;
boost::mutex m_mutex;

UDPCommunication::UDPCommunication(){
m_portReceive = 2041;
m_byteArrayLen = 0;
m_lengthReceive = 0;
m_dataReceived = false;
m_timeoutFired = false;
}

void UDPCommunication::openSocketReceive(){
try{
m_socketReceive = shared_ptr<udp::socket>(
new udp::socket(m_ioService,
udp::endpoint(udp::v4(), m_portReceive)));

m_receiveTimeout = shared_ptr<boost::asio::deadline_timer>(
new boost::asio::deadline_timer(m_ioService));

m_receiveTimeout->expires_at(boost::posix_time::pos_infin);
UDPCommunication::udpTimeoutHandler();

m_receiveTimeout->async_wait(
boost::bind(&UDPCommunication::udpTimeoutHandler, this));

m_dataReceived = false;

} catch(std::exception& e){
std::cerr << e.what() << std::endl;
ErrorLogging::log(e);
}
}

void UDPCommunication::udpReceiveWithTimeout(long time){

try{
boost::system::error_code ec;
m_receiveTimeout->expires_from_now(
boost::posix_time::time_duration(
boost::posix_time::seconds(time)));

m_socketReceive->async_receive_from(buffer(m_bufferReceive),
m_endpointReceive,
boost::bind(&UDPCommunication::udpReceiveHandler, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
do{
m_ioService.run_one();
}while((m_lengthReceive == 0)
&& (m_timeoutFired == false));

} catch(std::exception& e){
std::cerr << e.what() << std::endl;
ErrorLogging::log(e);
}
}

void UDPCommunication::udpReceiveHandler(const boost::system::error_code& ec,
size_t size){
try{
m_mutex.lock();
if(m_timeoutFired == false){
if(size > 0){
m_socketReceive->cancel();
m_receiveTimeout->cancel();
m_lengthReceive = size;

m_vectorBuffer.resize(m_lengthReceive);
int i = 0;
for(std::vector<unsigned char>::iterator it =
m_vectorBuffer.begin(); it != m_vectorBuffer.end();
++it){
*it = m_bufferReceive[i];
++i;
}

m_dataReceived = true;
}else{
m_lengthReceive = 0;
m_socketReceive->async_receive_from(buffer(m_bufferReceive),
m_endpointReceive,
boost::bind(&UDPCommunication::udpReceiveHandler, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
}
m_mutex.unlock();
} catch(std::exception& e){
std::cerr << e.what() << std::endl;
ErrorLogging::log(e);
m_mutex.unlock();
}
}


void UDPCommunication::udpTimeoutHandler(){
try{
m_mutex.lock();
if(m_lengthReceive == 0){
if(m_receiveTimeout->expires_at()
<= deadline_timer::traits_type::now()){
std::cout << "timeout: no data received from modem"
<< std::endl;
m_socketReceive->cancel();
m_dataReceived = false;
m_receiveTimeout->expires_at(boost::posix_time::pos_infin);
m_timeoutFired = true;
}
m_receiveTimeout->async_wait(
boost::bind(&UDPCommunication::udpTimeoutHandler, this));
}
m_mutex.unlock();
} catch(std::exception& e){
std::cerr << e.what() << std::endl;
ErrorLogging::log(e);
m_mutex.unlock();
}
}

bool UDPCommunication::dataReceived(){
return m_dataReceived;
}

void main(){
udpCommunication = shared_ptr<UDPCommunication>(new UDPCommunication());
udpCommunication->openSocketReceive();
udpCommunication->udpReceiveWithTimeout(5);
bool dataReceived = udpCommunication->dataReceived();

std::cout<< dataReceived << std::endl; //is data coming?

//now do something with data...
}

最佳答案

请注意,我没有检查每一行是否有其他错误,但我想到了两个问题:

  1. 您在 deadline_timer 上进行 async_wait,而没有先设置过期时间。

  2. 您使用 io_service.run_one() 而无需调用 io_service.reset()。

我不确定第一个是做什么的,但第二个是什么意思,一旦 run_one() 第一次返回(通过发布任何处理程序或停止蜂鸣),它会在每次再次调用时立即返回,没有做好它的工作。

可能第一个调用您的超时处理程序带有 operation_aborted,第二个点阻止您的 io_service 做任何其他事情。

编辑:也有问题

    do{
m_ioService.run_one();
}while(ec == boost::asio::error::would_block);

如果你想让 run_one() 方法改变 ec,你必须像这样传递它:run_one(ec)实际上,ec 是该方法中的局部变量,不应被任何内容修改,因此始终保持 would_block。当然,在那种情况下,run_one 将不再抛出任何东西,而是将其结果存储在 ec 中。

关于c++ - Boost UDP async_receive_from 不等待超时或接收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20236953/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com