我现在正在写一个C++程序,它使用UDP发送和接收与硬件设备的消息。这个程序在Windows上运行得很好,但是当我把同样的代码放在Linux(Ubuntu 22.04 LTS)上时,它运行得很差。它有时可以接收数据包,但在大多数情况下,它什么也没有收到。
下面是我的部分代码:
JULidar::JULidar(const std::string& local_ip, const std::string& local_port,
const std::string& device_ip, const std::string& device_port)
: io_context(),
socket(io_context),
local_endpoint(boost::asio::ip::address::from_string(local_ip), std::stoi(local_port)),
device_endpoint(boost::asio::ip::address::from_string(device_ip), std::stoi(device_port)),
receive_thr(&JULidar::receive_thread, this),
process_thr(&JULidar::process_thread, this),
output_flag(false),
param_pkg_operated_completed(false),
frame_update_completed(false)
{
try
{
std::cout << "binding local ip ..." << std::endl;
socket.open(boost::asio::ip::udp::v4());
socket.bind(local_endpoint);
asyncRecvFrom();
}
catch (boost::system::system_error)
{
std::cout << "local network config error, please modify the ip & port above." << std::endl;
}
}
JULidar::~JULidar()
{
socket.close();
io_context.stop();
receive_thr.interrupt();
receive_thr.join();
process_thr.interrupt();
process_thr.join();
}
void JULidar::asyncRecvFrom()
{
boost::system::error_code error;
socket.async_receive_from(
boost::asio::buffer(udpBuffer),
device_endpoint,
boost::bind(
&JULidar::recvHandler,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void JULidar::recvHandler(const boost::system::error_code& error, size_t bytes_received)
{
if (bytes_received != 0)
{
// ...
}
asyncRecvFrom();
}
void JULidar::receive_thread()
{
while (1)
{
try
{
io_context.run();
boost::this_thread::interruption_point();
}
catch (...)
{
break;
}
}
std::cout << "recv_thr ending..." << std::endl;
}
我创建了一个线程来运行io_context,并不断接收来自设备端点的消息。每次数据包到达时,函数recvc()都会做一些事情。它在Windows上的工作正如预期的那样。为什么它不能在Linux上运行?
真的很感谢任何人可以帮助!!!
这将是伟大的,如果该计划可以工作,因为它如何在Windows上工作。
1条答案
按热度按时间3z6pesqy1#
1.您正在以一种非典型(“错误”)的方式使用执行上下文。例如,在此循环中
整个
interruption_point()
只有在io_context.run()
预期用完工作时才有用。如果这是真的,那么代码就错了,因为io_context.restart()
(或以前的reset()
)从未被调用,而这是必需的。1.还有一个问题是,在套接字被打开/第一次发布之前就创建了线程。这意味着
io_context
可能已经立即用完了工作,即。在工作开始之前。请记住,UDP不能保证传输,所以如果您的机器“忙碌”,一些数据包丢失是可以预料的。
我会使用一个工作保护来重写逻辑,以 * 避免 * 上下文工作不足:
Live On Coliru
本地演示