okhttp源码

添加依赖

implementation 'com.squareup.okhttp3:okhttp:3.14.5'

okhttp最基本的请求

//请求客户端
      OkHttpClient okHttpClient = new OkHttpClient();
      //使用builder模式生成request对象
      Request request = new Request.Builder()
              .url("https://i0.hdslb.com/bfs/article/2b2d2f26caa0ebf07dbe617be4a5ba919eaa0724.jpg@1320w_742h.webp")
              .build();
      //请求同步
      Response response = okHttpClient.newCall(request).execute();

      //请求异步,开启一个子线程,不会阻塞
      okHttpClient.newCall(request).enqueue(new Callback() {
          @Override
          public void onFailure(Call call, IOException e) {

          }

          @Override
          public void onResponse(Call call, Response response) throws IOException {

          }
      });

###1.创建客户端okhttpClient源码:

OkHttpClient okHttpClient = new OkHttpClient();

public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {
public OkHttpClient() {
     this(new Builder());
}
//Builder.builder()方法调用这个构造函数并把builder传进来
OkHttpClient(Builder builder) {
  this.dispatcher = builder.dispatcher;
  this.proxy = builder.proxy;
  this.protocols = builder.protocols;
  this.connectionSpecs = builder.connectionSpecs;
  this.interceptors = Util.immutableList(builder.interceptors);
  this.networkInterceptors = Util.immutableList(builder.networkInterceptors);
  this.eventListenerFactory = builder.eventListenerFactory;
  this.proxySelector = builder.proxySelector;
  this.cookieJar = builder.cookieJar;
  this.cache = builder.cache;
  this.internalCache = builder.internalCache;
  this.socketFactory = builder.socketFactory;

  boolean isTLS = false;
  ......

  this.hostnameVerifier = builder.hostnameVerifier;
  this.certificatePinner = builder.certificatePinner.withCertificateChainCleaner(
      certificateChainCleaner);
  this.proxyAuthenticator = builder.proxyAuthenticator;
  this.authenticator = builder.authenticator;
  this.connectionPool = builder.connectionPool;
  this.dns = builder.dns;
  this.followSslRedirects = builder.followSslRedirects;
  this.followRedirects = builder.followRedirects;
  this.retryOnConnectionFailure = builder.retryOnConnectionFailure;
  this.connectTimeout = builder.connectTimeout;
  this.readTimeout = builder.readTimeout;
  this.writeTimeout = builder.writeTimeout;
  this.pingInterval = builder.pingInterval;
}
}

###2.发送HTTP请求
Request:包括:请求地址url,请求方法method,请求头head,请求体requestBody,标志位tag

Request request = new Request.Builder().url("url").build();

public final class Request {
final HttpUrl url;
final String method;
final Headers headers;
final @Nullable RequestBody body;
final Map, Object> tags;

private volatile @Nullable CacheControl cacheControl; // Lazily initialized.
//build()最终调用这个方法
Request(Builder builder) {
  this.url = builder.url;
  this.method = builder.method;
  this.headers = builder.headers.build();
  this.body = builder.body;
  this.tags = Util.immutableMap(builder.tags);
}
//写好默认的方法和头,url给我们写
public static class Builder {
  @Nullable HttpUrl url;
  String method;
  Headers.Builder headers;
  @Nullable RequestBody body;

  /** A mutable map of tags, or an immutable empty map if we don't have any. */
  Map, Object> tags = Collections.emptyMap();

