java http data chunk_Http chunked协议
HTTP协议中的TRANFER-ENCODING:CHUNKED编码解析
通常情况下,Transfer-Encoding域的值应当为chunked,表明采用chunked编码方式来进行报文体的传输。chunked编码是HTTP/1.1 RFC里定义的一种编码方式,因此所有的HTTP/1.1应用都应当支持此方式。
chunked编码的基本方法是将大块数据分解成多块小数据,每块都可以自指定长度,其具体格式如下(BNF文法):
Chunked-Body = *chunk //0至多个chunk
last-chunk //最后一个chunk
trailer //尾部
CRLF //结束标记符
chunk = chunk-size [ chunk-extension ] CRLF
chunk-data CRLF
chunk-size = 1*HEX
last-chunk = 1*("0") [ chunk-extension ] CRLF
chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
chunk-ext-name = token
chunk-ext-val = token | quoted-string
chunk-data = chunk-size(OCTET)
trailer = *(entity-header CRLF)
解释:
Chunked-Body表示经过chunked编码后的报文体。报文体可以分为chunk, last-chunk,trailer和结束符四部分。chunk的数量在报文体中最少可以为0,无上限;每个chunk的长度是自指定的,即,起始的数据必然是16进制数字的字符串,代表后面chunk-data的长度(字节数)。这个16进制的字符串第一个字符如果是“0”,则表示chunk-size为0,该chunk为last-chunk,无chunk-data部分。可选的chunk-extension由通信双方自行确定,如果接收者不理解它的意义,可以忽略。
trailer是附加的在尾部的额外头域,通常包含一些元数据(metadata, meta means "about information"),这些头域可以在解码后附加在现有头域之后。
实例分析:
下面分析用ethereal抓包使用Firefox与某网站通信的结果(从头域结束符后开始):
Address 0.......................... f
000c0 31
000d0 66 66 63 0d 0a ............... // ASCII码:1ffc\r\n, chunk-data数据起始地址为000d5
很明显,“1ffc”为第一个chunk的chunk-size,转换为int为8188.由于1ffc后马上就是
CRLF,因此没有chunk-extension.chunk-data的起始地址为000d5, 计算可知下一块chunk的起始
地址为000d5+1ffc + 2=020d3,如下:
020d0 .. 0d 0a 31 66 66 63 0d 0a .... // ASCII码:\r\n1ffc\r\n
前一个0d0a是上一个chunk的结束标记符,后一个0d0a则是chunk-size和chunk-data的分隔符。
此块chunk的长度同样为8188, 依次类推,直到最后一块
100e0 0d 0a 31
100f0 65 61 39 0d 0a...... //ASII码:\r\n\1ea9\r\n
此块长度为0x1ea9 = 7849, 下一块起始为100f5 + 1ea9 + 2 = 11fa0,如下:
100a0 30 0d 0a 0d 0a //ASCII码:0\r\n\r\n
“0”说明当前chunk为last-chunk, 第一个0d 0a为chunk结束符。第二个0d0a说明没有trailer部分,整个Chunk-body结束。
解码流程:
对chunked编码进行解码的目的是将分块的chunk-data整合恢复成一块作为报文体,同时记录此块体的长度。
RFC2616中附带的解码流程如下:(伪代码)
length := 0 //长度计数器置0
read chunk-size, chunk-extension (if any) and CRLF //读取chunk-size, chunk-extension
//和CRLF
while(chunk-size > 0 ) { //表明不是last-chunk
read chunk-data and CRLF //读chunk-size大小的chunk-data,skip CRLF
append chunk-data to entity-body //将此块chunk-data追加到entity-body后
read chunk-size and CRLF //读取新chunk的chunk-size 和 CRLF
}
read entity-header //entity-header的格式为name:valueCRLF,如果为空即只有CRLF
while (entity-header not empty) //即,不是只有CRLF的空行
{
append entity-header to existing header fields
read entity-header
}
Content-Length:=length //将整个解码流程结束后计算得到的新报文体length
//作为Content-Length域的值写入报文中
Remove "chunked" from Transfer-Encoding //同时从Transfer-Encoding中域值去除chunked这个标记
length最后的值实际为所有chunk的chunk-size之和,在上面的抓包实例中,一共有八块chunk-size为0x1ffc(8188)的chunk,剩下一块为0x1ea9(7849),加起来一共73353字节。
注:对于上面例子中前几个chunk的大小都是8188,可能是因为:"1ffc" 4字节,"\r\n"2字节,加上块尾一个"\r\n"2字节一共8字节,因此一个chunk整体为8196,正好可能是发送端一次TCP发送的缓存大小。
java http data chunk_Http chunked协议相关推荐
- java http data chunk_HTTP协议之Chunked解析
在网上找了好一会,始终没发现有解析Chunked编码的文章,那就自己写一个吧,呵呵.网上使用ChuPHP 在网上找了好一会,始终没发现有解析Chunked编码的文章,那就自己写一个吧,呵呵. 网上使用 ...
- 缓冲区溢出_在Java中使用Google的协议缓冲区
缓冲区溢出 最近发布了有效的Java第三版,我一直对确定此类Java开发书籍的更新感兴趣,该书籍的最新版本仅通过Java 6进行了介绍. 在此版本中,显然存在与Java 7 , Java 8和Java ...
- java使用缓冲区读取文件_在Java中使用Google的协议缓冲区
java使用缓冲区读取文件 最近发布了 有效的Java第三版 ,我一直对确定此类Java开发书籍的更新感兴趣,该书籍的最新版本仅通过Java 6进行了介绍 . 在此版本中,显然存在与Java 7 , ...
- 在Java中使用Google的协议缓冲区
最近发布了 有效的Java第三版 ,我一直对确定此类Java开发书籍的更新感兴趣,该书籍的最新版本仅通过Java 6进行了介绍 . 在此版本中,显然有与Java 7 , Java 8和Java 9密切 ...
- Java实例练习——基于UDP协议的多客户端通信
昨天学习了UDP协议通信,然后就想着做一个基于UDP的多客户端通信(一对多),但是半天没做出来,今天早上在参考了很多代码以后,修改了自己的代码,然后运行成功,在这里分享以下代码,也说一下自己的认识误区 ...
- c客户端http post chunked协议上传到服务器demo源码
下面例子中 :c 客户端采用 chunked协议上传到服务器,java 服务器返回的不是chunked 协议 chunked 编码协议格式参考 https://blog.csdn.net/wy5761 ...
- Java 面试知识点解析——网络协议篇
Java 面试知识点解析--网络协议篇 前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 ...
- java basic data type,java基本数据类型--Basic Datatypes
Variables are nothing but reserved memory locations to store values. This means that when you create ...
- Java学习系列(十八)Java面向对象之基于UDP协议的网络通信
UDP协议:无需建立虚拟链路,协议是不可靠的. A节点以DatagramSocket发送数据包,数据报携带数据,数据报上还有目的目地地址,大部分情况下,数据报可以抵达:但有些情况下,数据报可能会丢失 ...
最新文章
- 创建用于存放备份还原文件的网络文件夹(DPM配置管理系列七)
- EL与OGNL以及值栈的理解
- mysql多大_洞悉MySQL底层架构:游走在缓冲与磁盘之间
- php连接mysql原生_php链接mysql原生写法
- Flash/Flex学习笔记(34):AS3中的自定义事件
- html页面画一个矩形,使用HTML5 canvas绘制一个矩形的方法
- GNU make manual 翻译( 一百八十七)
- PMP培训班内部资料,免费分享
- RDP Wrapper
- 如何从道客巴巴上下载收费文档之我见
- cuda历史版本下载
- 家里的无线网最近总是网速不稳定,一阵一阵的卡,是怎么回事?
- 智能电视机顶盒开发记录
- UVA12307 Smallest Enclosing Rectangle 题解
- node.js版本不同,跑不起项目(个人笔记)
- 计算机网络管理工作记录,网络管理如何查看电脑开机、关机记录
- 阿里云 远程mysql_阿里云远程mysql
- 开关调色新世界BP2888电源解决方案
- 老罗的Android系统分析(三横三纵)
- 学编程的人那么多,到底编程的出路在哪?