1. 介绍
okHttp技术已被Android4.4之后纳入HttpURLConnection底层通信库,重要性不言而喻。
okhttp对网络通信中的通信协议,数据解析,I/O,缓存,并发请求实现了良好的策略,并拓展和支持了Application/NetWork拦截,HTTP2协议,数据ZIP压缩等功能。HTTPS其实是有两部分组成:HTTP + SSL / TLS
2. 通信
2.1 SSL/TLS加密: 保证数据传输的安全。
方法:客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。双方会通过通信中的几个随机随机数生成对称机密的“对话密钥”。对话密钥用户加密传输的数据,RSA公钥和私钥是为了验证各自的身份。通过两轮共四次握手确定了各自身份和加密方法。参考
SSL(Secure Socket Layer,安全套接字层):位于可靠的面向连接的网络层协议和应用层协议之间的一种协议层。
TLS(Transport Layer Security,传输层安全协议):用于两个应用程序之间提供保密性和数据完整性。
区别:TLS建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本。在TLS与SSL3.0之间的差别主要是它们所支持的加密算法不同。参考
公钥、私钥 的解释
公钥 :用于向外发布,任何人都能获取,
私钥 :要自己保存,切勿给别人
一下两种情况经常有人弄混,一定要理解。
情况1:公钥用于【加密】, 私钥用于【解密】
如果加密密钥是公开的,这用于客户给私钥所有者上传加密的数据,这被称作为公开密钥加密(狭义)。
例如,网络银行的客户发给银行网站的账户操作的加密数据。HTTPS 等。
情况2:公钥用于【解密】,私钥用于【加密】
如果解密密钥是公开的,用私钥加密的信息,可以用公钥对其解密,用于客户验证持有私钥一方发布的数据或文件是完整准确的,接收者由此可知这条信息确实来自于拥有私钥的某人,这被称作数字签名,公钥的形式就是数字证书。例如,从网上下载的安装程序,一般都带有程序制作者的数字签名,可以证明该程序的确是该作者(公司)发布的而不是第三方伪造的且未被篡改过(身份认证/验证)。
2.2 SOCKET通信
传输层的TCP是基于网络层的IP协议的,而应用层的HTTP协议又是基于传输层的TCP协议的,而Socket本身不算是协议,它只是提供了一个针对TCP或者UDP编程的通信API。Socket除非主动断开否则可保持长连接,HTTP1.0短连接,HTTP1.0的长连接有时限。HTTP通信服务可使用sockets实现。参考
3. I/O : Okio库
- Okio作为OkHttp使用的I/O接口,实现对文件/字符流/字节流等的读写的良好封装,使得通过
sink()
及souce()
即可进行数据读写。 - i/o流向
sink -> socket/File
Source <- socket/File
4. HTTP Interceptor图
httpInterceptor图5. 通信Platform
OkHttp的最底层是Socket
okhttp//实现HTTP协议
framwork//JRE,实现JDK中Socket封装
jvm//JDK的实现,本质对libc标准库的native封装
bionic//android下的libc标准库
ystemcall//用户态切换入内核
kernel//实现下协议栈(L4,L3)与网络驱动(一般是L2,L1)
6. 连接池的自动清理CleanUp
okhttp使用了类似于引用计数法与标记擦除法的混合使用,当连接空闲或者释放时,StreamAllocation的数量会渐渐变成0,从而被线程池监测到并回收,这样就可以保持多个健康的keep-alive连接
7. HTTP缓存策略
okHttp缓存策略可通过Header中设置Expires/Cache-Control/ETag/Last-Modified等设置。Expires/Cache-Conrol确定是否进行网络资源获取,ETag(if-not-match)/Last-Modified(if-modified-since)确定网络请求是否从代理CDN缓存中获取。
HTTP缓存策略
8. HTTP缓存的存储策略
缓存使用DiskLruCache结构管理缓存文件FileSystem,DiskLruCache内部使用LinkHashMap进行LRU算法实现。在缓存文件清理策略上使用LRU算法,以线程池进行缓存的自动清理。
扩展
LinkHashMap可以保持有序(插入顺序/LRU访问顺序)是因为内部维护了一个双向链表。
9. OKHTTP线程队列
OkHttp线程池可通过缓存和阈值控制CPU工作量。
采用Dispatcher分发技术与线程池配合,实现单生产者多消费者模式下的高并发低阻塞。
使try/finally减少使用采用wait/notify减少了编码复杂性和出错率。
1
网友评论