Android开发之网络

Http

Http报文

http报文分为请求报文和响应报文,格式大同小异。主要分为三部分:起始行,首部和主体。
请求报文格式:

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

响应报文格式:

<version><status><version-phrase>
<headers>
<entity-body>

从上可以看出请求报文和响应报文的差异主要在于起始行,下面是各个标签的解释:

<method> 指请求方法,常用的有get和post
<version> 指协议版本,现在通常都是http/1.1
<request-url> 请求地址
<status> 请求响应状态码,如200,404等
<reason-phrase> 原因短句,如200 OK、404 NOT FOUND等
method

我们常用的请求方法有get与post两种,它们之间有什么异同呢?

  • 通过get方法发起请求时,请求参数会拼接在request-url尾部,传输参数会暴露在地址栏中,且url是ASCII编码,所以参数中如果有Unicode编码的字符将会被编码传输。另外,虽然http协议没有对url长度做限制,但是部分浏览器和服务器可能会限制url的长度。而post方法将参数放置在请求体中,所以不会有get请求所述的这些问题。
  • get请求通常是从服务器获取资源,多次访问不会对服务器数据产生影响,而post请求通常是对服务器中的数据进行添加、修改、删除等操作。
  • get请求产生一个TCP数据包,而post请求产生两个TCP数据包。
状态码

常见的状态码有:
200 OK 请求成功,实体包含请求的资源
301 Moved Permanent 请求的URL被移除了,通常会在Location首部中包含新的URL用于重定向
304 Not Modify 条件请求进行再验证,资源未改变
404 Not Found 资源不存在
206 Partial Content 成功执行一个部分请求,断点续传时会涉及到

header

在请求报文和响应报文中都可以携带一些信息,信息位于起始行之下与实体之间,以键值对的形式,称之为首部。下列是与缓存相关的header:

header含义
Date响应头信息,表示当前服务器的日期
Cache-Control响应头信息,控制缓存失效时间
Last-Modify响应头信息,表示资源最近一次的修改时间
ETag响应头信息,用于校验客户端缓存
Expires响应头信息,控制缓存失效时间,与Cache-Control同时出现时按Cache-Control计算
if-Modified-Since请求头信息,将上次请求的Last-Modify日期信息为值进行条件请求,查询服务器资源自上次缓存后是否有修改
if-None-Match请求头信息,将上次请求的ETag信息作为值进行条件请求,用于校验缓存是否过期
if-Unmodified-Since请求头信息,使请求成为条件请求,当指定资源在指定时间之后没有修改过,服务器才返回请求资源
if-Range请求头信息,范围请求条件,如条件满足,该范围请求将被发出,并且服务器返回206
if-Match请求头信息,将上次请求的ETag信息带上发送请求,用于缓存控制
实体

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

Http缓存

当我们发起一个http请求后,服务器返回请求资源,此时我们可以将资源存储在本地,当再次对该url发起请求时,我们能快速的从本地存储中获取到该url资源,这就是所谓的缓存。缓存既可以节约不必要的网络宽带,又可以迅速对http请求做出响应。但是,有些url资源并不是一成不变的,服务器中的url资源可能在一定的时间之后被修改了,这时本地缓存的资源与服务器端的资源就会出现差异。

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

如果发现缓存资源超时了,我们再次发起请求时不会直接将缓存资源返回,而是去服务器查看该资源是否改变,这个就叫做再验证。如果服务器发现对应的url资源未改变,则会返回304 Not Modified,并且不再返回对应的实体,这称之为再验证命中。相反,如果验证未命中,则返回200 OK,并将对应的url资源返回,此时可用新资源替换缓存资源。

具体实现:

1.新鲜度检测
服务器通过在响应报文中增加Cache-Control:max-age或Expires这两个header决定资源缓存可用时间。需注意的是Cache-Control是http1.1的规范,通常是相对时间,需要结合last-modified计算出绝对时间。而Expires是http1.0的规范,后面接的是绝对时间。
2.再验证
如果通过新鲜度检测发现需要请求服务器进行再验证,那么我们应该告诉服务器我们缓存了什么样的资源,然后服务器判断缓存资源是否与服务器当前资源一致,在此可以采用条件请求的方式实现再验证。
3.http定义了5个header用于条件请求:

  • If-Modified-Since
  • If-None-Match
  • If-Unmodified-Since
  • If-Range
  • If-Match
    详情可见上表。