  public Builder() {
    this.method = "GET";
    this.headers = new Headers.Builder();
  }
  Builder(Request request) {
    this.url = request.url;
    this.method = request.method;
    this.body = request.body;
    this.tags = request.tags.isEmpty()
        ? Collections.emptyMap()
        : new LinkedHashMap<>(request.tags);
    this.headers = request.headers.newBuilder();
  }
   public Builder url(String url) {
    ......

    // Silently replace web socket URLs with HTTP URLs.
    if (url.regionMatches(true, 0, "ws:", 0, 3)) {
      url = "http:"   url.substring(3);
    } else if (url.regionMatches(true, 0, "wss:", 0, 4)) {
      url = "https:"   url.substring(4);
    }

    HttpUrl parsed = HttpUrl.parse(url);
    ......
    return url(parsed);
  }
  public Request build() {
    ......
    return new Request(this);
  }
}

okhttp中最重要的是一个拦截器,通过拦截器进行分发。进一步分析代码:

okHttpClient.newCall(request).execute()

//newCall()方法实际返回的是realCall对象
@Override public Call newCall(Request request) {
  return RealCall.newRealCall(this, request, false /* for web socket */);
}

#RealCall的execute、enqueue方法

//同步的调用方法
@Override public Response execute() throws IOException {
  synchronized (this) {
//判断call是否已经被请求
    if (executed) throw new IllegalStateException("Already Executed");
    executed = true;
  }
  transmitter.timeoutEnter();
  transmitter.callStart();
  try {
    client.dispatcher().executed(this); //okhttp的异同步请求
    return getResponseWithInterceptorChain();//okhttp的拦截器,真正做网络请求,并返回一个response的结果
  } finally {
    client.dispatcher().finished(this); //通知dispatcher任务执行完了。
  }
}

Response getResponseWithInterceptorChain() throws IOException {
  // Build a full stack of interceptors.
 //拦截器的集合
  List interceptors = new ArrayList<>();
  interceptors.addAll(client.interceptors());
  interceptors.add(new RetryAndFollowUpInterceptor(client));//重试,重定向
  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, transmitter, null, 0,
      originalRequest, this, client.connectTimeoutMillis(),
      client.readTimeoutMillis(), client.writeTimeoutMillis());

  boolean calledNoMoreExchanges = false;
  try {
    Response response = chain.proceed(originalRequest);
    if (transmitter.isCanceled()) {
      closeQuietly(response);
      throw new IOException("Canceled");
    }
    return response;
  } catch (IOException e) {
    calledNoMoreExchanges = true;
    throw transmitter.noMoreExchanges(e);
  } finally {
    if (!calledNoMoreExchanges) {
      transmitter.noMoreExchanges(null);
    }
  }
}


//异步的调用方法
@Override public void enqueue(Callback responseCallback) {
  synchronized (this) {
    if (executed) throw new IllegalStateException("Already Executed");
    executed = true;
  }
  transmitter.callStart();
  client.dispatcher().enqueue(new AsyncCall(responseCallback));
}

异步请求分析

//异步的调用方法,参数callBack是个接口实例
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
  if (executed) throw new IllegalStateException("Already Executed");
  executed = true;
}
transmitter.callStart();
//dispatcher是okhttpclient的Builder的一个成员。
//AsynCall是RealCall的一个内部类,AsynCall继承一个NamedRunnable的抽象类
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}

final class AsyncCall extends NamedRunnable {
  private final Callback responseCallback;
  private volatile AtomicInteger callsPerHost = new AtomicInteger(0);
 //传入实例的接口
  AsyncCall(Callback responseCallback) {
    super("OkHttp %s", redactedUrl());
    this.responseCallback = responseCallback;
  }
  ....
  @Override protected void execute() {
    boolean signalledCallback = false;
    transmitter.timeoutEnter();
    try {
      Response response = getResponseWithInterceptorChain();//同样调用拦截器方法得到response
      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);
      }
    } catch (Throwable t) {
      cancel();
      if (!signalledCallback) {
        IOException canceledException = new IOException("canceled due to "   t);
        canceledException.addSuppressed(t);
        responseCallback.onFailure(RealCall.this, canceledException);
      }
      throw t;
    } finally {
     //当任务执行完成后,无论是否有异常,都会执行Dispatcher的finished函数
      client.dispatcher().finished(this);
    }
  }
}


public abstract class NamedRunnable implements Runnable {
......

@Override 
public final void run() {
 ......
  try {
    execute();//使得抽象方法实例在这里被调用
  }
  ......
}
protected abstract void execute();
}

现在我们知道client.dispatcher().enqueue(new AsyncCall(responseCallback))才是真正的执行请求,那么我们来看看dispatcher().enqueue这个方法
###核心重点类Dispatcher线程池介绍

