Android 网络编程(http协议)

简介

  • HTTP全称是Hyper Text Transfer Protocol,翻译过来叫超文本传输协议,看起来很高端的名字,实际上他就是字面意思,就比如你想知道“HTTP协议是什么”,服务器上呢有个超文本,就姑且当他是个记事本里面记录着“HTTP协议是什么”的答案,你想要,那么服务器就和你约定好了用“顺丰快递传”,所以这就是传输超文本的协议。
  • 它是一个属于应用层的协议,什么叫应用层,简单说就是和应用进程交互 的层,想想应用里面有什么好交互的,当然是数据了,也就是说这一层解决的是如何包装数据的,还是很像快递。

特点

  1. C/S模式,快递员服务于客户。
  2. 简单:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST,每种方法规定了客户与服务器联系的类型不同。就相当于告诉快递员你的地址(路径)和你要的运输的方式(请求方法),比如我家住安卓小区你给我空运过来。。。
  3. 快速:由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
  4. 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
  5. 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。但是这种方式在请求频繁的条件下,将会在建立和断开连接上花费大部分时间,所以在1.0、1.1持久连接变为了默认连接方式,有兴趣的可以自己查一下这个方式。
  6. 无状态:HTTP协议是无状态协议,简单说就是健忘、没脑子。打电话给常年在小区送快递的快递小哥:“哥,还送老地方”,小哥:“你谁呀不认识!”,挂了。。。所以无状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

URL 格式

http://host[":"port][abs_path]

如:http://blog.csdn.net:80/qijinglai
http表示要通过HTTP协议来定位网络资源;host表示合法的Internet主机域名或者IP地址;port指定一个端口号,为空则使用默认端口80;abs_path指定请求资源的URI(Web上任意的可用资源)。

Http报文

http报文可以分为请求报文和响应报文,格式大同小异。主要分为三个部分:

  1. 起始行
  2. 首部
  3. 主体

请求报文格式:

<method> <request-url> <version>
<headers>

<entity-body>

响应报文格式:

<version> <status> <reason-phrase>
<headers>

<entity-body>

从请求报文格式和响应报文格式可以看出,两者主要在起始行上有差异。这里稍微解释一下各个标签:

<method> 指请求方法,常用的主要是Get、 Post、Head 还有其他一些我们这里就不说了,有兴趣的可以自己查阅一下

<version> 指协议版本,现在通常都是Http/1.1了

<request-url> 请求地址

<status> 指响应状态码, 我们熟悉的200、404等等

<reason-phrase> 原因短语,200 OK 、404 Not Found 这种后面的描述就是原因短语,通常不必太关注。

method

HTTP请求方法有8种

  1. GET:请求获取Request-URI所标识的资源
  2. POST:在Request-URI所标识的资源后附加新的数据
  3. HEAD:请求获取由Request-URI所标识的资源的响应消息报头
  4. PUT: 请求服务器存储一个资源,并用Request-URI作为其标识
  5. DELETE :请求服务器删除Request-URI所标识的资源
  6. TRACE : 请求服务器回送收到的请求信息,主要用于测试或诊断
  7. CONNECT: HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
  8. OPTIONS :请求查询服务器的性能,或者查询与资源相关的选项和需求

GET和POST的区别

两个方法之间在传输形式上有一些区别,通过Get方法发起请求时,会将请求参数拼接在request-url尾部,格式是url?param1=xxx&param2=xxx&[…]。
我们需要知道,这样传输参数会使得参数都暴露在地址栏中。并且由于url是ASCII编码的,所以参数中如果有Unicode编码的字符,例如汉字,都会编码之后传输。另外值得注意的是,虽然http协议并没有对url长度做限制,但是一些浏览器和服务器可能会有限制,所以通过GET方法发起的请求参数不能够太长。而通过POST方法发起的请求是将参数放在请求体中的,所以不会有GET参数的这些问题。
另外一点差别就是方法本身的语义上的。GET方法通常是指从服务器获取某个URL资源,其行为可以看作是一个读操作,对同一个URL进行多次GET并不会对服务器产生什么影响。而POST方法通常是对某个URL进行添加、修改,例如一个表单提交,通常会往服务器插入一条记录。多次POST请求可能导致服务器的数据库中添加了多条记录。所以从语义上来讲,两者也是不能混为一谈的。

状态码

状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:

  • 100~199:指示信息,表示请求已接收,继续处理
  • 200~299:请求成功,表示请求已被成功接收、理解、接受
  • 300~399:重定向,要完成请求必须进行更进一步的操作
  • 400~499:客户端错误,请求有语法错误或请求无法实现
  • 500~599:服务器端错误,服务器未能实现合法的请求

