Boost Asioを使用して、シリアル ポートから可変長メッセージを読み取りたいと考えています。回線がアイドル状態であることを確認するのに十分な時間、読み取りと待機をしたいのですが、完全にブロックしたくありません。
次のコードは私がこれまでに持っているもので、テスト中です。
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 でこれを行う (つまり、回線がアイドル状態になるまで読み取る) 正しい方法であるかどうかを知りたいですか?
ここに私のコールバックハンドラがあります:
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&);
};