3

Boost ASIO ライブラリのバージョン 1.52.0 を使い始めました。非同期ソケットで TCP/SSL 暗号化を使用しています。ここでASIOについて尋ねられた他の質問から、ASIOは可変長メッセージの受信と、そのメッセージのデータのハンドラーへの受け渡しをサポートしていないようです。

私は、ASIO がデータを循環バッファーに入れ、それぞれの個別のメッセージのすべての追跡を失っていると推測しています。何か見逃しており、ASIO が個々のメッセージを渡す方法を提供している場合は、その方法を教えてください。

私の質問は、個々のメッセージに関連付けられたバイトだけをどうにかして取得できないと仮定すると、async_read で transfer_exactly を使用して最初の 4 バイトだけを取得できるかということです。このプロトコルは常にメッセージの長さを配置します。次に、read または async_read (非同期ソケットで read が機能しない場合) を呼び出して、残りのメッセージを読み込みますか? これは機能しますか?それを行うより良い方法はありますか?

4

1 に答える 1

4

通常、私は async_read で受け取ったデータを取得して boost::circular_buffer に入れ、メッセージ パーサー レイヤーにメッセージがいつ完了したかを判断させ、データを引き出すのが好きです。 http://www.boost.org/doc/libs/1_52_0/libs/circular_buffer/doc/circular_buffer.html

以下の部分的なコード スニペット

boost::circular_buffer TCPSessionThread::m_CircularBuffer(BUFFSIZE);

void TCPSessionThread::handle_read(const boost::system::error_code& e, std::size_t bytes_transferred)
{
    // ignore aborts - they are a result of our actions like stopping
    if (e == boost::asio::error::operation_aborted)
        return;
    if (e == boost::asio::error::eof)
    {
        m_SerialPort.close();
        m_IoService.stop();
        return;
    }
    // if there is not room in the circular buffer to hold the new data then warn of overflow error
    if (m_CircularBuffer.reserve() < bytes)
    {
        ERROR_OCCURRED("Buffer Overflow");
        m_CircularBuffer.clear();
    }
    // now place the new data in the circular buffer (overwrite old data if needed)
    // note: that if data copying is too expensive you could read directly into
    // the circular buffer with a little extra effor
    m_CircularBuffer.insert(m_CircularBuffer.end(), pData, pData + bytes);
    boost::shared_ptr<MessageParser> pParser = m_pParser.lock(); // lock the weak pointer
    if ((pParser) && (bytes_transferred)) 
        pParser->HandleInboundPacket(m_CircularBuffer); // takes a reference so that the parser can consume data from the circ buf
    // start the next read
    m_Socket.async_read_some(boost::asio::buffer(*m_pBuffer), boost::bind(&TCPSessionThread::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
于 2013-01-18T21:16:19.120 に答える