public final class Dispatcher {
//最大并发请求数
private int maxRequests = 64;
//每个主机最大请求数
private int maxRequestsPerHost = 5;
private @Nullable Runnable idleCallback;
//线程池
private @Nullable ExecutorService executorService;

/** 准备执行的请求. */
private final Deque readyAsyncCalls = new ArrayDeque<>();

/** R正在执行的异步请求,包含已经取消但未执行完的请求 */
private final Deque runningAsyncCalls = new ArrayDeque<>();

/**  正在执行的同步请求,包含已经取消单未执行完的请求 */
private final Deque runningSyncCalls = new ArrayDeque<>();

public Dispatcher(ExecutorService executorService) {
  this.executorService = executorService;
}
public Dispatcher() {
}
//创建单例线程池
public synchronized ExecutorService executorService() {
//corePoolSize:最小并发线程数,如果是0的话,空闲一段时间后所有线程将全部被销毁。
//maximumPoolSize: 最大线程数,当任务进来时可以扩充的线程最大值,当大于了这个值就会根据丢弃处理机制来处理
//keepAliveTime: 当线程数大于corePoolSize时,多余的空闲线程的最大存活时间
//时间
//工作队列,先进先出:new SynchronousQueue()
//单个线程的工厂Util.threadFactory("OkHttp Dispatcher", false));       

  if (executorService == null) {
    executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
        new SynchronousQueue<>(), Util.threadFactory("OkHttp Dispatcher", false));
  }
  return executorService;
}

void enqueue(AsyncCall call) {
  synchronized (this) {
    readyAsyncCalls.add(call);

    // Mutate the AsyncCall so that it shares the AtomicInteger of an existing running call to
    // the same host.
    if (!call.get().forWebSocket) {
      AsyncCall existingCall = findExistingCallWithHost(call.host());
      if (existingCall != null) call.reuseCallsPerHostFrom(existingCall);
    }
  }
  promoteAndExecute();
}

void finished(AsyncCall call) {
  call.callsPerHost().decrementAndGet();
  finished(runningAsyncCalls, call);
}

/** Used by {@code Call#execute} to signal completion. */
void finished(RealCall call) {
  finished(runningSyncCalls, call);
}

//它将正在运行的任务Call从队列runningAsyncCalls中移除后,获判断是否进入了Idle状态,接着执行promoteAndExecute()函数,
private  void finished(Deque calls, T call) {
  Runnable idleCallback;
  synchronized (this) {
    if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
    idleCallback = this.idleCallback;
  }

  boolean isRunning = promoteAndExecute();

  if (!isRunning && idleCallback != null) {
    idleCallback.run();
  }
}
}


//主要就是遍历等待队列,并且需要满足同一主机的请求小于maxRequestsPerHost时,就移到运行队列中并交给线程池运行。就主动的把缓存队列向前走了一步,而没有使用互斥锁等复杂编码
private boolean promoteAndExecute() {
  assert (!Thread.holdsLock(this));

  List executableCalls = new ArrayList<>();
  boolean isRunning;
  synchronized (this) {
  //遍历等待队列
    for (Iterator i = readyAsyncCalls.iterator(); i.hasNext(); ) {
      AsyncCall asyncCall = i.next();
     //最大并发数和主机请求数则退出遍历
      if (runningAsyncCalls.size() >= maxRequests) break; // Max capacity.
      if (asyncCall.callsPerHost().get() >= maxRequestsPerHost) continue; // Host max capacity.

      i.remove();
      asyncCall.callsPerHost().incrementAndGet();
      executableCalls.add(asyncCall);
      runningAsyncCalls.add(asyncCall);  //添加到执行队列
    }
    isRunning = runningCallsCount() > 0; //是否在执行
  }

  for (int i = 0, size = executableCalls.size(); i < size; i  ) {
    AsyncCall asyncCall = executableCalls.get(i);
    asyncCall.executeOn(executorService());
  }
  return isRunning;
}

