1、http的流程

  1. 使用DNS域名解析;
  2. 发起TCP的3次握手
  3. 建立TCP连接后发起http请求;
  4. 服务器响应http请求,浏览器得到返回response;
  5. 浏览器解析response,并请求其它的资源(如js、css、图片等);
  6. 浏览器对页面进行渲染。

2、Https的流程

发起请求、验证身份、协商秘钥、加密会话,具体流程如下(此例子只有客户端对服务端的单向验证):

  1、客户端向服务端发起建立HTTPS请求。

  2、服务器向客户端发送数字证书。

  3、客户端验证数字证书,证书验证通过后客户端生成会话密钥(双向验证则此处客户端也会向服务器发送证书)。

  4、服务器生成会话密钥(双向验证此处服务端也会对客户端的证书验证)。

  5、客户端与服务端开始进行加密会话。

具体的步骤如下:

第一步:客户端向服务端发起请求

1、客户端生成随机数R1 发送给服务端;

2、告诉服务端自己支持哪些加密算法;

第二步:服务器向客户端发送数字证书

1、服务端生成随机数R2;

2、客户端支持的加密算法中选择一种双方都支持的加密算法(此算法用于后面的会话密钥生成)

3、服务端生成把证书、随机数R2、会话密钥生成算法,一同发给客户端;

第三步:客户端验证数字证书。

1、验证证书的可靠性,先用CA的公钥解密被加密过后的证书,能解密则说明证书没有问题,然后通过证书里提供的摘要算法进行对数据进行摘要,然后通过自己生成的摘要与服务端发送的摘要比对。

2、验证证书合法性,包括证书是否吊销、是否到期、域名是否匹配,通过后则进行后面的流程

3、获得证书的公钥、会话密钥生成算法、随机数R2

4、生成一个随机数R3。

5、根据会话秘钥算法使用R1、R2、R3生成会话秘钥。

6、用服务端证书的公钥加密随机数R3并发送给服务端。

第四步:服务器得到会话密钥

1、服务器用私钥解密客户端发过来的随机数R3

2、根据会话秘钥算法使用R1、R2、R3生成会话秘钥

第五步:客户端与服务端进行加密会话

1、客户端发送加密数据给服务端

发送加密数据:客户端加密数据后发送给服务端。

2、服务端响应客户端

解密接收数据:服务端用会话密钥解密客户端发送的数据;                                                                加密响应数据:用会话密钥把响应的数据加密发送给客户端。

3、客户端解密服务端响应的数据

解密数据:客户端用会话密钥解密响应数据;

3、Okhttp的流程

(1)、当我们通过OkhttpClient创立一个okHttpClient 、Request 、Call,并发起同步或者异步请求时;

(2)、okhttp会通过Dispatcher对我们所有的Call(RealCall实现类)进行统一管理,并通过execute()及enqueue()方法对同步或者异步请求进行执行;
(3)、execute()及enqueue()这两个方法会最终调用RealCall中的getResponseWithInterceptorChain()方法,从阻拦器链中获取返回结果;
(4)、拦截器链中,依次通过ApplicationInterceptor应用拦截器)、RetryAndFollowUpInterceptor(重定向阻拦器)、BridgeInterceptor(桥接阻拦器)、CacheInterceptor(缓存阻拦器)、ConnectInterceptor(连接阻拦器)、NetwrokInterceptor(网络拦截器)、CallServerInterceptor(请求阻拦器)对请求依次处理,与服务的建立连接后,获取返回数据,再经过上述阻拦器依次解决后,最后将结果返回给调用方。

4、Okhttp防抓包

1、 使用Proxy.NO_PROXY进行防止抓包。
我们在使用OkHttp进行网络请求的时候防止Fiddler抓包可以简单的使用OkHttpClient.Builder中的builder.proxy(Proxy.NO_PROXY);方法就可以避免Fiddler基本抓包。

2、使用builder.proxySelector进行防止抓包。
因为第一种方法只能避免Fiddler基本抓包方式在OkHttp中还有一种方法可以防止抓包。

builder.proxySelector(new ProxySelector() {@Overridepublic List<Proxy> select(URI uri) {return Collections.singletonList(Proxy.NO_PROXY);}@Overridepublic void connectFailed(URI uri, SocketAddress sa, IOException ioe) {}});
3、验证Https证书

