0

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&);
};
4

2 に答える 2