##核心重点拦截器方法getResponseWithInterceptorChain():

Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
//拦截器的集合
List interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
//失败重试以及重定向
interceptors.add(new RetryAndFollowUpInterceptor(client));
//负责把用户构造的请求转换为发送到服务器的请求、把服务器返回的响应转换为用户友好的响应
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, transmitter, null, 0,
    originalRequest, this, client.connectTimeoutMillis(),
    client.readTimeoutMillis(), client.writeTimeoutMillis());

boolean calledNoMoreExchanges = false;
try {
 //转换成response
  Response response = chain.proceed(originalRequest);
  if (transmitter.isCanceled()) {
    closeQuietly(response);
    throw new IOException("Canceled");
  }
  return response;
} catch (IOException e) {
  calledNoMoreExchanges = true;
  throw transmitter.noMoreExchanges(e);
} finally {
  if (!calledNoMoreExchanges) {
    transmitter.noMoreExchanges(null);
  }
}
}

我们可以看到,当我们把拦截器集合添加好后,会实例化一个RealInterceptorChain,然后调用其proceed(Request)中从拦截器链中拿到结果。

Interceptor.Chain chain = new RealInterceptorChain(interceptors, transmitter, null, 0,
  originalRequest, this, client.connectTimeoutMillis(),
  client.readTimeoutMillis(), client.writeTimeoutMillis());
...
Response response = chain.proceed(originalRequest);

RealInterceptorChain类实现了Chain的接口:

public final class RealInterceptorChain implements Interceptor.Chain {

public RealInterceptorChain(List interceptors, Transmitter transmitter,
    @Nullable Exchange exchange, int index, Request request, Call call,
    int connectTimeout, int readTimeout, int writeTimeout) {
  this.interceptors = interceptors;
  this.transmitter = transmitter;
  this.exchange = exchange;
  this.index = index;
  this.request = request;
  this.call = call;
  this.connectTimeout = connectTimeout;
  this.readTimeout = readTimeout;
  this.writeTimeout = writeTimeout;
}
....
@Override public Response proceed(Request request) throws IOException {
  return proceed(request, transmitter, exchange);
}

public Response proceed(Request request, Transmitter transmitter, @Nullable Exchange exchange)
    throws IOException {
  if (index >= interceptors.size()) throw new AssertionError();

  calls  ;

  ......

  RealInterceptorChain next = new RealInterceptorChain(interceptors, transmitter, exchange,
      index   1, request, call, connectTimeout, readTimeout, writeTimeout);
 
  Interceptor interceptor = interceptors.get(index);
  Response response = interceptor.intercept(next);
  ....
  return response;
}
}

主要看proceed方法,proceed方法中判断index(此时为0)是否大于或者等于client.interceptors(List )的大小。由于httpStream为null,所以首先创建next拦截器链,主需要把索引置为index 1即可;然后获取第一个拦截器,调用其intercept方法。
intercept是一个接口方法,具体由各个拦截器子类实现:

public interface Interceptor {

Response intercept(Chain chain) throws IOException;

interface Chain {
  Request request();

  Response proceed(Request request) throws IOException;

  @Nullable Connection connection();

  Call call();

  int connectTimeoutMillis();

  Chain withConnectTimeout(int timeout, TimeUnit unit);

  int readTimeoutMillis();

  Chain withReadTimeout(int timeout, TimeUnit unit);

  int writeTimeoutMillis();

  Chain withWriteTimeout(int timeout, TimeUnit unit);
}
}

BridgeInterceptor
BridgeInterceptor从用户的请求构建网络请求,最后从网络响应中提取出给用户响应。

