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 回答