【问题标题】:boost::asio::async_read_until doesn't get complete packet [closed]boost::asio::async_read_until 没有得到完整的数据包[关闭]
【发布时间】:2014-07-12 02:32:50
【问题描述】:

我正在尝试使用 boost::asio::async_read_until 从客户端获取数据包。

boost::asio::async_read_until(socket, buf, 0x78, boost::bind(&Session::ReadHandler, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders: :bytes_transferred));

客户端发送 FE 42 54 89 7B 14 05 78 FE 42 55 89 7B 14 05 78 并使用 async_read_until 我得到 FE 42 54 89 7B 14 05 78。现在,我怎样才能获得数据包的第二部分?在某些情况下,客户端在发送到服务器之前将 2 个或多个数据包连接在一起。

我希望这是可能的,非常感谢!

编辑 1 我的代码

boost::asio::ip::tcp::socket socket;
boost::asio::streambuf buf;

void Session::Read()
{
    boost::asio::async_read_until(socket, buf, 0x78, boost::bind(&Session::ReadHandler, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}

void Session::ReadHandler(const boost::system::error_code &error, std::size_t bytes_transferred)
{
    if (!error)
    {
        boost::asio::streambuf::const_buffers_type data = buf.data();
        std::string packet(boost::asio::buffers_begin(data), boost::asio::buffers_end(data));
        buf.consume(buf.size());
    }
    else
    {
        socket.close();
    }
}

【问题讨论】:

  • 请阅读以下帮助链接,了解如何以人们可以提供帮助的方式提问——stackoverflow.com/help/mcvestackoverflow.com/help/on-topic
  • 因为你提到了数据包而不是数据流,ip::udp::socket不符合AsyncReadStream类型要求,所以你不能使用async_read_until

标签: c++ boost boost-asio packet


【解决方案1】:

async_read_until 完全按照它所说的那样做:检索数据直到条件为真,在您的情况下,直到检索到 0x78

如果您想获取更多数据,请在同一个缓冲区上执行另一个async_read_until

如果您使用的是 UDP(因此“数据包”实际上存在),那么请使用适用于数据包的东西,例如 async_receive_from

编辑:查看代码(仍然不是可编译的示例),它至少需要使用bytes_transferred 从缓冲区读取数据并消耗掉读取的内容,它需要在退出前执行另一个async_read_until

【讨论】:

  • 感谢您的回答,但我仍然不明白如何解决问题.. async_read_until 可以完美地获得 FE 42 54 89 7B 14 05 78.. 现在问题来了!如果我执行另一个 async_read_until 它没有得到 FE 42 55 89 7B 14 05 78 但跳过这个跳转到下一个数据包..我不知道数据包的实际大小,因为它总是在变化,我不知道在什么情况下客户端将 2 个数据包合二为一。我使用的是 TCP 协议。
  • @INIM 也许您想修改您的数据包以包含一个标志,指示更多即将到来或它是最后一个数据包。然后执行 { read_until } while(packet.flag != LAST);
  • 谢谢,但我想你还没有理解我的问题.. 这是客户端发送的数据包i.imgur.com/Ss2UhZa.png 这是 async_read_until 返回的内容 FF 16 D1 FA 7B 11 12 78 FF 16 D1 0A 7A 12 78 部分被跳过..循环不是问题..问题是当我得到多个分隔符时,async_read_until 只返回第一部分..是有解析完整数据包的方法吗?还是需要我逐字节获取字节并检查它?
  • @INIM 听起来像是一个完整的最小示例。根据我的经验,async_read_until 不会跳过任何内容。
  • 那么我不知道是什么问题,因为服务器继续获取数据包但是(我已经说过 3 次)如果在一个数据包中有超过 1 个分隔符,它只会得到第一部分。 . 我在第一篇文章中添加了我当前的代码..
猜你喜欢
  • 2011-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-22
  • 1970-01-01
  • 1970-01-01
  • 2017-04-04
  • 1970-01-01
相关资源
最近更新 更多