这种方式要在app嵌入证书,以okhttp为例:当okhttp使用X509TrustManager对服务器证书进行校验时,如果服务器证书的 subjectDN 和嵌入证书的 subjectDN 一致,我们再进行签名内容 signature 的比对,如果不一致,抛出异常。示例代码如下:

  • 首先从本地读出证书,获取一个X509Certificate
val myCrt: X509Certificate by lazy {getCrt(R.raw.my_ca)
}private fun getCrt(@RawRes raw: Int): X509Certificate {val certificateFactory = CertificateFactory.getInstance("X.509")val input = ApplicationContext.resources.openRawResource(raw)input.use {return certificateFactory.generateCertificate(input) as X509Certificate}
}
  • 检查服务器证书时对比嵌入的证书
private fun getTrustManagerInRelease(): X509TrustManager {return object : X509TrustManager {override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String?) {}override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String?) {val myCrt: X509Certificate = myCrtif (chain[0].subjectDN.name == myCrt.subjectDN.name) {if (!myCrt.signature!!.contentEquals(chain[0].signature)) {throw SSLHandshakeException("签名不符!")}}}}
}
  • 将自定义的 SSLSocketFactory 和 X509TrustManager 将入到 okhttp 客户端
private fun getClient(ssl: SSLSocketFactory, trustManager: X509TrustManager): OkHttpClient {return OkHttpClient.Builder().retryOnConnectionFailure(true).proxy(Proxy.NO_PROXY).sslSocketFactory(ssl, trustManager).build()
}

5、拦截器

RetryAndFollowUpInterceptor(重试和重定向拦截器)
第一个接触到请求,最后接触到响应;负责判断是否需要重新发起整个请求;主要就是完成两件事情:重试与重定向
BridgeInterceptor(桥接拦截器)
补全请求,并对响应进行额外处理
CacheInterceptor(缓存拦截器)
请求前查询缓存,获得响应并判断是否需要缓存
ConnectInterceptor(链接拦截器)
与服务器完成TCP连接 (Socket)
CallServerInterceptor(请求服务拦截器)
与服务器通信;封装请求数据与解析响应数据(如:HTTP报文)
关联:https://blog.csdn.net/qq_45866344/article/details/125052085

6、优点

(1)内置连接池,支持连接复用;
(2)支持gzip压缩响应体;
(3)通过缓存避免重复的请求;
(4)支持http2,对一台机器的所有请求共享同一个socket

7、连接池

OkHttp里面使用ConnectionPool实现连接池,而且默认支持5个并发KeepAlive,默认链路生命为5分钟。 双端队列Deque,双端都能进出,用来存储连接的。OkHttp框架采用的是Socket连接,底层涉及到Http协议的封装和解封,TLS/SSL安全协议的封装等;连接池主要涉及到几大类:ConnectionPool,RealConnection,StreamAllocation,ConnectionInterceptor;

1.ConnectionPool类:

该类是OkHttp的连接池,连接池可以有效地提高连接的使用效率;
主要涉及到添加,获取,删除连接等功能;

2.RealConection类:

RealConnection是Connection的是实现类,代表着一个真正的socket连接,RealConnection代表着客户端和服务器端已经有了一个通信链路;

3.StreamAllocation类:

StreamAllocation是外界使用Okhttp的连接的桥梁,通过newStream方法返回一个可使用的流,即HttpCodec实例,通过HttpCodec可以将输入数据封装成相应的Http协议的数据,然后通过socket的输出流发送出去,同时也可以通过socket的输入流读取数据并解析数据;

8、线程池

在OKHttp中,创建了一个阀值是Integer.MAX_VALUE的线程池,它不保留任何最小线程,随时创建更多的线程数,而且如果线程空闲后,只能多活60秒。所以也就说如果收到20个并发请求,线程池会创建20个线程,当完成后的60秒后会自动关闭所有20个线程。他这样设计成不设上限的线程,以保证I/O任务中高阻塞低占用的过程,不会长时间卡在阻塞上。