Https

简单的说Https=Http+加密+认证+完整性保护。
传统的Http协议是一种应用层的传输协议,Http与TCP协议通讯,其本身存在如下缺点:

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

Https通过增加的SSL\TLS,支持对于通信内容的加密,以及对通信双方进行身份验证。

Https的加密

SSL\TLS的加密方式结合了对称加密与非对称加密的优点。首先采用非对称加密将对称秘钥使用公开秘钥加密后传输给对方。对方使用私有秘钥进行解密,得到传输的对称秘钥。之后双方再使用对称秘钥进行通讯。

Https的认证

目前,Https认证使用由数字证书认证机构颁发的公开秘钥证书。服务器的运营人员可以向认证机构提出公开秘钥申请,认证机构在审核之后,将会将公开秘钥与公钥证书绑定,服务器就可将这个公钥证书下发给客户端,客户端接收到证书后,使用认证机构的公开密钥进行验证,若验证成功,则说明这个秘钥是可信任的秘钥。

总结

Https的通讯流程:
1.Client发起请求
2.Server端响应请求,并将证书发送至Client
3.Client使用认证机构的公钥认证证书,并从证书中取出Server端公钥。
4.Client使用公钥加密一个随机秘钥,并传到Server
5.Server使用私钥解密出随机秘钥
6.通讯双方使用随机秘钥作为对称秘钥进行加密解密

Socket长连接

TCP的三次握手

在这里插入图片描述
1.首先,客户端向服务端发送一个SYN,假设此时sequence number为x。这个x是由操作系统根据一定规则生成的,不妨认为它是一个随机数。
2.服务端收到SYN后会向客户端再发送一个SYN,此时服务器的seq number=y。与此同时,会回复ACK x+1,告诉客户端已收到SYN,可发送数据。
3.客户端收到服务器的SYN后,回复一个ACK y+1,这个ACK是告诉服务器,SYN已收到,服务器可发送数据。
经过这三步,TCP连接就建立了,这里需要注意三点:

  • 连接是由客户端主动发起的
  • 在第三步客户端向服务器回复ACK的时候,TCP协议是允许携带数据的,之所以做不到是因为API的限制导致的。
  • TCP协议还允许四次握手的发生,由于API的限制,这个极端情况并不会发生。
Socket基本用法

Socket是TCP层的封装,通过Socket,我们就能进行TCP通信。Socket的使用步骤如下:
1.创建ServerSocket并监听客户连接
2.使用Socket连接服务端
3.通过Socket获取输入输出流进行通信

Socket长连接的实现

Socket长连接指的是在客户和服务端之间保持一个socket连接长时间不断开。出现以下情况时,socket将不再可用:
1.某一端关闭socket。主动关闭一方会发送FIN,通知对方要关闭TCP连接。在这种情况下,另一端如果去读socket,将会读到EoF(End of File),于是我们知道对方关闭了socket。
2.应用系统崩溃,此时socket会由内核关闭,结果跟情况1一样。
3.系统崩溃,这时候系统是来不及发FIN的,因为他已经跪了。此时对方无法得知这一情况。对方在尝试读数据时,最后会返回read time out。如果写数据,则是host unreachable之类的错误。
4.电缆被挖断、网线被拔。跟情况3差不多,如果没有对socket进行读写,两边都不知道发生了事故。跟情况3不同的是,如果我们把网线接回去,socket依旧可以正常使用。

以上几种情况有一个共同点,就是只要去读、写socket,如果socket连接不正常,我们就能知道。基于这一点,要实现一个socket长连接,我们需要做的就是不断的给对方写数据,然后读取对方的数据,也就是所谓的心跳。只要心跳还在,socket就是活的。

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值