OkHttp源码:
dns 域名解析 tcp/ip连接 -》 请求数据
分发机制
同步请求 正在执行的队列
异步请求 等待队列 正在执行队列(并发 64) 在正在运行队列中同一个host 大于等于5个 不放入running队列 (running队列中 同一个host任务不能大于等于5个)
okhttp 设计到设计模式
构建者设计模式 OkhttpClient Request 等对象的创建
单例模式 Platform类中 okhttp 使用单例模式
责任链模式 拦截器的调用
okhttp 核心类
1.dispatcher 分发器
2.intercepter 拦截器
okhttp 执行一个异步任务流程
1.创建个 okhttpClient
2.创建个 request
3.client.newcall(request)--> 返回个realcall
4.realcall excute 同步 exqueue 异步
5.callback回调中 不能更新ui 需要在主线程中更新 callback onfailure(失败) onResponse (成功)
dispatcher 异步流程
realCall-->exqueue-->okhttpClient.dispatcher--> readlyAsyncCalls--> promoteAndExcute-->1.RunningAsyncCalls 中任务个数小于64 2.同一个host 不超过五个-->RunningAyncCalls-->executeto-->执行完了-->finished-->promoteAndExecute
异步分发用到的线程池
核心线程数 为0 工作线程为 Integer.MAX_VALUE, 队列为 没有容量的队列 (synchronousQueue [ˈsɪŋkrənəs]) 第二个进来 大于核心线程 加入队列 队列数量为0 开启工作线程 这样效率提升
线程池流程 --->核心线程 -->队列-->队列满了 --->工作线程---->工作线程达到了最大数据 队列满了 -->拒绝策略
小于核心线程数 创建核心线程 大于核心线程 放入队列等待 创建非核心线程 队列满了 拒绝策略 线程池添加顺序?
val response =getResponseWithIntercepterChain
拦截器
重试重定向拦截器 重定向次数最多 20
桥接拦截器 处理请求头信息 headler keep_alive content_type
缓存拦截器 缓存数据的
连接拦截器 连接服务器操作
callService 拦截器 请求服务器获取数据
重试重定向拦截器
缓存拦截器:(只缓存 get数据 不缓存post数据)
怎么判断 取不取缓存
catchStrategy 缓存策略
CacheStrategy strategy = new CacheStrategy.Factory(now, chain.request(), cacheCandidate).get();
Request networkRequest = strategy.networkRequest;
Response cacheResponse = strategy.cacheResponse;
networkRequest cashResponse
null notNull 取缓存
notNull null 请求数据
null null 504 报错
notNull notNull 请求数据 返回 304更新缓存 返回缓存
连接拦截器
http 协议是基于tcp/ip协议
代理分为 http代理 (只能代理http协议 http普通代理 https隧道代理)与socks代理(可以代理任何tcp/ip协议)
连接池:
什么是连接池 :连接对象 池 (是个队列)
get/put操作 put 将当前的连接对象放入到队列 --》clearUp方法 ---》 1.闲置连接数最多五个 连接闲置事件最长5分钟 --》遍历线程池清除不符合需求连接 (闲置事件越长 优先清除)
可能设置到的面试题
计算机网络体系结构
1.tcp /udp的区别
tcp 安全协议 连接要进行 三次握手操作 确定连接成功 才会通讯
udp 不安全协议 不需要进行连接判断 直接发送数据 使用 音视频直播
2.Tcp模型 OSI模型
Tcp模型 链路层 (mac地址物理地址) 网络层(ip地址) 传输层(端口号) 应用层
OSI模型 物理层 链路层 网络层 传输层 会话层 表示层 应用层
3.三次握手
1.为什么要进行三次握手 客户端以及服务端确保自己能接受能发送的最少次数是三次
2.三次握手过程
客户端 发送SYN 标志位=1 初始化序列号 seq(随便定义 100)的包 到服务端 客户端处于 SYN_SEND 状态 服务端收到消息 发送SYN= 1 seq (服务端初始化序列号 1000) ACK=1 ack=101 服务端处于 SYN_RCVD状态
客户端 发送个ACK=1 ack=1001的包 进入 established状态 服务端收到信息 也变成 established 状态
4.FSN 洪泛攻击 和dos ddos攻击的区别
FSN 攻击 是在第一次握手的时候利用虚假ip 向服务端发送包 服务端进入收到消息 SYN_RCVD等待状态 向虚假ip客户端进行第二次握手 因为是虚假的ip 收不到回应 无法进行第三次握手 服务器一直会在等待状态 大量的虚假ip及进行三次握手 就会造成服务器内存 cpu进行飙升 从而影响正常用户
dos (denial of service 拒绝服务)攻击 三次握手成功,发送大量的请求 让服务器带宽变小,cpu增长 从而影响正常的用户
ddod (destributed denial of servise 分布式拒绝服务) 相当于 控制不同地理位置上面的电脑 (攻击者)对服务器进行攻击
5.四次挥手
客户端 发送FIN 标志位=1 初始化序列号 seq(随便定义 100)的包到 服务器 客户端处于 FIN_WAIT_1状态 服务端收到消息 发送ACK=1 ack=101的确认包 服务端处于 CLOSE_WAITE状态
客户端接受到 服务端确认包之后 进入 FIN_WAIT_2状态
服务端 发送FIN=1 seq=y的包 服务端进入 CLOSE状态 客户端发送 ACK=1 seq=y+1 进入到 TIME_WAITTING 状态 服务器接受到包 进入CLOSED状态 客户端 等待2*MSL时间 之后变成CLOSED
6.为什么要进行四次挥手
因为 客户端和服务端是全双工的 为了确保都关闭的 需要四次
因为客户端向服务端发送关闭消息的时候 服务端有向客户端正在传输的数据的 不能直接断开的 ,所以先发送个确认包给客户端 等处理完了 再次发送断开包的
7.为什么客户端 要有 TIME_WAITTING 状态 时间为 2*MSl 时间
MSL 请求的报文在internet中存活的最大时间 官方是2分钟 现实是30 秒 所以 timewaitting 时间为 1-4 分钟
1.客户端 发送的确认包丢失 服务端会再次发送 FIN包到客户端 客户端 在发送确认包到服务端 如果关闭之后 就不会收到FIN消息
2. 客户端当发送了确认包的时候 服务端收到消息 发现有个消息没有处理完成 要给客户端发送个数据的 如果说客户端直接关闭的话 就不会收到消息的了
3. 端口唯一性 如果说一个应用占用了一个端口 那么其他的应用就不能占用这个端口的 如果客户端不等待2*msl时间 直接断开 会出现这样问题 a 断开了 b占用了这个端口 这时a发给服务端的确认包丢失,服务端发送FIN包 应该a接受 但是现在端口已被b占用,所用b收到了a的数据