关于HTTP判断文件是否下完的方法,查了下资料,差不多有3种:


1,有content-length
解决办法: 根据长度读取就行了
2,transfer-encoding:chunked
解决办法: 根据chunk编码实现协议栈。
一般来说HTTP 1.1都会设置此项,如果设置了Transfer-Encoding,那么Content-Length将被忽视(没有或不起效果)
这种方法指的是HTTP包按照固定的格式来组合,"Transfer-Encoding: chunked"是这样编码的:
HTTP头
\r\n
\r\n --连续的两个\r\n之后就是HTTP体了
16进制值代表的数据长度
\r\n
上面所指的数据长度
\r\n --每段数据结束后,以\r\n标识
16进制代表的第二段数据
\r\n
XX长度的数据
\r\n
………… (反复通过这样的方式表示每次传输的数据长度)
0 --数据结束部分用0表示,然后是连续的两个\r\n
\r\n
\r\n
3,以上2项都没有,但是有connection:close
解决办法: 根据recv返回0(服务器已经断开连接)。
HTTP 1.0没有keep-alive这概念,每次服务器完成请求处理后立即断开TCP连接。
自己写的demo通过libcurl来实现,我这边测试了下,发现有通过第二种情况来判断的可能,抓包如下
抓包中可以看出在数据传输完后,是客户端这边主动发起FIN关闭连接,这样libcurl就可能是通过content-length或者chunk编码的方式来判断是否文件下完。
log中输出每次libcurl回调读取数据的打印信息,如下
末尾中正好有
0
\r\n
\r\n
的格式,可见存在以chunk编码来判断文件结束的可能。
又查了下实际通过CURLOPT_WRITEDATA保存下来的数据,是没有这chunk编码末尾这一段的,libcurl对chunk编码是有过处理的。同时也存在通过其他两种方法来判断文件结束的可能,具体再看下源码。
CDS(一款HTTP测试品质参数的工具)的last data是通过200 OK最后一条信息来判断,可能是通过数据量达到content-length以及末尾chunk编码格式来判断。
其实根据上面3种判断情况,再考虑到HTTP 1.0和HTTP 1.1的区别,整理下差不多可以得出以下结论(目前测试还没出现之外的情况):
1、在HTTP 1.0及之前版本中,content-length字段可有可无(因为HTTP 1.0每次连接完成任务,服务器都会主动断开连接),完全可以通过第三种方法来判断。
2、在http1.1及之后版本。如果是keep alive,则content-length和chunk必然是二选一,不然没法判断是否结束。若是非keep alive,则和http1.0一样。content-length可有可无。