Android平台TCP TLS 1.2连接运行数小时后突然失效的原因排查
以下是针对该问题的可能原因及排查方向:
可能的原因
TLS会话复用逻辑漏洞
你重连时依赖有效会话跳过证书验证,Java 8的TLS会话复用存在会话超时或意外失效的情况,而IIS的TLS会话缓存默认有时间限制(通常为10分钟左右)。当会话过期后,若你的重连逻辑未重新触发完整的证书验证流程,会导致握手失败,但如果错误处理缺失,客户端不会发起重试,也不会生成日志。而ksoap2的HTTPS连接每次都会执行完整的证书验证,不受会话复用问题影响。心跳包未适配TLS层
原TCP的心跳是直接通过Socket发送的明文包,但TLS连接中所有数据必须经过SslSocket的加密/解密层处理。如果心跳包的发送逻辑直接操作底层Socket而非SslSocket的流,服务器无法识别为有效心跳,会触发IIS的连接闲置超时(默认约20分钟)并主动断开。而客户端的无消息检测逻辑可能仅基于纯TCP连接状态,未检测到TLS层的断开,因此没有启动重连。SslSocket资源泄漏
原TCP模块经过多年优化,资源释放逻辑完善,但替换为SslSocket后,可能存在输入流/输出流未正确关闭、会话缓存未清理的情况。长时间运行后资源堆积,导致新连接无法建立。而ksoap2的HTTPS连接每次都会创建新连接并正确释放资源,因此不受影响。IIS的TLS连接限制触发
Windows Server 2012的IIS对TLS连接有最大并发数、空闲超时等限制。如果你的TLS连接长时间保持且心跳未被识别,服务器会强制断开连接,但客户端的重连逻辑在TLS场景下未正确处理断开事件(比如SslSocket.read()返回-1时未触发重连)。而ksoap2的HTTPS连接多为短连接,或其重连逻辑更适配HTTPS场景。PFS加密套件的长时间运行异常
你使用的完美前向安全(PFS)加密套件可能在长时间会话中出现密钥交换缓存耗尽的问题,导致握手失败。而ksoap2的HTTPS连接可能使用了不同的加密套件优先级,或每次握手都会重新协商密钥,避免了该问题。
排查建议
- 恢复TLS连接,开启Logcat的
SslSocket相关详细日志(包括握手、读写、错误信息),捕捉失效时的具体异常。 - 检查重连逻辑:当会话失效时,确保会重新触发完整的证书验证流程,而非直接复用失效会话。
- 用抓包工具验证心跳包是否通过
SslSocket正确加密发送,且服务器有响应。 - 启用IIS的失败请求跟踪,或查看Windows事件日志中的TLS相关记录,排查服务器端是否有连接断开的触发原因。
- 对比TCP与TLS的重连触发条件,确认TLS连接断开时,客户端的无消息检测逻辑能正确识别并启动重连。
内容的提问来源于stack exchange,提问作者FrankKrumnow

