Android OkHttpClient设置长超时仍报SocketTimeoutException异常
问题根因
异常触发的核心原因是未配置OkHttp的callTimeout参数。
OkHttp 3.12及以上版本默认设置了10秒的全局请求总超时(callTimeout),这个超时覆盖完整请求生命周期:包括DNS解析、连接建立、请求体发送、服务端处理、响应体读取全流程,只要总耗时达到阈值,框架会主动关闭socket触发你看到的SocketTimeoutException: timeout + socket is closed异常,和你单独配置的connectTimeout、readTimeout没有冲突——你之前设置的两类超时只覆盖连接、读两个单独阶段,不会影响全局总超时的计时。
另外你代码中在拦截器内通过chain.withReadTimeout/chain.withConnectTimeout重复设置超时属于无效操作,既不会覆盖全局callTimeout,也和Builder阶段的配置重复。
修复方案
按顺序调整配置即可:
- 给OkHttpClient构造器补充callTimeout配置,根据你的长请求需求设置总时长,需要保证总时长大于
delayMiliSeconds + connectTimeout + readTimeout的总和,不需要总超时限制可以传0关闭该规则:
OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder() // 新增下面这行,示例设为0关闭全局总超时,也可传入你需要的具体毫秒值 .callTimeout(0, TimeUnit.MILLISECONDS) .readTimeout(readTimeOut, TimeUnit.MILLISECONDS) .writeTimeout(readTimeOut, TimeUnit.MILLISECONDS) .connectTimeout(connectTimeOut, TimeUnit.MILLISECONDS);
注意:callTimeout的优先级高于所有阶段单独超时,只要总耗时达标就会触发断开,是你当前场景下必须配置的参数。
- 简化拦截器中的proceed逻辑,删除冗余的chain重复超时设置,直接执行请求:
// 替换原来带withReadTimeout/withConnectTimeout的链式调用 return chain.proceed(request);
- 如果你设置的
delayMiliSeconds是测试用的模拟延迟,注意这部分等待时间会计入请求总耗时,配置callTimeout时需要把这部分时长算入阈值。
额外排查项
如果调整配置后依然出现短时间超时断开,需要排查链路中间节点的超时限制:
- 本地是否挂了抓包代理(比如Charles、Fiddler),这类工具默认的长连接超时通常在30-60秒
- 服务端网关、负载均衡(比如Nginx、SLB)是否配置了默认的请求超时,这类中间件主动断开连接的场景下,客户端修改超时配置无法解决问题,需要同步调整对应节点的超时规则。
内容的提问来源于stack exchange,提问作者Fernando
相关产品推荐
相关产品推荐

