跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

OkHttp3 网络请求中的代理选择与路由策略详解

OkHttp3 代理与路由机制涉及 ProxySelector 的选择、Address 的配置封装以及 StreamAllocation 的连接管理。Android 与 JDK 平台默认实现存在差异,Address 对象在拦截器链中传递配置,RouteSelector 据此生成可用路由。连接建立时,ConnectInterceptor 根据路由类型判断是否需要 HTTP 隧道,最终完成 TCP 握手及 SSL 协商。理解这一流程对排查网络问题至关重要。

GitMaster发布于 2025/1/19更新于 2026/10/1692 浏览
OkHttp3 网络请求中的代理选择与路由策略详解

代理选择器 ProxySelector 的实现

在 OkHttp3 中,ProxySelector 对象由 OkHttpClient 维护。创建客户端时,可以通过 Builder 设置自定义的 ProxySelector;若未指定,则回退到系统默认实现。

OpenJDK 1.8 默认的 ProxySelector 为 sun.net.spi.DefaultProxySelector,它通过读取系统属性来决定代理行为。而在 Android 平台上,默认使用的是 ProxySelectorImpl,其核心逻辑是从系统属性(System Properties)中获取代理配置,并过滤掉禁止代理的主机。

public abstract class ProxySelector {
    private static ProxySelector defaultSelector = new ProxySelectorImpl();
    
    public static ProxySelector getDefault() {
        return defaultSelector;
    }
}

Android 端的 ProxySelectorImpl 会根据 URI 的 scheme(如 http、https、ftp)查找对应的系统属性(例如 http.proxyHost),如果匹配到非代理主机列表则直接返回 NO_PROXY,否则尝试建立连接。

Address 与路由信息封装

前面提到的 RouteSelector 依赖 Address 提供的代理和地址信息来收集路由数据。Address 类在 OkHttp3 中扮演着配置容器的角色,它描述了建立连接所需的所有参数,包括 HTTP 服务器地址、DNS 解析器、SocketFactory、代理、TLS 设施等。

public final class Address {
    final HttpUrl url;
    final Dns dns;
    final SocketFactory socketFactory;
    final Proxy proxy;
    final ProxySelector proxySelector;
    // ... 其他配置
}

在拦截器链的执行过程中,RetryAndFollowUpInterceptor 负责创建 Address 对象,并从 中获取当前的 。随后,这个 会被传递给 ,用于后续的路由选择和连接管理。

OkHttpClient
ProxySelector
Address
StreamAllocation

连接建立与隧道协商

StreamAllocation 是连接管理的核心,它在 findConnection() 方法中决定是使用连接池中的复用连接,还是新建连接。新建连接的过程遵循以下流程:选择一个 Route -> 创建 RealConnection 对象 -> 保存进连接池 -> 执行实际连接。

在 RealConnection.connect() 方法中,OkHttp 会判断是否需要建立隧道连接。这主要取决于代理类型和请求协议:

public boolean requiresTunnel() {
    return address.sslSocketFactory != null && proxy.type() == Proxy.Type.HTTP;
}

当使用 HTTP 代理且请求需要 SSL/TLS 加密通道(如 HTTPS 或 HTTP/2)时,必须建立隧道。此时会调用 buildTunneledConnection() 进行握手;如果是明文传输或其他代理类型,则直接调用 buildConnection() 建立 TCP 连接。

这一机制确保了在不同网络环境下,无论是直连还是经过代理,都能正确协商出可用的通信路径。

目录

  1. 代理选择器 ProxySelector 的实现
  2. Address 与路由信息封装
  3. 连接建立与隧道协商

更多推荐文章

查看全部
  • cJSON 1.7.19 源码深度分析:数据结构、解析流程与注释实践
  • 本地大语言模型部署实战:Ollama + Open WebUI
  • 构建与 GitHub 深度集成的自动化工作流实战指南
  • GLM-5 与 Qwen3.5 大模型 API 调用教程
  • Android 应用启动白屏问题解决方案
  • DeerFlow 2.0:字节开源的超级 Agent 框架深度解析
  • Spring Boot 实战:配置 MySQL、集成 Spring Security 与基础 CRUD
  • Java 高级开发面试复盘:HashMap 原理、Spring 核心与分布式 ID 实战
  • Qt Creator 配置 GitHub Copilot 插件指南
  • Flink 实时计算案例:TxPayMatchByJoin
  • 实战演练:基于 Next.js 和 Wagmi 构建支持 TokenP 钱包登录的 DApp 前端
  • 光伏产品缺陷检测 AI 深度学习算法 (CN118134841A)
  • Flutter for OpenHarmony 项目 Lint 配置与最佳实践
  • 无人机视觉语言导航概述:概念、定义与应用场景
  • 前端 CI/CD 实践:构建与自动化部署详解
  • Win10 升级后频繁弹出 Microsoft 365 Copilot 窗口如何禁用
  • 本地免费部署 Llama 3.1 大模型详细教程
  • OpenClaw Docker 部署教程:集成飞书钉钉 QQ 机器人
  • Python 生成器函数深度解析:asyncio 事件循环底层实现与异步编程实战
  • 大模型入门:从零开始理解大语言模型原理与应用

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online