面试复习题--Okhttp相关推荐

  1. Java高频面试复习题,助你吊打面试官

    前言 2022年对程序员来说是特别严峻的一年,也是大改革的一年,大部分人因为今年"疫情"的原因纷纷离开了自己原有的岗位,也有人抓住机会逆流而上拿到更高的待遇! 2022年金九银十已 ...

  2. 2022年各大厂Java高频面试复习题,帮你吊打面试官!

    前言 2022年对程序员来说是特别严峻的一年,也是大改革的一年,大部分人因为今年"疫情"的原因纷纷离开了自己原有的岗位,也有人抓住机会逆流而上拿到更高的待遇! 2022年金九银十已 ...

  3. Java高频面试复习题,助你面试成功

    前言 2022年对程序员来说是特别严峻的一年,也是大改革的一年,大部分人因为今年"疫情"的原因纷纷离开了自己原有的岗位,也有人抓住机会逆流而上拿到更高的待遇! 2022年金九银十已 ...

  4. Github上365道Java高频面试复习题,助你吊打面试官

    前言 2022年对程序员来说是特别严峻的一年,也是大改革的一年,大部分人因为今年"疫情"的原因纷纷离开了自己原有的岗位,也有人抓住机会逆流而上拿到更高的待遇1 我这里收集了一套大厂 ...

  5. 365道Java高频面试复习题,助你吊打面试官

    前言 2022年对程序员来说是特别严峻的一年,也是大改革的一年,大部分人因为今年"疫情"的原因纷纷离开了自己原有的岗位,也有人抓住机会逆流而上拿到更高的待遇! 无论如何在这几个月的 ...

  6. Github 上 365 道 Java 高频面试复习题,助你吊打面试官

    前言 无论如何在这两个月的跳槽黄金期 筹备面试是最重要的了,你有规划好自己的复习方向了吗? 我这里收集了一套大厂的面试题包含了答案,技术点概括了:基础.JVM.多线程并发.spring.mybatis ...

  7. 面试复习题--jvm的细枝末节

    1.数组是对象,底层数组是继承object的,而且实现了clone和serizable接口 2.class各个阶段代码被执行的时机 父类静态代码块 子类静态代码块 SuperBean属性类静态代码块 ...

  8. 面试复习题--锁的细枝末节

    1.对于所对象的选择 我们在选择synchronized 进行代码块锁定时,选择的锁对象应该是new Object,还是new Object[0], 或者是new byte[0],其实在Android ...

  9. 面试复习题-- Android构建细枝末节

    1.这是因为 NDK r17 之后不再支持 mips 平台,在 build.gradle 里增加如下配置可解决 android {defaultConfig {.....}packagingOptio ...

最新文章

  1. MATLAB利用YCBCR切割出人脸头像
  2. el replace 表达式_EL表达式截取字符串 各种字符串操作的方式全解 泽0715新浪博客...
  3. 如果沟通有范式,它会是怎么样子?
  4. 2019年我总结的前端面试题
  5. REDIS 在电商中的实际应用场景(转)
  6. Multi_thread--Linux下多线程编程互斥锁和条件变量的简单使用
  7. Python风格总结:Python3 标准库概览
  8. LINQ to Objects和多线程实现文件查找与分组
  9. Java:注解(Annotation)自定义注解入门
  10. linux机器crt连接不上,SecureCRT连不上Linux主机了,求破
  11. jQuery源码系列(一)
  12. JAVA文件夹批量重命名
  13. nb信号和4g信号_NB-IoT DTU与4G DTU有什么不同之处
  14. java猜拳小游戏心得体会_java实现猜拳小游戏
  15. 好奇心是怎么驱动成功的
  16. 移动硬盘插上电脑卡住_插入移动硬盘死机故障分析及解决方案(图文详解)
  17. hdf heg 批量拼接_MODIS处理工具MRT已被HEG代替
  18. python连接sap接口_基于Python的SAP流程自动化
  19. 计算机专业必看!10天用Flutter撸了个高仿携程App,好文推荐
  20. 在每一个时光寻找,寻找适合我的孤岛。

热门文章

  1. mac下编译ncnn和ncnn中的pnnx
  2. IPv4地址分类(A类 B类 C类 D类 E类)
  3. 装机吧的小编告诉你破解电脑密码的办法
  4. js解leetcode(62)-中等
  5. 实战!我用 Wireshark 让你「看得见」 TCP
  6. 基于PHP+小程序(MINA框架)+Mysql数据库的电影院售票选座小程序系统设计与实现
  7. Android保活黑科技的技术实现,在阿里工作5年了
  8. 三次贝塞尔曲线画圆的方法。
  9. WinForm加载网络图片并显示进度条
  10. Nginx 0.8.x + PHP 5.2.13(FastCGI)搭建胜过Apache十倍的Web服务器(第6版)[转]