返回列表 发新帖

http协议之chunked解析

194.5k 8
swmozowtfl 发表于 2015-7-10 20:44:48|湖北 | 查看全部 阅读模式
网上使用chunked编码的网站似乎并不是很多,除了那些使用gzip压缩的网站,例:google.com,还有就是大部分打开gzip压缩的php论坛。
; j/ ~- e0 b. A6 H3 a- d* q根据本人的理解,使用chunked编码的主要好处就在于一些程序的运算出过程中,可以动态的输出内容。
7 ?- w8 C+ Q" D/ v/ u例如,要在后台处理一个小时的运算,但又不希望用户等一个小时才能看到结果。这时就可采用chunked编码将内容分块输出,用户随时都可以接收到最新的处理结果。. ]- q; N7 i& ?6 t8 G) M
asp关闭了缓存的输出模式,就是chunked编码的。(response.buffer = false)9 B- e: z8 `2 k
而每一次的response.write,都是一个chunked,所以不要使用的太频繁哦,否则chunk数量太多,额外的数据太浪费空间了。& [. z$ s+ K6 \6 l2 `9 ^
若想了解chunked的具体编码结构,用asp关闭缓存调试蛮方便的。:)- r  u. b: E2 s; ?7 @) b
我们先来看看rfc2616中对chunked的定义:
4 `. ^5 D/ U9 k7 [chunked-body = *chunk& N4 q  J/ i/ H( l2 t2 O' _9 H# R
last-chunk
3 A9 D$ a4 c  D: ^% [- Otrailer6 s* I' S3 F( X2 c+ ~4 M5 T% V: n
crlf
: E" @. z, ^5 S- \' [chunk = chunk-size [ chunk-extension ] crlf) R5 x6 p% p- O4 J  o4 ]9 d$ _- U7 B
chunk-data crlf
/ A  ]; U( a. k; P: vchunk-size = 1*hex
9 x5 m6 o9 R! i: }2 k) @! glast-chunk = 1*(0) [ chunk-extension ] crlf" d5 a& V0 Y/ \$ j6 I1 k% Y7 X, Q: M
chunk-extension= *( ; chunk-ext-name [ = chunk-ext-val ] ), q9 G% A) q, p  \% E6 z
chunk-ext-name = token
2 ]- H# E  g7 \$ cchunk-ext-val = token | quoted-string+ G# N9 |: x- z4 h  O. c6 V5 O
chunk-data = chunk-size(octet)$ |0 U! d% M  }. A6 ^$ p; ^7 G
trailer = *(entity-header crlf)! N' a% T- c" y) a' q$ l. S6 `: E
我们来模拟一下数据结构:' B5 |( y, O9 h* m& }6 J
[chunk大小][回车][chunk数据体][回车][chunk大小][回车][chunk数据体][回车][0][回车]8 R% J  @+ M" a6 S' [5 `
注意chunk-size是以十六进制的ascii码表示的,比如86ae(实际的十六进制应该是:38366165),计算成长度应该是:34478,表示从回车之后有连续的34478字节的数据。$ p$ B* k0 _* L% H7 j
跟踪了的返回数据,发现在chunk-size中,还会多一些空格。可能是固定长度为7个字节,不满7个字节的,就以空格补足,空格的ascii码是0x20。
( l' w0 d, o" L9 Q- q4 Q" t- M以下是解码过程的伪代码:% \$ U) x/ {* h& ^! _3 h
length := 0//用来记录解码后的数据体长度% |1 P- w. k0 n4 R% g) k
read chunk-size, chunk-extension (if any) and crlf//第一次读取块大小4 U6 R& w& Z9 y: a6 \! E# Q/ t3 i( S
while (chunk-size > 0) {//一直循环,直到读取的块大小为0! Y, {- @1 R7 P! K0 r3 i6 }9 t
read chunk-data and crlf//读取块数据体,以回车结束
5 R4 t! S1 e' v# P3 _+ H0 [7 Lappend chunk-data to entity-body//添加块数据体到解码后实体数据
, k+ }- p( O& ^% {, hlength := length + chunk-size//更新解码后的实体长度5 c7 o$ p% d& E- @; }: `9 d
read chunk-size and crlf//读取新的块大小
0 }; o) ?  `/ q' O- K! P7 C}2 `  U: l6 l, h+ V# A# `
read entity-header//以下代码读取全部的头标记7 b- s" E6 v: M7 C  J' G5 W! z
while (entity-header not empty) {
0 E. M2 r+ H0 C1 Q' }; ]append entity-header to existing header fields2 z% c& Z" F" |$ [+ ?8 U: x
read entity-header
9 u  t& L+ N$ F: h  @% i}; P+ G% x. l$ V4 F0 [
content-length := length//头标记中添加内容长度4 f3 U" [# o4 i( R
remove chunked from transfer-encoding//头标记中移除transfer-encoding1 Y- L' Q6 `0 ]5 A2 a4 u
有空再研究一下gzip+chunked是如何编码的,估计是每个chunk块进行一次gzip独立压缩。2 c% d" j' u* @9 V
使用了chunked,自然会在性能上稍微打点折扣,因为比正常的数据体多出了一些额外的消耗。) H7 U, s3 Q9 t
但是有一些情况下,必需要使用分块输出,这也是不得已而为之.: f4 A: L9 U; M8 E& r5 S

5 p0 L" G1 x( D5 S# N+ V& s更多网页制作信息请查看: 网页制作

回复|共 8 个

gevaemaidovef 发表于 2016-3-24 15:23:38|Reserved | 查看全部
楼猪.重量级人物阿.
Mqokjdvq 发表于 2016-3-24 15:24:17|加拿大 | 查看全部
笨点也好~~~~
seazvyt 发表于 2016-3-24 15:24:19|英国 | 查看全部
我又回复了
tohme 发表于 2016-3-24 15:24:27|韩国 | 查看全部
cd:遮~~~~~~
tohme 发表于 2016-4-1 11:59:35|美国 | 查看全部
这话从何说起那~~~
buingeEvineus 发表于 2016-4-1 11:59:36|美国 | 查看全部
唉!猪!你怎么了?
GoodyFouppy 发表于 2016-4-1 12:00:15|美国 | 查看全部
这就是我斗胆的一点粗略分析,每天睡觉以前,我都会把您的帖子再三拜读,拜读。
bqtklouu 发表于 2016-4-1 12:00:44|美国 | 查看全部
你该这么说~~

回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

得知互动是一个融创意、设计、开发、营销、生活、互联网于一体的专业交流分享平台。
Copyright © 2026 得知互动-专注Ai与站长技术交流社区-Ai交流平台 版权所有 All Rights Reserved. Powered by Discuz! X5.0 鄂ICP备15006301号-5|鄂公网安备 42018502006730号
关灯 在本版发帖 扫一扫添加QQ客服 返回顶部
快速回复 返回顶部 返回列表