作者回复: 在http层是看不到tcp的,它不知道下层协议是否会分块,下层是否分块对它来说没有意义,不关心。
在http里一个报文必须是完整交付,在处理大文件的时候就很不方便,所以就要分块,在http层面方便处理。
chunked主要是在http的层次来解决问题。
作者回复: 举个例子,从GitHub上下载源码包,GitHub要实时压缩实时发送,而不是一下子压缩好再发送,这样body的长度一开始就是未知的。
所以就要用分块编码,压缩一部分,就发一部分,这部分的长度是已知的,但总长度只有压缩完才能知道。
chunked编码用在“流式”收发数据的时候,通常数据是即时生成的,也就是动态数据。
作者回复: http传输永远是一个请求一个响应的工作模式,只是响应是chunked分块,body数据不是一次性发过来的,而是分批分块发送,但仍然是在一个报文里。
客户端发送请求后等待响应,服务器组织数据,分块发送,最后一个分块是结束标志。客户端依次接收分块,收到结束标志后就把数据拼成完整的报文。
作者回复: 1正确。
2需要分情况,看原文件是什么形式。如果原来的文件是gzip的,那就正确。如果原文件是文本,而是在传输过程中被压缩,那么就应用于压缩前的数据。
总之,range是针对原文件的。
作者回复:
1.网络视频不一定用的就是http协议,也可能是其他的专用协议,所以不能简单地判断就是分块传输。如果是http协议,对于大文件通常都是range请求,也不一定用chunk分块。
2.是的,这是由http的请求-应答工作模式决定的。不管是不是chunk,只要响应没有结束,这个来回就不会完成。
3.也可能用的是其他协议。
4.应该是range的分段,不是chunk,chunk只是在传输过程中分块,最后到客户端会是一个完整的文件。
5.视频文件的分段计算比较复杂,课程里面只是作为简单的示例,实际情况不一定就是这么简单。
6.分段的range和分块的chunk是两个完全无关的概念,不要弄混了。chunk是传输时分成小块逐个发送,range是取大文件中间的一部分。
7.不客气,后面的https、http/2也继续努力吧。
作者回复: 1,是的,通过多线程并发下载,提高下载速度。
2,范围可以不连续,例子里就是这样。
3,客户端上传的时候也可以用chunked、gzip,但不能用range。
注意这些字段的类型,只要是实体字段,那就在请求响应里都可以用。
作者回复: 说的很好。
作者回复: 1,计算范围从0开始计数,用的是C语言惯例。
2,浏览器的技术不是很清楚,抱歉了。
作者回复: 就是按照格式分成一些片段,逐块发送,浏览器收到后去掉分隔符,再拼成原来的样子。
作者回复: 1不对,前面已经有同学回答了,因为分块包含了长度,所以回车换行不影响。
2需要分情况,看原文件是什么形式。如果原来的文件是gzip的,那就正确。如果原文件是文本,而是在传输过程中被压缩,那么就应用于压缩前的数据。
总之,range是针对原文件的。
作者回复: 流式数据就是stream,虽然还是用一个个的chunk发过来的,但从更高层次上看,它像是从源头持续不断地、慢慢地“流”过来的,而不是一次性、一整块发过来的。
可以对比一下tcp和udp,tcp是流式数据,而udp是一个个的数据包。
作者回复:
1.请参考一下讲长连接的那一讲,现在的http请求应该都是使用的长连接,不会每次都重新建立连接,否则效率太低。
2.流式数据就是分块发送,像tcp那样一块一块地发过来,而不是像普通http那样一次完整地全发过来。
3.多段数据可以是mulitpart,每段数据是有可能不同的,比如发出一个请求,服务器返回了一个txt和json,所以要这么做。当然这种情况比较少见,但协议就必须要考虑到这种情况。
作者回复: 服务器掌控数据,有很多办法可以限流限速,不是简单的客户端就能控制的。
作者回复: 这个需要实际测试,http的优势是灵活,相关的工具多,传输效率上都是依赖于底层的tcp,应该差不多。
作者回复: 1不对,因为chunked格式里已经有长度了。
2正确。
看来有不少同学对第二个问题比较迷惑,我再说具体一点。
比如说,有一个1M的纯文本,range请求其中的500K,然后服务器编码为gzip(Content-Encoding: gzip),压缩成200k,浏览器收到后解压缩,就得到了这部分的500k数据。
作者回复: thanks。
作者回复: 只要是用http传输,就会用range,但他们也有可能用自己的协议而不是http,比如rmtp。
作者回复:
1.对。
2.range作用于“原始文件”,如果原始文件是压缩的就请求压缩的部分,如果原始文件没有被压缩,那就是原始部分,传输中的压缩不影响。
你理解的很对。
作者回复: 标准规范里没有限制,但不宜太大,过大就失去了分块的意义。