增强ASIO TCP消息分离

Boost ASIO TCP separation of messages

本文关键字:分离 消息 TCP ASIO 增强      更新时间:2023-10-16

我刚刚开始使用Boost ASIO库,版本1.2.0。我使用TCP/SSL加密与异步套接字。从这里关于ASIO的其他问题来看,ASIO似乎不支持接收可变长度消息,然后将该消息的数据传递给处理程序。

我猜ASIO将数据放入循环缓冲区并丢失每个单独消息的所有跟踪。如果我错过了一些东西,ASIO确实提供了一种传递个人消息的方法,那么请告知如何。

我的问题是,假设我不能以某种方式获得与单个消息相关的字节,我可以在async_read中使用transfer_exactly来获得前4个字节,我们的协议总是放置消息的长度。然后调用read或async_read(如果read不能与异步套接字一起工作)来读取消息的其余部分?这能行吗?有更好的方法吗?

通常我喜欢把我在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));
}