前言
看任何源码框架,尽量带着问题去看。OkHttp的连接层,我最开始对它的疑问有两个:
- 它是怎么将我包装好的
Request
对象发送到服务器,又是怎么从服务器获取到数据然后包装成Response
对象回调给开发人员的? - OkHttp的网络连接复用机制是怎么样的?
博客内容:
- 为什么需要复用socket
- TCP连接和分手过程
- TLS连接过程
- 数据请求和响应过程
- socket连接的复用原理
为什么需要复用socket
我们在面试时,经常会被问到安卓性能优化的知识,性能优化主要分为两部分,一个是网络优化,一个是内存优化。网络优化,现在OkHttp已经帮我们做好了,但是,我们还是有必要了解一下OkHttp网络优化的一些原理。
在我之前的一篇文章-安卓进阶(6)之OkHttp整体架构/基本使用/OkHttpClient原理解析有讲到,OkHttp设置的默认最大并发请求是64个,单域名下并发请求最大是5个(如果想改并发请求数量的话,可以在调度器Dispathcer中改)。一般在app中,我们都是往一个域名去请求数据,换句话说,OkHttp默认支持的最大并发数可以认为是5个。
所有的http/https请求,底层都是基于socket通信的。然而,每创建一个socket对象时,TCP连接和分手过程比较消耗时间,所以,尽量去复用socket对象。
TCP连接和分手过程
连接过程
不管是http,还是https,都需要有TCP连接和分手过程。
连接主要分为三个步骤:
- 客户端发送连接请求和一个标志位,并等待服务器响应;
- 服务器接收客户端的标志位,并将服务器的一个标志位和客户端的标志位都发给客户端;
- 客户端接收到服务器的标志位,并告诉服务器,TCP连接成功,后面就可以开始数据通信了。
分手过程
4个步骤:
- 客户端发送报文段,告诉服务器,不需要数据连接了;
- 服务器接收客户端的报文段,回送报文段给客户端;
- 服务器再发送报文段给客户端,请求关闭连接;
- 客户端接收服务器关闭连接的报文段,告诉服务器,关闭连接。
PS:关于具体发送的哪些标志位和报文段,可以看下面的参考文章,标志位和报文段我感觉是汇编语言的,死记硬背那些没啥用,记住流程就好!
TLS连接过程
TLS
是https
协议中专有的,它是在http
和TCP/IP
之间,增加了一层。这一层,可以理解为是为了对数据的加密而出现的。
连接过程:
- 通过RSA非对称加密,在服务器和客户端建立一个加密通道;
- 客户端用安全通道生成随机对称密钥,并将对称密钥发送给服务器;
- 客户端和服务器通过随机生成的对称密钥进行加解密。
连接池复用机制
OkHttp的连接对象是RealConnection
,而不是HttpUrlConnection
。连接池中有个双端队列参数connections
,它的特点是后进先出,主要负责对多个RealConnection
对象的管理。连接池中的RealConnection
的存活时间是5分钟,设置这个时间,估计也是OkHttp开发人员通过各种合理性测试得来的。设置的时间太短,会经常重连接导致耗时比较长;设置的时间太长,会出现很多僵尸连接,导致app持续占用资源。关于OkHttp的连接池复用机制,还没有完全吃透,先暂告一段落了,以后有时间继续啃源码~
参考文章
OkHttp3源码解读四:连接层
TCP连接与OKHTTP复用连接池
浅析 OkHttp 的 TLS 连接过程
okhttp连接池复用机制