OSI七层模型介绍,TCP/IP模型介绍,HTTP协议格式介绍
OSI七层模型
应用层------可见的终端(浏览器)
表示层------计算机识别的信息转变人可以识别的信息
回话层------传输端口和接受端口的建立回话
传输层------传输数据的协议与端口
网络层------IP地址
数据链路层------交换机传输
物理层------具体物理设备
TCP/IP模型
应用层----http https REST REMT
传输层----Socket
应用层
主机至网络层
HTTP GET Request
发起请求:1.请求头之请求行 2. 请求头之请求属性集
HTTP POST Request
发起请求:1.请求头之请求行 2. 请求头之请求属性集 3.请求体长度 4.请求的类型
OKHttp主线流程的源码解读
OKHttp的使用:
OKHttpClient------Request------newCall 执行RealCall.enqueue(){不能重复执行}------
Dispatcher.enqueue(AsyncCall:if先加入运行队列,执行异步任务 else 直接加入等待队列)------AsyncCall.excute()区分责任划分判断是用户导致还是OKHttp导致的,责任链模式,多个拦截器,返回response。
OKHttp源码解读之线程池详解
线程池的作用就是避免重复创建和销毁线程耗费内存
ThreadPoolExecutorexecutor=new ThreadPoolExecutor(0,Integer.MAX_VALUE,60, TimeUnit.MILLISECONDS,new LinkedBlockingDeque());
参数一:corePoolSize 核心线程数
参数二:maximumPoolSize 最大线程数
参数三/四:时间数值 keepAliveTime 单位unit 时分秒
正在执行的任务数量>corePoolSize---->参数三、四才会起作用
任务执行完毕后,闲置超过参数三、四设置的时间,才会回收线程,在这段时间以内就会复用线程。
参数五:workQueue队列 会把超出的任务加入队列,缓存起来
OkHttp里面的线程池:
public synchronized ExecutorServiceexecutorService() {
if (executorService ==null) {
executorService =new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
new SynchronousQueue(), Util.threadFactory("OkHttp Dispatcher", false));
}
return executorService;
}
有源码可知:OkHttp里面的线程池采用的是缓存策略,
OkHttp里面线程池,采用的是缓存方案+线程工厂+非守护线程
将核心线程设为0,只要runnable>1,60秒之内就会复用线程,超过60秒回收线程。
OKHttp源码阅读之构建者模式/责任链模式
构建着模式:链式编程结构清晰(方法返回client本身),通过Builder来实现参数的复制
责任链模式:将不同的模块分块,集成共同的接口,设置一个manager也集成共同的接口,将不同的模块添加到集合中,通过重写共同接口的方法,达到在集合中不断执行不同模块的功能,如果不符合条件就停止执行。
OKHttp 手写实现之整体框架搭建
根据OKHttp的源码创建自己的OkHttpClient2 Request2 Call2 CallBack2.....
public void uesMyOkHttp(View view) {
OkHttpClient2 okHttpClient2 =new OkHttpClient2.Builder().build();
Request2 request2 =new Request2.Builder().url("https://www.baidu.com").build();
Call2 call = okHttpClient2.newCall(request2);
call.enqueue(new CallBack2() {
@Override
public void onFailure(Call2 call, IOException e) {
Log.e("eeeeeee",e.getMessage());
}
@Override
public void onResponse(Call2 call, Response2 response)throws IOException {
Log.e("eeeeeee",response.getBody());
}
});
}
OkHttpClient2 Request2一样,都是采用创建者模式,链式编程可以传入自定义的参数、
public class OkHttpClient2 {
private Dispacher2dispacher2;
private boolean isCancle;
private Stringurl;
private int recount;
public int getRecount() {
return recount;
}
public OkHttpClient2() {
this(new Builder());
}
public OkHttpClient2(Builder builder) {
this.dispacher2 = builder.dispacher2;
this.isCancle = builder.isCancle;
this.url = builder.url;
this.recount=builder.recount;
}
public boolean getCanle() {
return isCancle;
}
public static final class Builder {
private Stringurl;
private Dispacher2dispacher2;
private boolean isCancle;
int recount =3;//默认重试3次
public Builder() {
dispacher2 =new Dispacher2();
}
public OkHttpClient2build() {
return new OkHttpClient2(this);
}
public BuildersetCount(int recount) {
this.recount = recount;
return this;
}
public Buildercancle() {
isCancle =true;
return this;
}
public Builderdispacher(Dispacher2 dispacher2) {
this.dispacher2 = dispacher2;
return this;
}
public Builderurl(String url) {
this.url = url;
return this;
}
}
public Call2newCall(Request2 request2) {
return new RealCall2(request2, this);
}
public Dispacher2dispacher() {
return dispacher2;
}
}
public class Request2 {
public static final StringGET ="GET";
public static final StringPOST ="POST";
private Stringurl;
public StringgetUrl() {
return url;
}
public StringgetRequestMethod() {
return requestMethod;
}
public MapgetmHeadList() {
return mHeadList;
}
private StringrequestMethod =GET;
private MapmHeadList =new HashMap<>();
public Request2() {
this(new Builder());
}
public Request2(Builder builder) {
this.url = builder.url;
this.requestMethod = builder.requestMethod;
this.mHeadList = builder.mHeadList;
}
public static final class Builder {
private Stringurl;
private StringrequestMethod =GET;
private MapmHeadList =new HashMap<>();
public Request2build() {
return new Request2(this);
}
public Builderget() {
requestMethod =GET;
return this;
}
public Builderpost() {
requestMethod =POST;
return this;
}
public BuilderaddHead(String key, String value) {
mHeadList.put(key, value);
return this;
}
public Builderurl(String url) {
this.url = url;
return this;
}
}
}
定义一个接口Call2
public interface Call2 {
void enqueue(CallBack2 responseCallback);
}
定义一个RealCall实现Call2
public class RealCall2implements Call2 {
private boolean excuted;
private Request2request2;
private OkHttpClient2okHttpClient2;
public boolean isExcuted() {
return excuted;
}
public Request2getRequest2() {
return request2;
}
public OkHttpClient2getOkHttpClient2() {
return okHttpClient2;
}
public RealCall2(Request2 request2, OkHttpClient2 okHttpClient2) {
this.request2 = request2;
this.okHttpClient2 = okHttpClient2;
}
@Override
public void enqueue(CallBack2 responseCallback) {
synchronized (this) {
if (excuted) {
excuted =true;
throw new IllegalArgumentException("Already Executed");
}
}
okHttpClient2.dispacher().enqueue(new AsyncCall2(responseCallback));
}
public final class AsyncCall2implements Runnable {
private CallBack2callBack2;
public Request2getRequest2() {
return RealCall2.this.request2;
}
public AsyncCall2(CallBack2 callBack2) {
this.callBack2 = callBack2;
}
@Override
public void run() {
boolean signalledCallback =false;
try {
Response2 response = getResponseWithInterceptorChain();
if (okHttpClient2.getCanle()) {
signalledCallback =true;
callBack2.onFailure(RealCall2.this, new IOException("用户取消了 请求"));
}else {
signalledCallback =true;
callBack2.onResponse(RealCall2.this, response);
}
}catch (IOException e) {
//责任的划分
if (signalledCallback) {//用户的操作
System.out.println("用户再使用过程中 出错了");
}else {
callBack2.onFailure(RealCall2.this, new IOException("OKHttp getResponseWithInterceptorChain错误 e:" + e.toString()));
}
}finally {//回收
okHttpClient2.dispacher().finished(this);
}
}
private Response2getResponseWithInterceptorChain()throws IOException {
Response2 response2 =new Response2();
response2.setBody("流程走通");
return response2;
}
}
}
通过构造参数将前面的client和request传到RealCall里面
重写enqueue方法,执行dispacher里面的enqueue方法
@Override
public void enqueue(CallBack2 responseCallback) {
synchronized (this) {
if (excuted) {
excuted =true;
throw new IllegalArgumentException("Already Executed");
}
}
okHttpClient2.dispacher().enqueue(new AsyncCall2(responseCallback));
}
创建Dipacher2 在enqueue方法里面判断是将任务添加到执行队列还是等待队列,添加到执行队列后利用线程池执行任务。
通过finally {//回收
okHttpClient2.dispacher().finished(this);
}
将等待队列的任务便利执行完毕。,还将run方法里面责任进行划分,明确是OK HTTP本身的责任还是使用者的责任,callBack2执行callback,将执行情况返回给页面,
Response2 response = getResponseWithInterceptorChain();通过责任链模式将response返回,详细情况在下面手写socket
public class Dispacher2 {
private int maxRequests =64;//同时访问任务,最大数量是64
private int maxRequestsPerHost =5;//同时访问同一个服务器域名,最大限制
private DequerunningAsyncCalls =new ArrayDeque<>();
private DequereadyAsyncCalls =new ArrayDeque<>();
public void enqueue(RealCall2.AsyncCall2 call) {
if (runningAsyncCalls.size()
runningAsyncCalls.add(call);//加入运行队列
executorService().execute(call);//然后再执行
}else {
readyAsyncCalls.add(call);//加入等待队列
}
}
private ExecutorexecutorService() {
ExecutorService executorService =new ThreadPoolExecutor(0, 64, 60l, TimeUnit.MILLISECONDS, new SynchronousQueue(), new ThreadFactory() {
@Override
public ThreadnewThread(Runnable r) {
Thread thread =new Thread(r);
thread.setName("自定义的线程。。。");
thread.setDaemon(false);
return thread;
}
});
return executorService;
}
/**
* 判断AsyncCall2中的Host,在运行的队列中,计数,然后返回
*/
private int runningCallsForHost(RealCall2.AsyncCall2 call) {
int count =0;
if (runningAsyncCalls.isEmpty()) {
return 0;
}
SocketRequestSever src =new SocketRequestSever();
//遍历运行队伍里面的所有人物,取出任务host==call.host +1
for (RealCall2.AsyncCall2 runningAsyncCall :runningAsyncCalls) {
if (src.getHost(runningAsyncCall.getRequest2()).equals(call.getRequest2())) {
count++;
}
}
return count;
}
public void finished(RealCall2.AsyncCall2 call2) {
//当前运行队列
runningAsyncCalls.remove(call2);
//等待队列为空就返回
if (readyAsyncCalls.isEmpty()) {
return;
}
//把等待队列任务移动到运行队列
for (RealCall2.AsyncCall2 readyAsyncCall :readyAsyncCalls) {
readyAsyncCalls.remove(readyAsyncCall);//杀出等待队列的任务
runningAsyncCalls.add(readyAsyncCall);
executorService().execute(readyAsyncCall);
}
}
}
创建CallBack2和AsyncCall2
public interface CallBack2 {
void onFailure(Call2 call, IOException e);
void onResponse(Call2 call, Response2 response)throws IOException;
}
public final class AsyncCall2implements Runnable {
private CallBack2callBack2;
public Request2getRequest2() {
return RealCall2.this.request2;
}
public AsyncCall2(CallBack2 callBack2) {
this.callBack2 = callBack2;
}
@Override
public void run() {
boolean signalledCallback =false;
try {
Response2 response = getResponseWithInterceptorChain();
if (okHttpClient2.getCanle()) {
signalledCallback =true;
callBack2.onFailure(RealCall2.this, new IOException("用户取消了 请求"));
}else {
signalledCallback =true;
callBack2.onResponse(RealCall2.this, response);
}
}catch (IOException e) {
//责任的划分
if (signalledCallback) {//用户的操作
System.out.println("用户再使用过程中 出错了");
}else {
callBack2.onFailure(RealCall2.this, new IOException("OKHttp getResponseWithInterceptorChain错误 e:" + e.toString()));
}
}finally {//回收
okHttpClient2.dispacher().finished(this);
}
}
private Response2getResponseWithInterceptorChain()throws IOException {
Response2 response2 =new Response2();
response2.setBody("流程走通");
return response2;
}
}
自定义拦截器
首先创建Interceptor2接口
public interface Interceptor2 {
Response2doNext(Chain2 chain2)throws IOException;
}
创建一个充实拦截器ReRequestInterceptor
public class ReRequestInterceptor implements Interceptor2 {
@Override
public Response2doNext(Chain2 chain2)throws IOException {
ChainManager chainManager = (ChainManager) chain2;
RealCall2 realCall2 = chainManager.getCall2();
OkHttpClient2 okHttpClient2 = realCall2.getOkHttpClient2();
IOException ioException =null;
if (okHttpClient2.getRecount() !=0) {
for (int i =0; i < okHttpClient2.getRecount(); i++) {
try {
Response2 response2 = chain2.getResponse(chainManager.getRequest());
return response2;
}catch (IOException e) {
ioException = e;
}
}
}
throw ioException;
}
}
创建Chain2接口
public interface Chain2 {
Request2getRequest();
Response2getResponse(Request2 request2)throws IOException;
}
创建ChainManager,将拦截器存放到集合中,循环便利
public class ChainManager implements Chain2 {
private final Listinterceptors;
private int index;
private final Request2request2;
private final RealCall2call2;
public ListgetInterceptors() {
return interceptors;
}
public int getIndex() {
return index;
}
public RealCall2getCall2() {
return call2;
}
public ChainManager(List interceptors, int index, Request2 request2, RealCall2 call2) {
this.interceptors = interceptors;
this.index = index;
this.request2 = request2;
this.call2 = call2;
}
@Override
public Request2getRequest() {
return request2;
}
@Override
public Response2getResponse(Request2 request2)throws IOException {
if(index>interceptors.size())throw new AssertionError();
if(interceptors.isEmpty())throw new IOException("interceptor is empty");
ChainManager chainManager=new ChainManager(interceptors,index++,request2,call2);
Interceptor2 interceptor=interceptors.get(index);
Response2 response2=interceptor.doNext(chainManager);
return response2;
}
}
OKHttp 手写实现之socket请求与响应
创建SocketRequestServer
public class SocketRequestServer {
private final String K = " ";
private final String VIERSION = "HTTP/1.1";
private final String GRGN = "\r\n";
/**
* todo 通过Request对象,寻找到域名HOST
* @param request2
* @return
*/
public String getHost(Request2 request2) {
try {
// http://restapi.amap.com/v3/weather/weatherInfo?city=110101&key=13cb58f5884f9749287abbead9c658f2
URL url = new URL(request2.getUrl());
return url.getHost(); // restapi.amap.com
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
/**
* todo 端口
* @param request2
* @return
*/
public int getPort(Request2 request2) {
try {
URL url = new URL(request2.getUrl());
int port = url.getPort();
return port == -1 ? url.getDefaultPort() : port;
} catch (MalformedURLException e) {
e.printStackTrace();
}
return -1;
}
/**
* todo 获取请求头的所有信息
* @param request2
* @return
*/
public String getRequestHeaderAll(Request2 request2) {
// 得到请求方式
URL url = null;
try {
url = new URL(request2.getUrl());
} catch (MalformedURLException e) {
e.printStackTrace();
}
String file = url.getFile();
// TODO 拼接 请求头 的 请求行 GET /v3/weather/weatherInfo?city=110101&key=13cb58f5884f9749287abbead9c658f2 HTTP/1.1\r\n
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(request2.getRequestMethod()) // GET or POST
.append(K)
.append(file)
.append(K)
.append(VIERSION)
.append(GRGN);
// TODO 获取请求集 进行拼接
/**
* Content-Length: 48\r\n
* Host: restapi.amap.com\r\n
* Content-Type: application/x-www-form-urlencoded\r\n
*/
if (!request2.getmHeaderList().isEmpty()) {
Map<String,String> mapList = request2.getmHeaderList();
for (Map.Entry<String, String> entry: mapList.entrySet()) {
stringBuffer.append(entry.getKey())
.append(":").append(K)
.append(entry.getValue())
.append(GRGN);
}
// 拼接空行,代表下面的POST,请求体了
stringBuffer.append(GRGN);
}
// TODO POST请求才有 请求体的拼接
if ("POST".equalsIgnoreCase(request2.getRequestMethod())) {
stringBuffer.append(request2.getRequestBody2().getBody()).append(GRGN);
}
return stringBuffer.toString();
}
}
在getResponseWithInterceptorChain()里面添加
private Response2 getResponseWithInterceptorChain() throws IOException {
// Response2 response2 = new Response2();
// response2.setBody("流程走通....");
// return response2;
List<Interceptor2> interceptor2List = new ArrayList<>();
interceptor2List.add(new ReRequestInterceptor()); // 重试拦截器
interceptor2List.add(new RequestHeaderInterceptor()); // 请求头拦截器
interceptor2List.add(new ConnectionServerInterceptor()); // 连接服务器的拦截器
ChainManager chainManager = new ChainManager(interceptor2List, 0, request2, RealCall2.this);
return chainManager.getResponse(request2); // 最终返回的Response
}
}
url 统一资源定位符
url.getHost() 域名
url.getPort() 端口
url.getFile() 传输文件
url.getProtocol() 协议