如何知道HTTP服务器何时完成数据发送

3
我正在从事一个关于浏览器/代理的项目,需要下载网页。在向Web服务器发送自定义HTTP请求后,我开始监听服务器响应。
读取响应时,我会检查响应头是否包含Content-Length行。如果有这样的行,那么很容易确定服务器何时完成数据发送,因为我始终知道接收到了多少字节的数据。
当服务器没有包含Content-Length头并且仍然保持连接以进行进一步请求时,问题就出现了。例如,谷歌服务器响应具有压缩内容,但不包括内容长度。那么,我如何知道何时停止等待更多数据并关闭连接?
我考虑使用超时值来在一段时间内未收到数据时关闭连接,但这似乎不是正确的方法。例如,Chrome可以像我一样下载相同的页面,并且总是知道何时准确地关闭连接。
3个回答

2
请查看IETF RfC 2616,搜索分块编码和内容范围。
HTTP旨在返回长度未知的内容,例如:
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked

25
This is the data in the first chunk

1C
and this is the second one

3
con
8
sequence
0

source Wikipedia


如果这也适用于压缩数据的话,这似乎是解决它的正确方式(我认为它适用,因为我在一些请求中看到了Transfer-Encoding:头部,但缺少Content-Length)。谢谢! - Accatyyc

1

我建议您尝试强制使用Connection: close头部,这样您就可以确保服务器在输出完成后关闭连接,无论是否设置了Content-length。这样做可能会部分影响性能。


谢谢你的回答。这是我已经尝试过的方法,但很多服务器会忽略它,所以它并不是百分之百可靠的。此外,如果我们查看Chrome发送的请求,我们可以看到它总是使用连接:keep-alive,但仍然知道何时完成。因此,我认为这种方法(即使有时候有效)是解决问题的错误方式。 - Accatyyc
如果服务器忽略连接: close,那么你会遇到大麻烦,需要使用非常短的超时时间(如2秒)。Connection:close要求服务器关闭连接。不关闭连接是违反协议的行为。此外,我可能怀疑Chrome期望</html>标签来确定“它已完成”。 - usr-local-ΕΨΗΕΛΩΝ
我不这么认为,因为在解压缩之前读取压缩文档的HTML标记是没有意义的。看看bew的答案。Chrome通过读取块大小来解决这个问题。 - Accatyyc

0

有两种情况可能会发生: 1. socket关闭 2. socket超时

通常情况下,socket将被关闭,声明Socket超时也是有意义的。

请记住

 int stream.read(byte[],size);

返回已读取到套接字关闭或套接字超时(或达到size-argument)的byte[]参数大小的实际大小。

敬礼。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接