【问题标题】:boost asio detecting / avoiding reception buffer overflowboost asio 检测/避免接收缓冲区溢出
【发布时间】:2018-07-26 02:47:13
【问题描述】:

假设客户端使用 TCP 向服务器发送数据,使用 boost::asio,在“同步模式”(也称为“阻塞”功能)。

客户端代码(略过查询和io_service部分):

tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::socket socket( io_service );
boost::asio::connect( socket, endpoint_iterator );
std::array<char, 1000> buf = { /* some data */ };
size_t n = socket.send( boost::asio::buffer(buf) );

这会将整个缓冲区(1000 字节)发送到连接的机器。

现在是服务器代码:

tcp::acceptor acceptor( io_service, tcp::endpoint( tcp::v4(), port ) );
tcp::socket socket( io_service );
boost::system::error_code err;
std::array<char, 500> buff;
size_t n = socket.read_some( boost::asio::buffer(buff), err );
std::cout << "err=" << err.message() << '\n';
  • 这是做什么的:客户端通过连接发送 1000 字节,服务器尝试将其存储在 500 字节缓冲区中。
  • 我所期望的:服务器错误状态表明缓冲区太小和/或接收到的数据过多。
  • 我得到的结果:“成功”错误值,并且服务器中的 n=1000。

我在这里错过了什么? ASIO 不能检测缓冲区溢出吗? 我应该继续使用其他一些类/函数(可能是流吗?)

Refs(对于 1.54,这是我使用的):

【问题讨论】:

    标签: c++ networking boost boost-asio


    【解决方案1】:

    您确实收到了 500 个字节,并且可以通过再次调用 asio 来读取最后 500 个字节。只是这么说,在我看来你误解了 asio 的行为。

    【讨论】:

      【解决方案2】:

      你严重误解了 TCP。

      TCP 是一个字节流。 TCP 流内部没有数据包边界。在您关闭套接字之前,所有字节都会形成一个流。 (与 UDP 不同)

      Boost.Asio 知道这一点。只要流是开放的,就不能说流最终会有多大。如果你有一个 500 字节的缓冲区,Boost Asio 可以用 TCP 流的前 500 个字节填充它。

      但是,read_some 只是查看已经可用的内容。在您的情况下,只有 1000 个字节,完全可以预期您的网卡上可以使用全部 1000 个字节。那部分没有错误。它只是不适合您的缓冲区,但这在网络端不是问题。

      TCP 和 UDP 都没有办法回复接收者期待更小的数据包。那是应用程序级别的逻辑,您可以在应用程序级别处理它。例如,HTTP 有413 Payload Too Large。因此,Boost.Asio 不提供标准机制。

      【讨论】:

      • 感谢您的回答。我对 TCP 没意见,问题是我不明白为什么 ASIO 不能 count 传入的字节并将其与提供的缓冲区的大小进行比较。 FWIW,我也尝试了函数的第二种形式:socket.read_some( boost::asio::buffer(buff,500), err );:类似的行为。
      • @kebs:正在计算它们。 Asio 不会在您的数组之外写入。它知道std::array&lt;char,500&gt; 是 500 字节。手动指定没有意义,这确实不会改变任何事情。第二种格式可能很有用,例如如果您只想使用 500 字节缓冲区的前 400 字节,则将 100 字节用于其他目的。
      • 为了清楚起见(从答案的最后 § 开始),我不是要求将溢出事件传达给客户端,只是在本地检测它!
      • 所以 ASIO 正在计算字节数,但它不会向用户代码发出溢出信号,尽管它有所有需要的信息。好吧,我想这背后有一个基本原理,对我来说似乎很奇怪。所以我想我必须定义一个两步协议,第二条消息的大小包含在第一条消息中。
      • @kebs:看看 HTTP Content-Length。您可能正在重新发明轮子。
      猜你喜欢
      • 2013-02-10
      • 1970-01-01
      • 1970-01-01
      • 2013-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-19
      相关资源
      最近更新 更多