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

发布于 2022-09-01 18:52:47 字数 2493 浏览 28 评论 0

通信采用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));
        }
    }
}

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

将军与妓 2022-09-08 18:52:47

CMemBlock 的 Length没有计算正确导致的。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文