Http chunk介绍

总结:
HTTP 1.1时,Response要嘛通过Content-Length来指定要传输的内容大小,要嘛通过Transfer-Encoding: chunked来传输动态大小的内容,此时要求Response传输的内容要符合chunk encoding的规定。
从抓包的角度来说,两个请求如果HTTP 参数(Head和Body)都相同的话,是等价的,不管请求是从浏览器还是Java代码发出来的。

CRLF -- Carriage-Return Line-Feed回车换行 回车(CR, ASCII 13, \r) 换行(LF, ASCII 10, \n)。
carriage ['kæridʒ] n. 运输;运费;四轮马车;举止;客车厢

HTTP1.1默认 支持长连接(持久连接),长连接避免为每个请求都创建各自的连接,而是多个请求使用一个已经建立好的连接。如果每个HTTP请求都进行set up和tear down,这对于性能损失是非常严重的。
在长连接中,每次传输的长度必须都被计算的非常精确。如果在http头中以Content-Length来标记请求request或者响应response的大小,客户端或者服务器就只会从流中读取 Content-Length指定大小的字节,然后表明本次传输结束。使得下一次客户端请求以及服务器端响应 继续使用这个相同的socket连接成为可能。

在交互式应用程序中有1个问题,就是它并不知道将要传输的数据有多大。
在HTTP1.0中,服务器就会省略response头中的Content-Length而持续写数据出去,当服务器挂了的话,它简单地断开连接。而经典的HTTP客户端会一直读数据直到碰到-1(传输结束的标识符)。
为了处理这个问题,HTTP1.1中增加了一个特殊的header: Transfer-Encoding:chunked,允许响应response被分块chunked。每次向连接写数据的时候会先计算大小,最后在response的尾部以一个0长度的chunk块标志着此次传输的结束。即HTTP1.1支持chunked编码,它允许HTTP消息被分成多块后再进行传输。 Chunking一般用在服务器响应response的时候,但是客户端也可以chunk大的请求request。 即Chunk编码允许服务器在发送完Header后,发送更多的Body内容。

Chunked编码使用若干个Chunk块串连而成, 每个Chunk块都以一个表明chunk快大小的16进制数字和一个额外的CRLF(回车换行)开始,后面跟着指定大小的内容。即每个Chunk块分为头部和正文两部分,头部内容指定下一段正文的字符总数(十六进制的数字)和数量单位(一般不写),正文部分就是指定长度的实际内容,两部分之间用回车换行(CRLF)隔开。 最后以一个长度为0的Chunk表明本次传输结束 。
1个典型的Chunk传输例子:
Html代码 复制代码  收藏代码
  1. C\r\n   
  2. Some data...   
  3. 11\r\n   
  4. Some more data...   
  5. 0\r\n  
C\r\n
Some data...
11\r\n
Some more data...
0\r\n

上述消息内容包含2个chunk块,第一个块是12字节长度(hex C),第二个块是17字节长度(hex 11)。

Java中减少Chunk数量的一种方法是不要适应flush(),只使用1个write()方法来输出所有内容。如果被输出的内容大小大于output的buffer大小,那么输出还是会被chunk,但是不使用flush()方法还是可以有效地减少不必要的chunking。

在有些情况下,有些客户端或者服务器只能处理老的HTTP1.0的行为。此时,应该使用 Connection: close的header来通知接收部分不要使用长连接。
Connection: keep-alive表明可以使用长连接。

参考: HTTP Chunking





相关解决的问题:
Axis2 RPC客户端默认根据Content-Length的大小来读取Response,而相应的Web Service使用chunked encoding的方式来传输,因此报错。通过设置参数来通知服务器不使用Chunk编码来解决。
Axis2 客户端调用时报【Transport error: 411 Error: Length Required】


CRLF、missing CR这2个错误都表明返回的Response内容不正确。
即返回的Response Header头中指定了Transfer-Encoding:chunked,但是传输的Response内容却不符合HTTP 1.1 RFC中对于chunked的规定。
因此在apache http client包通过以下2种不同的方法调用Request后,做解码操作时,在某个读取某个chunk时,读取根据CRLF标识符前面指定的字节数后,紧跟着应该是下一个Chunk,而读下一个Chunk时,发现CRLF前面的字符并不是16进制的数,即返回的Response不符合Chunking中对于分块的规定,所以报错。
Java代码 复制代码  收藏代码
  1. java.io.IOException: CRLF expected at end of chunk: 47/109  
  2.     at org.apache.commons.httpclient.ChunkedInputStream.readCRLF(ChunkedInputStream.java:207)   
  3.     at org.apache.commons.httpclient.ChunkedInputStream.nextChunk(ChunkedInputStream.java:219)   
  4.     at org.apache.commons.httpclient.ChunkedInputStream.read(ChunkedInputStream.java:176)   
  5.     at java.io.FilterInputStream.read(Unknown Source)   
  6.     at org.apache.commons.httpclient.AutoCloseInputStream.read(AutoCloseInputStream.java:108)   
  7.     at java.io.FilterInputStream.read(Unknown Source)   
  8.     at org.apache.commons.httpclient.AutoCloseInputStream.read(AutoCloseInputStream.java:127)   
  9.     at org.apache.jmeter.protocol.http.sampler.HTTPSampler2.sample(HTTPSampler2.java:853)   
  10.     at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1038)   
  11.     at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1022)   
  12.     at org.apache.jmeter.threads.JMeterThread.doNormalSample(JMeterThread.java:292)   
  13.     at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:351)   
  14.     at java.lang.Thread.run(Unknown Source)   
  15.   
  16.   
  17. java.io.IOException: missing CR   
  18.     at sun.net.www.http.ChunkedInputStream.processRaw(Unknown Source)   
  19.     at sun.net.www.http.ChunkedInputStream.readAheadNonBlocking(Unknown Source)   
  20.     at sun.net.www.http.ChunkedInputStream.readAhead(Unknown Source)   
  21.     at sun.net.www.http.ChunkedInputStream.available(Unknown Source)   
  22.     at java.io.FilterInputStream.available(Unknown Source)   
  23.     at java.io.BufferedInputStream.read(Unknown Source)   
  24.     at java.io.FilterInputStream.read(Unknown Source)   
  25.     at org.apache.jmeter.protocol.http.sampler.HTTPSampler.readResponse(HTTPSampler.java:260)   
  26.     at org.apache.jmeter.protocol.http.sampler.HTTPSampler.sample(HTTPSampler.java:480)   
  27.     at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1038)   
  28.     at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1022)   
  29.     at org.apache.jmeter.threads.JMeterThread.doNormalSample(JMeterThread.java:292)   
  30.     at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:351)   
  31.     at java.lang.Thread.run(Unknown Source)  
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
nginx-http-flv-module 是一个支持 HTTP-FLV 协议的 nginx 模块,用于实现直播媒体服务。下面是 nginx-http-flv-module 的详细安装程: 1. 安装 nginx 首先需要安装 nginx。可以使用 apt-get、yum 或者从源码编译安装 nginx。 2. 下载源码 可以通过 GitHub 下载源码: ``` git clone https://github.com/winshining/nginx-http-flv-module.git ``` 3. 编译安装 nginx 进入 nginx 源码目录,执行 configure 命令,加入 nginx-http-flv-module 模块: ``` ./configure --prefix=/usr/local/nginx --add-module=/path/to/nginx-http-flv-module ``` 然后执行 make 和 make install 命令进行编译安装。 4. 配置 nginx 编辑 nginx 配置文件 nginx.conf,添加以下配置: ``` rtmp { server { listen 1935; chunk_size 4096; application live { live on; record off; # HLS hls on; hls_path /usr/local/nginx/html/hls; hls_fragment 3; hls_playlist_length 60; # HTT-FLV flv_live_buffer 1m; flv_live_max_buffer 4m; flv_socket_buffer 512k; flv_timeout 10s; } } } http { server { listen 80; server_name localhost; # HLS location /hls { types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; } root /usr/local/nginx/html; add_header Cache-Control no-cache; } # HTTP-FLV location /live { flv; chunked_transfer_encoding on; } } } ``` 其中,rtmp 部分用于配置 RTMP 服务,http 部分用于配置 HTTP 服务。 5. 启动 nginx 执行以下命令启动 nginx: ``` /usr/local/nginx/sbin/nginx ``` 至此,nginx-http-flv-module 的安装配置完成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值