<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Computer, Electron and Technology &#187; 网络</title>
	<atom:link href="http://www.donevii.com/post/tag/%e7%bd%91%e7%bb%9c/feed" rel="self" type="application/rss+xml" />
	<link>http://www.donevii.com</link>
	<description>关注技术、移动互联网以及一切 GEEK &#38; NERD 的事情</description>
	<lastBuildDate>Wed, 21 Dec 2011 10:49:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>[转] HTTP协议之Chunked解析</title>
		<link>http://www.donevii.com/post/468.html</link>
		<comments>http://www.donevii.com/post/468.html#comments</comments>
		<pubDate>Tue, 02 Sep 2008 13:59:00 +0000</pubDate>
		<dc:creator>gavinkwoe</dc:creator>
				<category><![CDATA[protocol]]></category>
		<category><![CDATA[chunked]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[协议]]></category>
		<category><![CDATA[编码]]></category>
		<category><![CDATA[网络]]></category>

		<guid isPermaLink="false">http://www.donevii.com/?p=468</guid>
		<description><![CDATA[转至: http://hi.baidu.com/zkheartboy/blog/item/9216a0fd05591e1508244d74.html 在网上找了好一会，始终没发现有解析Chunked编码的文章，那就自己写一个吧，呵呵。 网上使用Chunked编码的网站似乎并不是很多，除... ]]></description>
			<content:encoded><![CDATA[<p>转至: <a href="http://hi.baidu.com/zkheartboy/blog/item/9216a0fd05591e1508244d74.html">http://hi.baidu.com/zkheartboy/blog/item/9216a0fd05591e1508244d74.html</a></p>
<p>在网上找了好一会，始终没发现有解析Chunked编码的文章，那就自己写一个吧，呵呵。<br />
网上使用Chunked编码的网站似乎并不是很多，除了那些使用GZip压缩的网站，例：google.com，还有就是大部分打开GZip压缩的PHP论坛。<br />
根据本人的理解，使用Chunked编码的主要好处就在于一些程序的运算出过程中，可以动态的输出内容。<br />
例如，要在后台处理一个小时的运算，但又不希望用户等一个小时才能看到结果。这时就可采用Chunked编码将内容分块输出，用户随时都可以接收到最新的处理结果。<br />
ASP关闭了缓存的输出模式，就是Chunked编码的。(Response.Buffer = false)<br />
而每一次的Response.Write，都是一个Chunked，所以不要使用的太频繁哦，否则Chunk数量太多，额外的数据太浪费空间了。<br />
若想了解Chunked的具体编码结构，用ASP关闭缓存调试蛮方便的。:)</p>
<p>我们先来看看RFC2616中对Chunked的定义：<br />
<a href="http://www.donevii.com/post/tag/chunked" class="st_tag internal_tag" rel="tag" title="Posts tagged with chunked">Chunked</a>-Body = *chunk<br />
last-chunk<br />
trailer<br />
CRLF</p>
<p>chunk = chunk-size [ chunk-extension ] CRLF<br />
chunk-data CRLF<br />
chunk-size = 1*HEX<br />
last-chunk = 1*(&#8220;0&#8243;) [ chunk-extension ] CRLF</p>
<p>chunk-extension= *( &#8220;;&#8221; chunk-ext-name [ "=" chunk-ext-val ] )<br />
chunk-ext-name = token<br />
chunk-ext-val = token | quoted-string<br />
chunk-data = chunk-size(OCTET)<br />
trailer = *(entity-<a href="http://www.donevii.com/post/tag/header" class="st_tag internal_tag" rel="tag" title="Posts tagged with header">header</a> CRLF)</p>
<p>我们来模拟一下数据结构：<br />
[Chunk大小][回车][Chunk数据体][回车][Chunk大小][回车][Chunk数据体][回车][0][回车]</p>
<p>注意chunk-size是以十六进制的ASCII码表示的，比如86AE（实际的十六进制应该是：38366165），计算成长度应该是：34478，表示从回车之后有连续的34478字节的数据。<br />
跟踪了www.yahoo.com的返回数据，发现在chunk-size中，还会多一些空格。可能是固定长度为7个字节，不满7个字节的，就以空格补足，空格的ASCII码是0&#215;20。</p>
<p>以下是解码过程的伪代码：<br />
length := 0//用来记录解码后的数据体长度<br />
read chunk-size, chunk-extension (if any) and CRLF//第一次读取块大小<br />
while (chunk-size &gt; 0) {//一直循环，直到读取的块大小为0<br />
read chunk-data and CRLF//读取块数据体，以回车结束<br />
append chunk-data to entity-body//添加块数据体到解码后实体数据<br />
length := length + chunk-size//更新解码后的实体长度<br />
read chunk-size and CRLF//读取新的块大小<br />
}<br />
read entity-header//以下代码读取全部的头标记<br />
while (entity-header not empty) {<br />
append entity-header to existing header fields<br />
read entity-header<br />
}<br />
Content-Length := length//头标记中添加内容长度<br />
Remove &#8220;chunked&#8221; from <a href="http://www.donevii.com/post/tag/transfer" class="st_tag internal_tag" rel="tag" title="Posts tagged with transfer">Transfer</a>-<a href="http://www.donevii.com/post/tag/encoding" class="st_tag internal_tag" rel="tag" title="Posts tagged with encoding">Encoding</a>//头标记中移除Transfer-<a href="http://www.donevii.com/post/tag/encoding" class="st_tag internal_tag" rel="tag" title="Posts tagged with encoding">Encoding</a></p>
<p>有空再研究一下GZip＋Chunked是如何编码的，估计是每个Chunk块进行一次GZip独立压缩。</p>
<p>使用了Chunked，自然会在性能上稍微打点折扣，因为比正常的数据体多出了一些额外的消耗。<br />
但是有一些情况下，必需要使用分块输出，这也是不得已而为之～^_^</p>
]]></content:encoded>
			<wfw:commentRss>http://www.donevii.com/post/468.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[转] Chunked编码</title>
		<link>http://www.donevii.com/post/466.html</link>
		<comments>http://www.donevii.com/post/466.html#comments</comments>
		<pubDate>Tue, 02 Sep 2008 13:57:02 +0000</pubDate>
		<dc:creator>gavinkwoe</dc:creator>
				<category><![CDATA[doc]]></category>
		<category><![CDATA[protocol]]></category>
		<category><![CDATA[chunked]]></category>
		<category><![CDATA[encoding]]></category>
		<category><![CDATA[header]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[transfer]]></category>
		<category><![CDATA[编码]]></category>
		<category><![CDATA[网络]]></category>

		<guid isPermaLink="false">http://www.donevii.com/?p=466</guid>
		<description><![CDATA[转至: http://www.21andy.com/blog/20071109/660.html 有时候，Web服务器生成HTTP Response是无法在Header就确定消息大小的，这时一般来说服务器将不会提供Content-Length的头信息，而采用Chunked编码动态的提供body... ]]></description>
			<content:encoded><![CDATA[<p>转至: <a title="Chunked编码" href="http://www.21andy.com/blog/20071109/660.html">http://www.21andy.com/blog/20071109/660.html</a></p>
<p>有时候，Web服务器生成HTTP Response是无法在Header就确定消息大小的，这时一般来说服务器将不会提供Content-Length的头信息，而采用Chunked编码动态的提供body内容的长度。</p>
<p>进行Chunked编码传输的HTTP Response会在消息头部设置：</p>
<div class="hl-surround">
<div class="hl-main"><a href="http://www.donevii.com/post/tag/transfer" class="st_tag internal_tag" rel="tag" title="Posts tagged with transfer">Transfer</a>-<a href="http://www.donevii.com/post/tag/encoding" class="st_tag internal_tag" rel="tag" title="Posts tagged with encoding">Encoding</a>: <a href="http://www.donevii.com/post/tag/chunked" class="st_tag internal_tag" rel="tag" title="Posts tagged with chunked">chunked</a></div>
</div>
<p>表示Content Body将用Chunked编码传输内容。</p>
<p>Chunked编码使用若干个Chunk串连而成，由一个标明长度为0的chunk标示结束。每个Chunk分为头部和正文两部分，头部内容指定下一段正文的字符总数（十六进制的数字）和数量单位（一般不写），正文部分就是指定长度的实际内容，两部分之间用回车换行(CRLF)隔开。在最后一个长度为0的Chunk中的内容是称为footer的内容，是一些附加的Header信息（通常可以直接忽略）。具体的Chunk编码格式如下：</p>
<div class="hl-surround">
<div class="hl-main">　　Chunked-Body = *chunk<br />
　　　　　　　　　&#8221;0&#8243; CRLF<br />
　　　　　　　　　footer<br />
　　　　　　　　　CRLF<br />
　　chunk = chunk-size [ chunk-ext ] CRLF<br />
　　　　　　chunk-data CRLF</p>
<p>　　hex-no-zero = &lt;HEX excluding &#8220;0&#8243;&gt;</p>
<p>　　chunk-size = hex-no-zero *HEX<br />
　　chunk-ext = *( &#8220;;&#8221; chunk-ext-name [ "=" chunk-ext-value ] )<br />
　　chunk-ext-name = token<br />
　　chunk-ext-val = token | quoted-string<br />
　　chunk-data = chunk-size(OCTET)</p>
<p>　　footer = *entity-<a href="http://www.donevii.com/post/tag/header" class="st_tag internal_tag" rel="tag" title="Posts tagged with header">header</a></p></div>
</div>
<p>RFC文档中的Chunked解码过程如下：</p>
<div class="hl-surround">
<div class="hl-main">　　length := 0<br />
　　read chunk-size, chunk-ext (if any) and CRLF<br />
　　while (chunk-size &gt; 0) {<br />
　　read chunk-data and CRLF<br />
　　append chunk-data to entity-body<br />
　　length := length + chunk-size<br />
　　read chunk-size and CRLF<br />
　　}<br />
　　read entity-header<br />
　　while (entity-header not empty) {<br />
　　append entity-header to existing header fields<br />
　　read entity-header<br />
　　}<br />
　　Content-Length := length<br />
　　Remove &#8220;chunked&#8221; from Transfer-Encoding</div>
</div>
<p>最后提供一段PHP版本的chunked解码代码：</p>
<div class="hl-surround">
<div class="hl-main"><span style="color: #00008b;">$chunk_size</span><span style="color: gray;"> = </span><span style="color: olive;">(</span><span style="color: blue;">integer</span><span style="color: olive;">)</span><span style="color: blue;">hexdec</span><span style="color: olive;">(</span><span style="color: blue;">fgets</span><span style="color: olive;">(</span><span style="color: gray;"> </span><span style="color: #00008b;">$socket_fd</span><span style="color: gray;">, </span><span style="color: maroon;">4096</span><span style="color: gray;"> </span><span style="color: olive;">)</span><span style="color: gray;"> </span><span style="color: olive;">)</span><span style="color: gray;">;<br />
</span><span style="color: green;">while</span><span style="color: olive;">(</span><span style="color: gray;">!</span><span style="color: blue;">feof</span><span style="color: olive;">(</span><span style="color: #00008b;">$socket_fd</span><span style="color: olive;">)</span><span style="color: gray;"> &amp;&amp; </span><span style="color: #00008b;">$chunk_size</span><span style="color: gray;"> &gt; </span><span style="color: maroon;">0</span><span style="color: olive;">)</span><span style="color: gray;"> </span><span style="color: olive;">{</span><span style="color: gray;"><br />
    </span><span style="color: #00008b;">$bodyContent</span><span style="color: gray;"> .= </span><span style="color: blue;">fread</span><span style="color: olive;">(</span><span style="color: gray;"> </span><span style="color: #00008b;">$socket_fd</span><span style="color: gray;">, </span><span style="color: #00008b;">$chunk_size</span><span style="color: gray;"> </span><span style="color: olive;">)</span><span style="color: gray;">;<br />
    </span><span style="color: blue;">fread</span><span style="color: olive;">(</span><span style="color: gray;"> </span><span style="color: #00008b;">$socket_fd</span><span style="color: gray;">, </span><span style="color: maroon;">2</span><span style="color: gray;"> </span><span style="color: olive;">)</span><span style="color: gray;">; </span><span style="color: #ffa500;">// skip \r\n</span><span style="color: gray;"><br />
    </span><span style="color: #00008b;">$chunk_size</span><span style="color: gray;"> = </span><span style="color: olive;">(</span><span style="color: blue;">integer</span><span style="color: olive;">)</span><span style="color: blue;">hexdec</span><span style="color: olive;">(</span><span style="color: blue;">fgets</span><span style="color: olive;">(</span><span style="color: gray;"> </span><span style="color: #00008b;">$socket_fd</span><span style="color: gray;">, </span><span style="color: maroon;">4096</span><span style="color: gray;"> </span><span style="color: olive;">)</span><span style="color: gray;"> </span><span style="color: olive;">)</span><span style="color: gray;">;<br />
</span><span style="color: olive;">}</span></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.donevii.com/post/466.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

