问题描述
我想使用提升Asio 来读取序列中的可变长度消息港口.我想阅读并等待足够长的时间,以确保线路空闲,但我不想完全阻塞.
I would like to use Boost Asio to read variable length messages from the serial port. I would like to read and wait long enough to be sure that the line is idle, but I do not want to block completely.
以下是我到目前为止的代码,我正在对其进行测试:
The following code is what I have so far, and I am in the process of testing it:
long readData(void *_pData, unsigned long _uSize, size_t millis)
{
size_t n = 0; // n will return the message size.
if (millis > 0) // millis is the acceptable idle time, 0 is invalid in my case.
{
size_t uBytesTransferred = 0;
boost::asio::deadline_timer timeout(m_ioService);
ReadCallback readCallback(uBytesTransferred, timeout);
WaitCallback waitCallback(m_port);
while (_uSize - (unsigned long)n > 0)
{
// Setup asynchronous read with timeout
m_ioService.reset();
m_port.async_read_some(boost::asio::buffer((char*)_pData + n, _uSize - (unsigned long)n), readCallback);
timeout.expires_from_now(boost::posix_time::milliseconds(millis));
timeout.async_wait(waitCallback);
// Block until asynchronous callbacks are finished
m_ioService.run();
// Continue if any bytes were received, stop otherwise
if (uBytesTransferred > 0)
{
n += uBytesTransferred;
m_uBytesReceived += uBytesTransferred;
}
else
{
break;
}
}
}
return n;
}
我想知道这是使用Boost Asio执行此操作的正确方法(即读取直到该行空闲)吗?
I would like to know if this is the correct way of doing this (that is, reading until the line is idle) with Boost Asio?
这是我的回调处理程序:
Here are my callback handlers:
struct ReadCallback
{
ReadCallback(std::size_t &_uBytesTransferred, boost::asio::deadline_timer &_timeout)
:m_uBytesTransferred(_uBytesTransferred), m_timeout(_timeout)
{}
void operator()(const boost::system::error_code &_error, std::size_t _uBytesTransferred)
{
m_uBytesTransferred = _uBytesTransferred;
if (!_error && (_uBytesTransferred > 0) )
{
m_timeout.cancel();
}
}
std::size_t &m_uBytesTransferred;
boost::asio::deadline_timer &m_timeout;
private:
ReadCallback();
ReadCallback &operator=(const ReadCallback&);
};
struct WaitCallback
{
WaitCallback(boost::asio::serial_port &_port)
:m_port(_port)
{}
void operator()(const boost::system::error_code &_error)
{
if (!_error)
{
m_port.cancel();
}
}
boost::asio::serial_port &m_port;
private:
WaitCallback();
WaitCallback &operator=(const WaitCallback&);
};
推荐答案
现在使用增强线程从串行端口读取和缓冲数据.现在,我可以将串行数据读取为流,而且还可以窥视,执行非阻塞和阻塞读取.
Now using a boost thread to read and buffer the data from the serial port. I can now read the serial data as a stream, but also have the ability to peek, do non-blocking and blocking reads.
我将串行io包装在boost线程中-只是无法使asio回调按我想要的方式工作.我现在正在缓冲线程中的读取数据,但仍使用阻塞写入来将等待时间保持在尽可能低的水平.
I wrapped the serial io in a boost thread -- just couldn't make the asio callbacks work the way I wanted. I'm now buffering the read data in the thread, but still using blocking writes to keep the latency as low as possible.
这篇关于使用Boost Asio从串行端口读取消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!