HTTP传输二进制初探
【转】HTTP传输二进制初探
http://www.51testing.com/?uid-390472-action-viewspace-itemid-233993
【转】HTTP传输二进制初探
上一篇 / 下一篇 2011-04-11 04:34:49 / 个人分类:知识
关于HTTP传输ASCII文本内容的过程相信大家都应该容易理解,因为HTTP请求头和响应头都是以ASCII文本方式传输的。而对于HTTP传输二进制流的相关细节,其实没有我想象中的那么复杂,以前学习POP3和SMTP(这两个都是邮件传输协议)的时候,知道他们都只能传输ASCII文本,如果要在邮件中加入附件,如一张图片(图片文件就是二进制文件)那就得先对图片文件转码,即将邮件协议不能传输的二进制数据流转换成可被邮件协议传输的ASCII数据流,其中用的最多的转换就是BASE64编码转换。其实BASE64编码转换也同样适合于HTTP协议,只有你在转换后将HTTP响应头中的Transfer-Encoding设置为base64,当然如果客服端浏览器不支持base64编码那这种转换也是徒劳的,不过幸好现在几乎所有浏览器都支持BASE64(你能用浏览器查看邮件中的附件就是证据)。
不过话又回来,既然HTTP能够直接支持二进制的数据流传输,那我们又何必绕着弯子,走冤枉路呢?
如果你和一样,也对HTTP能直接传输二进制感到疑问,那么下面的内容会很对你胃口。
我们以一张图片的传输来说明这个问题:
http://gimg.baidu.com/img/gs.gif 这是百度主页上一张非常小的图片的链接地址 即右侧
图片
我们用到的工具有:
Firefox 浏览器
Firebug 一个非常不错的web调试器,Firefox插件
Ethereal 网络抓包工具
如果你对上面三个工具不是很了解,建议你先去google一下。然后再来阅读。
下面是我们在Firefox地址栏里面输入http://gimg.baidu.com/img/gs.gif 回车后,Firefox默默地为我们做的事情。关于HTTP通行的细节请参阅我以前的文章
http://blog.chinaunix.net/u3/104217/showart.php?id=2075210
http://p.99081.com/unix/http_protocol_summary.html
GET /gs.gif HTTP/1.1
Host: gimg.baidu.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
当Firefox发出该请求后,服务器接收并分析该请求,经分析后得出客服端浏览器请求的文件(或者说页面)为/img/gs.gif (第一个斜杆代表服务器根目录),于是服务器(百度的HTTP服务器为Apache)从服务器主机的硬盘(或者直接从内存的缓冲区)中读出该图片(注意哦,直接读二进制流),并将其拼接到HTTP响应头后,然后把这片数据(我指的是HTTP响应头加上图片的二进制数据)拷贝到TCP的发送缓冲区(也就是调用send函数)。
下面即位客服端收到的从服务器端发来的数据流:
我们还是先来分析一下响应头
HTTP/1.1 200 OK
Date: Tue, 27 Oct 2009 13:43:15 GMT
Server: Apache
Last-Modified: Fri, 11 Aug 2006 04:20:15 GMT
Accept-Ranges: bytes
Content-Length: 91
Cache-Control: max-age=315360000
Expires: Fri, 25 Oct 2019 13:43:15 GMT
Connection: close
Content-Type: image/gif
注意最后一个字段 Content-Type:image/gif 这说明传输的是一个image对象,该对象为gif格式。另外我们还有记下Content-length:91 这说明传输的数据(即gs.gif图片)的大小为91个字节,此外我们还发现响应头中并没有Transfer-Encoding这个字段,这说明传输的数据没有经过任何形式的编码转换,传输的就是源文件的内容。
请认真查看上图中蓝底部分,在蓝底的最后那一行,有两个连续的 0d 0a 0d 0a ,这说明HTTP响应头已经结束,接下来的内容为传输的文件。好啦,那接下来当然是要分析传输的文件到底是啥东西了。请看下图
图中蓝底的部分即为传输的数据流(即传输的文件),这些是什么东西,我也搞不懂,(估计只有搞图片压缩算法的人能够看得懂),不过没关系,我们可以先把图片保存在本地,然后用一个十六进制查看软件打开该图片,即可知道其中的奥秘。
下面是用UltraEdit打开该图片后的截图
请比较一下上面两张图片是不是有很多相同的地方呀,其实上面两张图中,第一张中的蓝底部分就是第二张中的数据。这下你应该明白了吧,其实HTTP传输的就是图片文件的二进制编码,Apache没有对二进制文件进行任何形式的编码转换。我们还可以计算一下这个图片的大小:16 * 5 + 11 = 91 (也就是 0x5a – 0x00 = 0x5a),正好和HTTP响应头中的Content-Length相等。
如果没有UltraEdit等十六进制编辑器,我写了个简单的程序以供查看,下面是源码:
check_hex.c
|
#define HEX_BUFFER 1024 int main(int argc, char *argv[]) |
HTTP传输二进制初探的更多相关文章
- Linux企业级项目实践之网络爬虫(16)——使用base64传输二进制数据
用http传输二进制的数据时,需要将二进制做一下转化,例如传输的int类型,将int类型之间转为char以后,丢失掉了长度的信息,如数字123456,本来只有4个字节,但是转化成文本的"12 ...
- atitit.无损传输二进制数据串传输网络
atitit.无损传输二进制数据串传输网络 1. gbk的网络传输问题,为什么gbk不能使用来传输二进制数据 1 2. base64 2 3. iso-8859-1 (推荐) 2 4. utf-8 ...
- 如何提升mysql replication的性能&多线程传输二进制日志
1,最好使用内网或者专线链路传输binlog数据 (千兆网卡.还不够的话,bounding 技术,扩展带宽) 在my.cnf中强制使用内网ip传输数据bind-address=ip2,将二进制保存在独 ...
- gSoap传输二进制数据
最近使用gSoap传输二进制数据,遇到问题.gSoap不能一次传输二进制数据.所以使用分包传送. struct xsd_DwgInfo { ];//分包大小 int m_nReadSize;// bo ...
- JavaScript读二进制文件并用ajax传输二进制流
综合网上多个教程,加上自己实践得出的方法,目前能够兼容谷歌.IE11.IE10. htmlbody里的内容,没什么特殊的. <div id="dConfirm"> &l ...
- C++和python使用struct传输二进制数据结构来实现
网络编程问题往往涉及二进制数据的传输.在C++经常使用的传输是文本字符串和分组结构. 假设该数据可以预先送入连续的内存区域,然后让send函数来获得的第一个地址,这一块连续的内存区就能完成传输数据.文 ...
- json传输二进制的方案【转】
本文转自:http://wiyi.org/binary-to-string.html json 是一种很简洁的协议,但可惜的是,它只能传递基本的数型(int,long,string等),但不能传递by ...
- http协议传输二进制数据以及对输入流(php://input)和http请求的理解
1.index.php <?php $data=file_get_contents('./a.jpg'); $opts = array('http' => array( 'method' ...
- atitit.二进制数据无损转字符串网络传输
atitit.二进制数据无损转字符串网络传输 1. gbk的网络传输问题,为什么gbk不能使用来传输二进制数据 1 2. base64 2 3. iso-8859-1 (推荐) 2 4. utf-8 ...
随机推荐
- laravel groupby分组问题。
laravel 5.7使用groupBy分组查询时会提示一个错误,但是sql可以执行. 因为:mysql从5.7以后,默认开启了严格模式. 解决方法:将/config/database.php 中:关 ...
- HUD-1559 最大子矩阵,dp模拟
最大子矩阵 ...
- HDU 3932 模拟退火
HDU3932 题目大意:给定一堆点,找到一个点的位置使这个点到所有点中的最大距离最小 简单的模拟退火即可 #include <iostream> #include <cstdio& ...
- 选课(codevs 1378)
题目描述 Description 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了N(N<300)门的选修课程,每个学生可选课程的数量M是给定的.学生选修 ...
- 转 蓝桥杯 历届试题 波动数列 [ dp ]
传送门 历届试题 波动数列 时间限制:1.0s 内存限制:256.0MB 锦囊1 锦囊2 锦囊3 问题描述 观察这个数列: 1 3 0 2 -1 1 -2 ... 这个 ...
- poj2553 有向图缩点,强连通分量。
//求这样的sink点:它能达到的点,那个点必能达到他,即(G)={v∈V|任意w∈V:(v→w)推出(w→v)} //我法:tarjan缩点后,遍历点,如果该点到达的点不在同一个强连通中,该点排除, ...
- Xcode warning: code will never be executed.
在xcode编译的时候,提示了code will never be executed这个警告.百度了一下,大体的意思是,该代码永远不会执行的意思. 比如: - (void)setMyStyle:(Ad ...
- hdu 4819 Mosaic
无论是线段树还是树状数组维护最大值最小值的时候一定要注意,如果有修改操作的话,这个最小值和最大值的更新一定不能由原来的和修改的值得到,一定要重新查询一次,否则可能出现当前最小值是原来的未修改值,但事实 ...
- 清北省选 DAY last 集锦
这是题目描述的链接: http://lifecraft-mc.com/wp-content/uploads/2018/03/problems1.pdf (虽然这次没去清北,但还是厚颜无耻的做了一下这套 ...
- Shiro经过Redis管理会话实现集群(转载)
原文:http://www.myexception.cn/software-architecture-design/1815507.html Shiro通过Redis管理会话实现集群 写在前面 1.在 ...