我目前正在开发一个应用程序,它应该获取一个网页并从其内容中提取信息。
正如我从研究中学到的(至少在我看来),没有理想的方法来确定HTTP消息的结束。
一般来说,我发现了两种不同的方法:
为套接字设置O_NONBLOCK标志,并在while循环中使用recv()获取数据。如果流中没有字节,则假设消息已完成并中断。
依靠HTTP Content-Length标头并用它确定消息的结尾。
这两种方式对我来说似乎并不完全安全。解决方案(1)可能会在消息完成之前中断recv循环。另一方面,解决方案(2)需要正确设置Content-Length标头。
在这种情况下,最好的方法是什么?我是否可以始终依赖Content-Length标头设置?
答案 0 :(得分:0)
让我从这里开始:
不,你不能。我是否可以始终依赖Content-Length标头设置?
Content-Length
是一个可选标头。但是,如果HTTP消息要符合RFC标准,则绝对必须才能确定其长度(cf RFC7230, sec. 3.3.3)。话虽如此,只要未指定内容长度,就可以在chunked encoding上解析。
至于你原来的问题:确保消息的完整性实际上应该是TCP的工作。但是由于存在诸如消息流水线这样复杂的事情,最好在实践中检查两件事:
哦,正如@MartinJames所说,非阻塞可能不是最好的主意。
答案 1 :(得分:0)
定义了HTTP响应的结束:
在前两种情况下,您有一个定义明确的结束,因此您可以验证数据是否已完全接收。仅在最后一种情况下(TCP连接结束),您不知道在发送所有数据之前连接是否已关闭。但通常你会得到案例1或案例2。
答案 2 :(得分:0)
为了让您的生活更轻松,您可能想提供
Connection: close
在发出HTTP请求时标题 - 在给出完整页面请求之后,Web服务器将关闭连接,您将不必处理块。
如果您只对这个页面感兴趣,并且不会请求额外的资源(脚本文件,图像等),那么这只是一个可行的选择 - 在后一种情况下,对于您的应用程序和应用程序而言,这将是一个非常低效的解决方案服务器