c++ - 网络爬虫在 read() 中下载网页的 recv 缓冲区应该有多大?

标签 c++ sockets http buffer httprequest

我正在用 C++ 编写一个网络爬虫,想找出读取 http 请求响应的最佳方法。

目前我正在使用一个 1M 大小的缓冲区来包含 read() 中的 recv 消息(read() 的计数是 4K 字节)。这是我要抓取的网页的最大尺寸。然而,这是一种浪费,所以我也在考虑以下其他方法:

  1. 第一轮发送http HEAD请求,从header中读取content-length信息。创建一个大小为 content-length 的字符数组,然后发送 http GET 以检索内容。
    Q1:如果来自服务器的header信息没有content-lenght怎么办?
    Q2:这种方法使网络流量翻倍。付出这样的开销值得吗?

  2. 直接发送 http GET 并使用较小的缓冲区(例如 16K 字节)。但在接收到所有数据之前不处理响应,而是在缓冲区已满后处理数据,然后清理缓冲区以接收其余数据。
    Q1: 这样,爬虫可能需要几次迭代才能完整读取大型网页。如果处理工作耗时,同时读取多个网页,网络等待数据是否会超出系统缓冲区而导致丢包?

谢谢。

最佳答案

Currently I'm using a buffer of 1M size to contain the recv message in read() (count is 4K bytes for read()). This is the max size of webpage I would like to crawl. However this is sort of waste

确实如此。无论如何,每次读取操作读取的数据不会超过几 K,因此巨大的缓冲区毫无意义。

Send http HEAD request in the first round and read the content-length info from header. Create a char array with size of content-length and send http GET then to retrieve the content.

那是另一个网络操作。也很浪费。

Q1: What if the header info from server does not have content-length?

不确定这对 HEAD 是否有效,但您必须检查 RFC。

Q2: This approach doubles the network traffic.

不,它没有。它使请求/响应对的数量加倍。这不是一回事。

Is it worthy paying such overhead?

没有。

Send http GET directly and using a smaller buffer (e.g. 16K bytes).

当然。

But not processing the response until all data is received

为什么不呢?为什么不在收到时处理它?这是最好的方法。最小的缓冲区,最低的延迟。

instead processing the data once the buffer is full and then clean the buffer to receive the rest.

您永远不需要清理缓冲区。

Q1: In this way the crawler may need a few iterations to read a large webpage completely

您总是需要迭代才能从网络中读取网页或任何其他内容。 recv() 函数只保证在阻塞模型中传输至少一个字节,除非出现 EOS 或错误。它没有义务填充缓冲区,除非您的套接字接收缓冲区也是 1M 并且您在读取之间浪费了足够的时间,否则它已经填充了。如果您正确编程,就不会发生这种情况。

If the processing job is time-costly and multiple webpages are being read at the same time, could the waiting data from network exceeds system buffer and cause packet loss?

不在 TCP 中。这只会导致发件人停顿并浪费时间。

关于c++ - 网络爬虫在 read() 中下载网页的 recv 缓冲区应该有多大?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23102726/

相关文章:

c++ - 检查 C++ 中是否只有一个字符串变量不是 nullptr

c++ - Listwidget 中的右键

c++ - 序列化优于 sockets c++ 的优势

http PUT 请求在 golang 中上传 zip 文件

c++ - 为什么会出现错误 "no matching function for call to ' A(A<...auto...> )'"?

C++:不允许 void 的部分函数特化 - 替代解决方案?

javascript - 断开或重新加载时Io套接字重置连接

python - select() 在 python 套接字中可以管理多少个文件描述符?

rest - 未处理的异常:类型 'int'不是类型转换中类型 'String'的子类型

python - HTTP 下载非常大的文件