常见的状态码如下:

  • 200 OK:客户端请求成功
  • 400 Bad Request:客户端请求有语法错误,不能被服务器所理解
  • 401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
  • 403 Forbidden:服务器收到请求,但是拒绝提供服务
  • 500 Internal Server Error:服务器发生不可预期的错误
  • 503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常

header

在请求报文和响应报文中都可以携带一些信息,通过与其他部分配合,能够实现各种强大的功能。这些信息位于起始行之下与请求实体之间,以键值对的形式,称之为首部。每条首部以回车换行符结尾,最后一个首部额外多一个换行,与实体分隔开。

  • 通用报头,既可以出现在请求报头,也可以出现在响应报头中
    Date:表示消息产生的日期和时间
    Connection:允许发送指定连接的选项,例如指定连接是连续的,或者指定“close”选项,通知服务器,在响应完成后,关闭连接
    Cache-Control:用于指定缓存指令,缓存指令是单向的(响应中出现的缓存指令在请求中未必会出现),且是独立的(一个消息的缓存指令不会影响另一个消息处理的缓存机制)

  • 请求报头,用于服务器传递自身信息的响应,常见的响应报头:
    Location:用于重定向接受者到一个新的位置,常用在更换域名的时候
    Server:包含可服务器用来处理请求的系统信息,与User-Agent请求报头是相对应的

  • 实体报头,实体报头用来定于被传送资源的信息,既可以用于请求也可用于响应。请求和响应消息都可以传送一个实体,常见的实体报头为:
    Content-Type:发送给接收者的实体正文的媒体类型
    Content-Lenght:实体正文的长度
    Content-Language:描述资源所用的自然语言,没有设置则该选项则认为实体内容将提供给所有的语言阅读
    Content-Encoding:实体报头被用作媒体类型的修饰符,它的值指示了已经被应用到实体正文的附加内容的编码,因而要获得Content-Type报头域中所引用的媒体类型,必须采用相应的解码机制。
    Last-Modified:实体报头用于指示资源的最后修改日期和时间
    Expires:实体报头给出响应过期的日期和时间

实体

请求发送的资源,或是响应返回的资源。

Http缓存

当我们发起一个http请求后,服务器返回所请求的资源,这时我们可以将该资源的副本存储在本地,这样当再次对该url资源发起请求时,我们能快速的从本地存储设备中获取到该url资源,这就是所谓的缓存。缓存既可以节约不必要的网络带宽,又能迅速对http请求做出响应。

先摆出几个概念:
新鲜度检测
再验证
再验证命中

我们知道,有些url所对应的资源并不是一成不变的,服务器中该url的资源可能在一定时间之后会被修改。这时本地缓存中的资源将与服务器一侧的资源有差异。

既然在一定时间之后可能资源会改变,那么在某个时间之前我们可以认为这个资源没有改变,从而放心大胆的使用缓存资源,当请求时间超过来该时间,我们认为这个缓存资源可能不再与服务器端一致了。所以当我们发起一个请求时,我们需要先对缓存的资源进行判断,看看究竟我们是否可以直接使用该缓存资源,这个就叫做新鲜度检测。即每个资源就像一个食品一样,拥有一个过期时间,我们吃之前需要先看看有没有过期。

如果发现该缓存资源已经超过了一定的时间,我们再次发起请求时不会直接将缓存资源返回,而是先去服务器查看该资源是否已经改变,这个就叫做再验证。如果服务器发现对应的url资源并没有发生变化,则会返回304 Not Modified,并且不再返回对应的实体。这称之为再验证命中。相反如果再验证未命中,则返回200 OK,并将改变后的url资源返回,此时缓存可以更新以待之后请求。

我们看看具体的实现方式:

新鲜度检测
我们需要通过检测资源是否超过一定的时间,来判断缓存资源是否新鲜可用。那么这个一定的时间怎么决定呢?其实是由服务器通过在响应报文中增加Cache-Control:max-age,或是Expire这两个首部来实现的。值得注意的是Cache-Control是http1.1的协议规范,通常是接相对的时间,即多少秒以后,需要结合last-modified这个首部计算出绝对时间。而Expire是http1.0的规范,后面接一个绝对时间。
再验证
如果通过新鲜度检测发现需要请求服务器进行再验证,那么我们至少需要告诉服务器,我们已经缓存了一个什么样的资源了,然后服务器来判断这个缓存资源到底是不是与当前的资源一致。逻辑是这样没错。那怎么告诉服务器我当前已经有一个备用的缓存资源了呢?我们可以采用一种称之为条件请求的方式实现再验证。
Http定义了5个首部用于条件请求:
If-Modified-Since
If-None-Match
If-Unmodified-Since
If-Range
If-Match