public final class BridgeInterceptor implements Interceptor {

//chain.proceed通过调用这个方法拿到response
//首先获取原请求,然后在请求中添加头,比如Host、Connection、Accept-Encoding参数等,
//然后根据看是否需要填充Cookie,
//在对原始请求做出处理后,使用chain的procced方法得到响应,
//接下来对响应做处理得到用户响应,最后返回响应。

@Override public Response intercept(Chain chain) throws IOException {
  Request userRequest = chain.request();
  Request.Builder requestBuilder = userRequest.newBuilder();

//添加头
  RequestBody body = userRequest.body();
  if (body != null) {
    //如果存在请求主体部分,那么需要添加Content-Type、Content-Length首部
    MediaType contentType = body.contentType();
    if (contentType != null) {
      requestBuilder.header("Content-Type", contentType.toString());
    }
    long contentLength = body.contentLength();
    if (contentLength != -1) {
      requestBuilder.header("Content-Length", Long.toString(contentLength));
      requestBuilder.removeHeader("Transfer-Encoding");
    } else {
      requestBuilder.header("Transfer-Encoding", "chunked");
      requestBuilder.removeHeader("Content-Length");
    }
  }



  if (userRequest.header("Host") == null) {
    requestBuilder.header("Host", hostHeader(userRequest.url(), false));
  }
  if (userRequest.header("Connection") == null) {
    requestBuilder.header("Connection", "Keep-Alive");
  }

  boolean transparentGzip = false;
  if (userRequest.header("Accept-Encoding") == null && userRequest.header("Range") == null) {
    transparentGzip = true;
    requestBuilder.header("Accept-Encoding", "gzip");
  }


//看是否需要填充Cookie
  List cookies = cookieJar.loadForRequest(userRequest.url());
  if (!cookies.isEmpty()) {
    requestBuilder.header("Cookie", cookieHeader(cookies));
  }

  if (userRequest.header("User-Agent") == null) {
    requestBuilder.header("User-Agent", Version.userAgent());
  }

//在对原始请求做出处理后,使用chain的procced方法得到响应
  Response networkResponse = chain.proceed(requestBuilder.build());

  HttpHeaders.receiveHeaders(cookieJar, userRequest.url(), networkResponse.headers());

//接下来对响应做处理得到用户响应,最后返回响应
  Response.Builder responseBuilder = networkResponse.newBuilder()
      .request(userRequest);

  if (transparentGzip
      && "gzip".equalsIgnoreCase(networkResponse.header("Content-Encoding"))
      && HttpHeaders.hasBody(networkResponse)) {
    GzipSource responseBody = new GzipSource(networkResponse.body().source());
    Headers strippedHeaders = networkResponse.headers().newBuilder()
        .removeAll("Content-Encoding")
        .removeAll("Content-Length")
        .build();
    responseBuilder.headers(strippedHeaders);
    String contentType = networkResponse.header("Content-Type");
    responseBuilder.body(new RealResponseBody(contentType, -1L, Okio.buffer(responseBody)));
  }

  return responseBuilder.build();
}

private String cookieHeader(List cookies) {
  StringBuilder cookieHeader = new StringBuilder();
  for (int i = 0, size = cookies.size(); i < size; i  ) {
    if (i > 0) {
      cookieHeader.append("; ");
    }
    Cookie cookie = cookies.get(i);
    cookieHeader.append(cookie.name()).append('=').append(cookie.value());
  }
  return cookieHeader.toString();
}
}

ConnectInterceptor
ConnectInterceptor负责和服务器建立连接

public final class ConnectInterceptor implements Interceptor {
  ....
//主要是创建Exchange 对象
@Override public Response intercept(Chain chain) throws IOException {
  RealInterceptorChain realChain = (RealInterceptorChain) chain;
  Request request = realChain.request();
  Transmitter transmitter = realChain.transmitter();

  // We need the network to satisfy this request. Possibly for validating a conditional GET.
  boolean doExtensiveHealthChecks = !request.method().equals("GET");
  Exchange exchange = transmitter.newExchange(chain, doExtensiveHealthChecks);

  return realChain.proceed(request, transmitter, exchange);
}
}

CallServerInterceptor
CallServerInterceptor是拦截器链中最后一个拦截器,负责将网络请求提交给服务器。

