1. HTTP状态码:
1xx: Infomational (信息状态码) ,接收的请求正在处理
2xx: Succeed(成功),请求正常处理完毕,如 200
3xx: Redirection(重定向),需要进行附加操作,一般是没有响应数据返回的,如 304(Not,modified)307 (重定向)
4xx: Client Error (客户端的错误),服务器无法处理请求,如 404
5xx: Server Error (服务端的错误),服务器处理请求出错,如 500
2.Http 和 Https 的区别:
Https = Http + 加密 + 验证 + 完整
端口:Http (80) Https (443)
Http 的缺点:
2.1 数据是没有加密传输,可能遭遇窃听
2.2 不验证通信方的身份,可能会遭遇伪装
2.3 无法验证报文的完整性,可能会遭遇篡改
TLS/SSL 协议:
加密:对称加密(AES,DES) + 非对称加密 (RSA,DSA)
证书:要钱(便宜),建立连接的速度会拖慢,TCP 3 次握手,8 次握手
![
3. Http 1.x 和 Http 2.0 的区别
3.1 Http 2.0 采用二进制格式而非文本格式
3.2 Http 2.0 支持完全的多路复用
3.3 Http 2.0 使用报头压缩,降低开销
3.4 Http 2.0 让服务器将响应主动推送给客户端,(带内容推送,不带内容推送的通知)
4. 异步和同步
跟线程没什么关系,打电话
同步:打电话 -> 处理(没挂断) -> 反馈
异步:打电话 -> 处理(挂断)-> 打回来
5. 整体架构和源码分析
5.1 自己如果要写一个框架你要怎么处理
- 网络是耗时,开线程,new Thread() ? 线程池
- 处理网络,HttpUrlConnection(简单) 或者 输入流+Socket(麻烦)
- 网络请求头信息处理,缓存的处理,文件格式上次的方式(表单提交,拼格式)
- 路由的一些操作,Http 2.0 复用 等等
5.2 OkHttp 大致内容 Okio,Socket
okio:原生的JavaIO + 自定义封装 ,其实就是对于 io 的封装
Socket 连接
拦截器
整体主线流程
- 1、建造者模式构建okhttpClient
mOkHttpClient = new OkHttpClient.Builder()
.cache(cache)
.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
.addInterceptor(mRewriteCacheControlInterceptor)
.addInterceptor(new LoggingInterceptor())
// .addInterceptor(interceptor)
// .cookieJar(new CookiesManager())
.cookieJar(cookieJar)
.build();
2、建造者模式构建Request
Request.Builder requestBuilder = new Request.Builder();
appendHeaders(requestBuilder);
url = appendParams(url, mParams.urlParamsMap);
return requestBuilder.get().url(url).tag(tag).build();
- 3、newCall(不能重复执行)
实际返回的是RealCall中的enqueue方法
源码
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
- 4、实际调用的Dispatcher.enqueue方法,而参数便是AsyncCall
synchronized void enqueue(AsyncCall call) {
//如果正在运行队列的大小小于64并且主机允许的最大并发请求数量小于5则加入正在运行的异步请求中,否则加入等待异步队列中
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}`
- 5、异步执行任务AsyncCall中的execute方法
executorService().execute(call);//call==AsyncCall
- 6、返回结果
@Override protected void execute() {
boolean signalledCallback = false;
try {
//getResponseWithInterceptorChain责任链
Response response = getResponseWithInterceptorChain();
if (retryAndFollowUpInterceptor.isCanceled()) {
signalledCallback = true;
responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
} else {
signalledCallback = true;
responseCallback.onResponse(RealCall.this, response);
}
} catch (IOException e) {
if (signalledCallback) {
// Do not signal the callback twice!
Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
} else {
responseCallback.onFailure(RealCall.this, e);
}
} finally {
client.dispatcher().finished(this);
}
}
}
java几种线程池
- 缓存线程池
Executors.newCachedThreadPool()
源码
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
- 单线程池
Executors.newSingleThreadExecutor()
源码
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
OKHttp里面的线程池
- enqueue源码分析:实际调用的是RealCall中的enqueue代码
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
dispatch中的enqueue方法
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
executorService()的源码
public synchronized ExecutorService executorService() {
if (executorService == null) {
executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
}
return executorService;
}
Util.threadFactory的源码分析
public static ThreadFactory threadFactory(final String name, final boolean daemon) {
return new ThreadFactory() {
@Override public Thread newThread(Runnable runnable) {
Thread result = new Thread(runnable, name);
result.setDaemon(daemon);
return result;
}
};
}
分析结果:OkHttp里面的线程池采用的是缓存方案+线程工厂,而且不是守护线程
Okhttp源码阅读之责任链getResponseWithInterceptorChain
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
//自定义拦截器
List<Interceptor> interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
//重试与重写拦截器
interceptors.add(retryAndFollowUpInterceptor);
//请求信息处理拦截器
interceptors.add(new BridgeInterceptor(client.cookieJar()));
//缓存拦截器
interceptors.add(new CacheInterceptor(client.internalCache()));
//连接拦截器
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(forWebSocket));
Interceptor.Chain chain = new RealInterceptorChain(
interceptors, null, null, null, 0, originalRequest);
return chain.proceed(originalRequest);
}
剩下的下一篇文章再分析