If-Modified-Since 可以结合Last-Modified这个服务器返回的响应首部使用,当我们发起条件请求时,将Last-Modified首部的值作为If-Modified-Since首部的值传递到服务器,意思是查询服务器的资源自从我们上一次缓存之后是否有修改。

If-None-Match 需要结合另一个Etag的服务器返回的响应首部使用。Etag首部实际上可以认为是服务器对文档资源定义的一个版本号。有时候一个文档被修改了,可能所做的修改极为微小,并不需要所有的缓存都重新下载数据。或者说某一个文档的修改周期极为频繁,以至于以秒为时间粒度的判断已经无法满足需求。这个时候可能就需要Etag这个首部来表明这个文档的版号了。发起条件请求时可将缓存时保存下来的Etag的值作为If-None-Match首部的值发送至服务器,如果服务器的资源的Etag与当前条件请求的Etag一致,表明这次再验证命中。

OAuth

OAuth是一个用于授权第三方获取相应资源的协议。与以往的授权方式不同的是,OAuth的授权能避免用户暴露自己的用户密码给第三方,从而更加的安全。OAuth协议通过设置一个授权层,以区分用户和第三方应用。用户本身可以通过用户密码登陆服务提供商,获取到账户所有的资源。而第三方应用只能通过向用户请求授权,获取到一个Access Token,用以登陆授权层,从而在指定时间内获取到用户授权访问的部分资源。

OAuth定义的几个角色:

Role Description
Resource Owner 可以授权访问某些受保护资源的实体,通常就是指用户
Client 可以通过用户的授权访问受保护资源的应用,也就是第三方应用
Authorization server 在认证用户之后给第三方下发Access Token的服务器
Resource Server 拥有受保护资源的服务器,可以通过Access Token响应资源请求
 +--------+                               +---------------+
 |        |--(A)- Authorization Request ->|   Resource    |
 |        |                               |     Owner     |
 |        |<-(B)-- Authorization Grant ---|               |
 |        |                               +---------------+
 |        |
 |        |                               +---------------+
 |        |--(C)-- Authorization Grant -->| Authorization |
 | Client |                               |     Server    |
 |        |<-(D)----- Access Token -------|               |
 |        |                               +---------------+
 |        |
 |        |                               +---------------+
 |        |--(E)----- Access Token ------>|    Resource   |
 |        |                               |     Server    |
 |        |<-(F)--- Protected Resource ---|               |
 +--------+                               +---------------+

从上图可以看出,一个OAuth授权的流程主要可以分为6步:

  1. 客户端向用户申请授权。
  2. 用户同意授权。
  3. 客户端通过获取的授权,向认证服务器申请Access Token。
  4. 认证服务器通过授权认证后,下发Access Token。
  5. 客户端通过获取的到Access Token向资源服务器发起请求。
    6.资源服务器核对Access Token后下发请求资源。

Https

简单的说 Http + 加密 + 认证 + 完整性保护 = Https

传统的Http协议是一种应用层的传输协议,Http直接与TCP协议通信。其本身存在一些缺点:

  1. Http协议使用明文传输,容易遭到窃听。
  2. Http对于通信双方都没有进行身份验证,通信的双方无法确认对方是否是伪装的客户端或者服务端。
  3. Http对于传输内容的完整性没有确认的办法,往往容易在传输过程中被劫持篡改。

因此,在一些需要保证安全性的场景下,比如涉及到银行账户的请求时,Http无法抵御这些攻击。
Https则可以通过增加的SSL\TLS,支持对于通信内容的加密,以及对通信双方的身份进行验证。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容

  • 作者:涤生_Woo链接:https://www.jianshu.com/p/6e9e4156ece3 本篇文章篇幅...
    Fi的学习笔记阅读 1,698评论 0 4
  • 本文是《图解HTTP》读书笔记的第二篇,主要包括此书的第六章内容,因为第六章的内容较多,而且比较重要,所以单独写为...
    lijiankun24阅读 1,357评论 0 6
  • HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从服务器传输...
    blossomjae阅读 786评论 0 1
  • 路过早点摊 她正擦着嘴站起来 一个扶着电摩的男人看着她说 在这里吃饭的都是懒婆娘 我不由暗自一笑 她却喜滋滋地坐上...
    我是张望好时光阅读 147评论 2 3
  • 没人是真的在乎你,都是在他们需要你的时候才会记起你,想起还有一个不会拒绝的人陪他们聊天,好悲哀吧,明明都知道自己...
    乔灲妹阅读 292评论 0 0