@Override public Response intercept(Chain chain) throws IOException {
  RealInterceptorChain realChain = (RealInterceptorChain) chain;
  Exchange exchange = realChain.exchange();
  Request request = realChain.request();

  long sentRequestMillis = System.currentTimeMillis();
  //调用writeRequestHeaders方法写入请求的头部
  exchange.writeRequestHeaders(request);

  boolean responseHeadersStarted = false;
  Response.Builder responseBuilder = null;
  if (HttpMethod.permitsRequestBody(request.method()) && request.body() != null) {
  //然后判断是否需要写入请求的body部分
    if ("100-continue".equalsIgnoreCase(request.header("Expect"))) {
      exchange.flushRequest();
      responseHeadersStarted = true;
      exchange.responseHeadersStart();
      responseBuilder = exchange.readResponseHeaders(true);
    }

    if (responseBuilder == null) {
      if (request.body().isDuplex()) {
        // Prepare a duplex body so that the application can send a request body later.
        exchange.flushRequest();
        BufferedSink bufferedRequestBody = Okio.buffer(
            exchange.createRequestBody(request, true));
        request.body().writeTo(bufferedRequestBody);
      } else {
        // Write the request body if the "Expect: 100-continue" expectation was met.
        BufferedSink bufferedRequestBody = Okio.buffer(
            exchange.createRequestBody(request, false));
        request.body().writeTo(bufferedRequestBody);
        bufferedRequestBody.close();
      }
    } else {
      exchange.noRequestBody();
      if (!exchange.connection().isMultiplexed()) {
        // If the "Expect: 100-continue" expectation wasn't met, prevent the HTTP/1 connection
        // from being reused. Otherwise we're still obligated to transmit the request body to
        // leave the connection in a consistent state.
        exchange.noNewExchangesOnConnection();
      }
    }
  } else {
    exchange.noRequestBody();
  }

//后调用finishRequest()方法将所有数据刷新给底层的Socket
  if (request.body() == null || !request.body().isDuplex()) {
    exchange.finishRequest();
  }

  if (!responseHeadersStarted) {
    exchange.responseHeadersStart();
  }
//尝试调用readResponseHeaders()方法读取响应的头部,然后再调用openResponseBody()方法得到响应的body部分,最后返回响应
  if (responseBuilder == null) {
    responseBuilder = exchange.readResponseHeaders(false);
  }

  Response response = responseBuilder
      .request(request)
      .handshake(exchange.connection().handshake())
      .sentRequestAtMillis(sentRequestMillis)
      .receivedResponseAtMillis(System.currentTimeMillis())
      .build();

  int code = response.code();
  if (code == 100) {
    // server sent a 100-continue even though we did not request one.
    // try again to read the actual response
    response = exchange.readResponseHeaders(false)
        .request(request)
        .handshake(exchange.connection().handshake())
        .sentRequestAtMillis(sentRequestMillis)
        .receivedResponseAtMillis(System.currentTimeMillis())
        .build();

    code = response.code();
  }

  exchange.responseHeadersEnd(response);

  if (forWebSocket && code == 101) {
    // Connection is upgrading, but we need to ensure interceptors see a non-null response body.
    response = response.newBuilder()
        .body(Util.EMPTY_RESPONSE)
        .build();
  } else {
    response = response.newBuilder()
        .body(exchange.openResponseBody(response))
        .build();
  }

  if ("close".equalsIgnoreCase(response.request().header("Connection"))
      || "close".equalsIgnoreCase(response.header("Connection"))) {
    exchange.noNewExchangesOnConnection();
  }

  if ((code == 204 || code == 205) && response.body().contentLength() > 0) {
    throw new ProtocolException(
        "HTTP "   code   " had non-zero Content-Length: "   response.body().contentLength());
  }

  return response;
}

okhttp源码_第1张图片

**总结:**OkHttp的底层是通过Java的Socket发送HTTP请求与接受响应的(这也好理解,HTTP就是基于TCP协议的),但是OkHttp实现了连接池的概念,即对于同一主机的多个请求,其实可以公用一个Socket连接,而不是每次发送完HTTP请求就关闭底层的Socket,这样就实现了连接池的概念。而OkHttp对Socket的读写操作使用的OkIo库进行了一层封装。

okhttp源码_第2张图片

你可能感兴趣的:(笔记)