code小生,一个专注 Android 领域的技术平台 公众号回复 Android 加入我的安卓技术群
该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列。该系列引用了《Android开发艺术探索》以及《深入理解Android 卷Ⅰ,Ⅱ,Ⅲ》中的相关知识,另外也借鉴了其他的优质博客,在此向各位大神表示感谢,膜拜!!! 前言本篇文章是来说说HTTP那些事。 HTTP简介Web 使用一种名为 HTTP ( HyperText Transfer Protocol ,超文本传输协议的协议作为规范,完成从客户端到服务器端等一系列运作流程。本文探讨的是HTTP/1.1版本。这仍然是大多数网站采用的HTTP协议 我们先看一下下面这张广为流传的图。 网路传输的4层结构 那些与HTTP协议密切相关的协议IPIP 协议的作用是把各种数据包传送给对方。而要保证确实传送到对方那里,则需要满足各类条件。其中两个重要的条件是 IP 地址和 MAC地址( Media Access Control Address )。IP 地址指明了节点被分配到的地址, MAC 地址是指网卡所属的固定地址。 IP 地址可以和 MAC 地址进行配对。 IP 地址可变换,但 MAC地址基本上不会更改。IP使用 ARP 协议凭借 MAC 地址进行通信 TCP(确保可靠性的协议)按层次分, TCP 位于传输层,提供可靠的字节流服务。所谓的字节流服务( Byte Stream Service )是指,为了方便传输,将大块数据分割成以报文段( segment )为单位的数据包进行管理。而可靠的传输服务是指,能够把数据准确可靠地传给对方。 TCP连接的3次握手为了准确无误地将数据送达目标处, TCP 协议采用了三次握手( three-way handshaking )策略。 整个过程如下图所示 3次握手 为什么需要3次握手为什么需要3次握手,如果面试中问到了TCP相关知识,那么这个问题也几乎是必问的,为什么是3次,而不是1次,2次或者4次,5次?? 首先我们知道不管是客户端或者服务端发送数据都会消耗网络流量,还会造成许多不必要的通信开销,浪费资源,所以我们在保证TCP可靠性的前提下所经历的通信次数自然越少越好。 TCP的可靠性含义我们上面已经说了,那我们就从3次握手分析,如果只有1次握手,客户端只向服务端发送数据,那么就谈不上可靠性了,因为服务端都没有回复,那么我们来看只有2次握手行不行,如果只有2次握手,客户端只向服务端发送数据,服务器也向客户端回复我收到数据了,但是考虑此时如果发送数据的过程中数据丢失了,服务端认为连接建立了(数据我已经发出去了),可是客户端没有收到数据,客户端认为连接没有建立,就会重复请求,而这对与服务端来说就又是一个全新的连接。一言以蔽之:第三次握手是为了防止:如果客户端迟迟没有收到服务器返回确认报文,这时会放弃连接,重新启动一条连接请求,但问题是:服务器不知道客户端没有收到,所以他会收到两个连接,浪费连接开销。如果每次都是这样,就会浪费多个连接开销。 HTTP详解HTTP的报文结构用于 HTTP 协议交互的信息被称为 HTTP 报文。请求端(客户端)的HTTP 报文叫做请求报文,响应端(服务器端)的叫做响应报文。HTTP 报文本身是由多行(用 CR+LF 作换行符)数据构成的字符串文本。HTTP 报文大致可分为报文首部和报文主体两块。两者由最初出现的空行( CR+LF )来划分。通常,并不一定要有报文主体。 HTTP的报文结构 HTTP的请求以及响应报文结构HTTP的报文头部下面的是请求某网站时,请求报文以及响应报文的首部信息。 请求报文首部 Host: hackr.jp 响应报文首部 HTTP/1.1 200 OK 由上可知HTTP 首部字段是由首部字段名和字段值构成的,中间用冒号 “:” 分隔。 HTTP的报文头部类型HTTP 首部字段根据实际用途被分为以下 4 种类型。通用首部字段( General Header Fields )请求报文和响应报文两方都会使用的首部。
请求首部字段( Request Header Fields )从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、响应内容相关优先级等信息。
响应首部字段( Response Header Fields )从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。
实体首部字段( Entity Header Fields )针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。
HTTP 首部字段将定义成缓存代理和非缓存代理的行为,分成 2 种类型
下面列举了 HTTP/1.1 中的逐跳首部字段。除这 8 个首部字段之外,其他所有字段都属于端到端首部
关于各个首部命令的详细参数可参见[HTTP Headers] HTTP进阶如果这篇文章到上面为止,那跟手册貌似没有什么区别,之前听到过一位大神说的话,掌握一门技术,不仅需要知道这门技术能做到什么,也要知道它不能做到什么,在掌握一门技术的边界之后,便对一门技术游刃有余了,毕竟技术那么多,推陈换代那么快,对于大多数人来说没有精力貌似也不是十分必要去记忆技术的每一个细节(即使记忆了,有许多细节是我们平常用不到的,也就渐渐遗忘了)。在我们掌握边界以后,遇到问题时,我们知道这个问题能依靠该项技术解决,至于怎么解决,那时我们在去查相应手册即可。 那对于本篇的HTTP来说,我们就从以下两方面进行分析 HTTP能做到什么我们下面结合实际工作中的所遇到的HTTP的应用场景分为两大方面 访问大数据(图片,视频,大文件)时在访问这些大数据时,我们往往会遇到以下问题 我们通常在做下载功能的时候往往需要断点续传甚至多线程断点续传,那么上面的问题就肯定会遇到。下面我们一一解答 1.使用Range来请求某个资源的部分数据 Range: bytes=bytes=200-1000, 2000-6576, 19000- 2.ETag以及If-Match If-None-Match If-Range 响应首部字段ETag 能告知客户端实体标识。它是一种可将资源以字符串形式做唯一性标识的方式。服务器会为每份资源分配对应的 ETag值。另外,当资源更新时, ETag 值也需要更新。生成 ETag 值时,并没有统一的算法规则,而仅仅是由服务器来分配。
请求首部字段If-Match If-None-Match If-Range If-Match ,它会告知服务器匹配资源所用的实体标记( ETag )值。这时的服务器无法使用弱 ETag 值。服务器会比对 比If-Match 的字段值和资源的 ETag 值,仅当两者一致时,才会执行请求。反之,则返回状态码 412 Precondition Failed 的响应。还可以使用星号( * )指定 If-Match 的字段值。针对这种情况,服务器将会忽略 ETag 的值,只要资源存在就处理请求。 If-None-Match 只有在 If-None-Match 的字段值与 ETag 值不一致时,可处理该请求。与 If-Match 首部字段的作用相反 If-Range 浏览器告诉 WEB 服务器,如果我请求的对象没有改变,就把我缺少的部分给我,如果对象改变了,就把整个对象给我。浏览器通过发送请求对象的ETag 或者自己所知道的最后修改时间给 WEB 服务器,让其判断对象是否改变了。总是跟 Range 头部一起使用。 If-Range: Wed, 21 Oct 2015 07:28:00 GMT If-Range: "1234" If-Range 头字段通常用于断点续传的下载过程中,用来自从上次中断后,确保下载的资源没有发生改变。 通常情况下的 HTTP请求与响应我们现在的服务器大多是符合RESTFUL规范的,作为客户端(网页、Android、IOS)来说,我们与服务器的通常交互是数据量比较小的操作,增删改查,传递以及解析显示JSON数据。这是我们通常使用HTTP的场景。这种场景下所常用的HTTP头部字段是包含上述访问大数据(图片,视频,大文件)时的请求字段的,这些首部字段各有含义,见 HTTP不能做到什么(缺陷)
备注:由于上述 HTTP/1.1协议的缺陷,SPDY 和 WebSocket 等协议纷纷出现,还有HTTP/2.0版本,这些协议的出现在一定程度上弥补了HTTP/1.1协议的缺陷。感兴趣的同学可以深入了解。 本篇总结本篇文章介绍了HTTP协议。从TCP/IP到HTTP以及HTTP进阶,层层递进,希望读者有些许收货。 此致,敬礼 分享技术我是认真的 |
|
来自: codingSmart > 《待分类》