【问题标题】:Boost iostreams: How to create buffered (for reading) TCP stream?Boost iostreams:如何创建缓冲(用于读取)TCP 流?
【发布时间】:2012-03-02 23:34:27
【问题描述】:

所以我的主要问题是如何在 asio tcp::socket 或 tcp::iostream 之上实现一个结构来实现some kind of input-seekable filter

缓冲高达1kb?

【问题讨论】:

  • 一个问题是很难在异步套接字上使用流。例如,您从流中读取一个字符串,直到缓冲区中没有更多字符串。但是你(或流)怎么知道它是否真的是字符串的结尾呢?其余的可能会在另一个数据包中,并且无法知道何时或是否会交付。
  • 出于好奇,您看过这个吗? stackoverflow.com/questions/3668128/…
  • @JoachimPileborg:这非常容易知道 - 直到您到达流的末尾或套接字上的错误。其余的是严重依赖于使用的高级协议的业务逻辑。话虽如此,缓冲是必需的,但是为此使用 C++ iostream 是脑死的。出于这个原因,Libevent 提供了很好的通用缓冲区 API。
  • 你不能有一个可搜索的流,因为你必须阅读整个响应才能搜索结束,然后数据将不可用。因此,您的缓冲区必须与要搜索的位置一样大。
  • 漂亮的图表,但这不是一个特别好的 SO 问题,当然也不值得 12 分。你试过什么?

标签: c++ boost boost-asio iostream


【解决方案1】:

我认为像“转到流的末尾”这样的东西对于 TCP 连接是不可能的。 像这样的调用(参见下面的代码)是否应该等待(阻塞)连接关闭?当响应达到缓冲区大小(例如 1Kb)时,它应该如何存储响应?

s.seekg (0, ios::end);

因此,通常很难(/不可能?)实现可搜索的 TCP 流。即使您有无限的缓冲区(不仅仅是 1Kb)。

当设置 Content-Length 标头时,应该可以为 HTTP(S) 等特定协议实现类似 input-seekable 的功能。但在这种情况下,除非您使用 HTTP/1.1 Range 标头,否则 1Kb 的固定大小缓冲区将不起作用。

也许有帮助: Christopher M. Kohlhoff(Boost asio 的作者)实现了Urdl(在 SourceForge 上标记为“Prealpha”),他将 HTTP 连接建模为 istream。我认为 read_some 方法对您来说可能很有趣:https://github.com/jnorthrup/urdl/blob/master/include/urdl/detail/http_read_stream.hpp#L426

【讨论】:

    【解决方案2】:

    我不熟悉这个特殊的 boost 模块。但是,如果您正在寻找一种方法来创建一个类似于存储库的缓冲区,我会创建另一个线程来管理它。该线程可以 LIFO 传入流,处理过滤器请求和缓冲区管理。将其保存在单独的线程上意味着它会在系统缓冲区用完之前注意传入的数据包,因此您不必担心会丢失任何内容。可以创建消息队列以在线程之间进行调解。

    也就是说,最终可能最简单的方法是使用预先编写的库来处理它并为自己节省一点时间。查看this post

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-06
      • 2016-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-19
      • 2011-09-19
      • 2012-09-07
      相关资源
      最近更新 更多