使用BOOST的ASIO通信框架,客户端发送给服务端的数据偶尔会出现遗失或者错误。


通信采用ASIO框架,主要问题出现在客户端发送数据给服务端的过程中。
客户端发送数据使用的是如下函数:


 void CNetClient::Send(BYTE *buff, int length)
{
    //CMemBlock是一个可动态扩展的内存块,类似于Vector<char*>
    CMemBlock* pSend = new CMemBlock(length + m_parser.GetHeaderLength() + m_parser.GetTailLength());
    m_parser.AppendHeader(pSend, length);
    pSend->AppendData(buff, length);
    m_parser.AppendTail(pSend);

    Send(pSend);
}


 void CNetClient::Send(CMemBlock* pData)
{
    //m_io_service是客户端使用的boost::asio::io_service对象
    m_io_service.post(boost::bind(&CNetClient::do_write, this, pData));
}


 void CNetClient::do_write(CMemBlock* pSend)
{
    //m_socket是和服务端连接的boost::asio::ip::tcp::socket对象
    boost::asio::write(m_socket, boost::asio::buffer(pSend->GetBuffer(), pSend->GetLength()));

    delete pSend;
}

服务端采用的接收数据方式是:


 void CConnection::Start()
{
    //m_Socket是和客户端连接的boost::asio::ip::tcp::socket对象
    boost::asio::async_read(m_Socket,
        boost::asio::buffer(m_Buffer, m_PacketParser.GetNeedLength()),
        boost::bind(&CConnection::handle_read, this,
        boost::asio::placeholders::error,
        boost::asio::placeholders::bytes_transferred));
}


 void CConnection::handle_read(const boost::system::error_code& err, std::size_t bytes_transferred)
{
    if (!err)
    {
        if (m_PacketParser.Parse(m_Buffer.data(), m_PacketParser.GetNeedLength()) )                 // command has been decoded, to process command
        {
            m_RequestHandler->HandleCommand(&m_PacketParser.GetPacket(), m_Reply);
            m_PacketParser.Reset();
        }
        else
        {
            if(m_PacketParser.GetState()==m_PacketParser.state_parse_header)
            {
                m_PacketParser.GetPacket().Clear();
                m_PacketParser.GetPacket().AppendInt(NETMSG_PARSE_FAILURE);
                m_RequestHandler->HandleCommand(&m_PacketParser.GetPacket(), m_Reply);
                m_PacketParser.Reset();
            }
        }

        {
            boost::asio::async_read(m_Socket,
                boost::asio::buffer(m_Buffer, m_PacketParser.GetNeedLength()),
                boost::bind(&CConnection::handle_read, this,
                boost::asio::placeholders::error,
                boost::asio::placeholders::bytes_transferred));
        }
    }
}

现在遇到的主要问题是:客户端发送的数据有时服务端无法收到或者收到的数据有错误,请教下是哪个地方造成的原因。

asio boost C++

子在川上日 9 years, 4 months ago

Your Answer