2. 网络异常类型:连接超时、DNS解析失败、TCP连接重置、SSL/TLS握手失败、HTTP状态码异常

做OTA升级,说白了就是在跟网络打交道。网络这东西,你我都清楚,它从来不会老老实实按剧本走。我在项目里见过太多因为网络异常导致升级失败的情况,有些甚至让设备变砖。所以今天咱们就把这些常见的网络异常类型掰开揉碎了讲清楚。

2.1 连接超时

连接超时,这是最基础也最常见的问题。你想想看,设备要跟服务器建立连接,结果服务器没响应,或者网络太慢,超过了你设定的等待时间,那就超时了。

我个人习惯把连接超时分两种来看:

  • 建立连接超时:TCP三次握手没完成。比如服务器挂了,或者防火墙把端口给封了。
  • 数据传输超时:连接是建起来了,但数据传着传着卡住了。比如网络抖动,或者服务器处理不过来。

关键点:超时时间设多少合适?

我在项目中遇到过,有些同事把超时设成5秒,结果用户网络差一点就频繁失败。后来我改成这样:

  • 连接超时:10秒(公网环境)
  • 读取超时:30秒(大文件下载)
  • 写入超时:15秒(上报状态)

我的小技巧:不要用固定的超时值。可以根据网络质量动态调整。比如第一次超时了,下次重试时把超时时间适当延长。但别无限延长,设个上限,比如60秒。

2.2 DNS解析失败

DNS解析失败,说白了就是设备找不到服务器在哪。你给了一个域名,但DNS服务器没法把它转成IP地址。

为什么会这样?常见原因有:

  • DNS服务器本身挂了或者响应慢
  • 设备网络配置不对,比如DNS地址写错了
  • 域名过期或者被劫持了

我记得有一次,客户反馈设备升级总失败。查了半天,发现是他们的路由器DNS缓存出了问题。设备请求解析域名,路由器返回了一个过期的IP地址,结果连到一台不存在的服务器上。

避坑指南:我曾经在项目里吃过亏,设备只配了一个DNS服务器,结果那个服务器挂了,所有设备都解析不了域名。后来我强制要求:

  • 至少配置两个DNS服务器,主备切换
  • 本地缓存DNS解析结果,避免频繁请求
  • 如果DNS解析失败,尝试用IP地址直连(前提是你知道服务器的IP)

2.3 TCP连接重置

TCP连接重置,就是RST包。你正跟服务器聊得好好的,突然对方发了个RST,连接就断了。

这种情况我见得多了,常见场景有:

  • 服务器端程序崩溃,操作系统发送RST
  • 防火墙或者负载均衡器主动断连
  • 设备端发送了非法数据包
  • 连接空闲太久,被服务器主动关闭

你想想看,设备正在下载升级包,突然收到RST,那下载就中断了。如果没处理好,设备可能处于一个半升级状态,那就麻烦了。

处理建议

  • 捕获RST异常后,不要立即重试,等几秒再试
  • 检查是不是自己发送了非法数据,比如格式不对
  • 如果是服务器主动断连,考虑是不是需要重新认证

2.4 SSL/TLS握手失败

现在OTA升级基本都用HTTPS了,所以SSL/TLS握手失败也是个高频问题。握手失败,意味着加密通道建不起来,数据没法安全传输。

握手失败的原因很多,我挑几个常见的:

原因 说明 我的处理方式
证书过期 服务器证书不在有效期内 检查设备系统时间是否正确,很多设备时间不准
证书链不完整 设备没有安装中间证书 把完整的证书链打包到固件里
协议版本不匹配 设备只支持TLS 1.2,服务器要求TLS 1.3 尽量支持多个TLS版本,向下兼容
密码套件不支持 设备和服务器的加密算法对不上 使用通用的密码套件,比如ECDHE-RSA-AES128-GCM-SHA256

嗯,这里要注意。设备的时间问题我吃过亏。有些设备没有RTC电池,断电后时间就回到1970年了。这时候去验证证书,肯定失败。所以我建议在握手前先检查设备时间,如果不对,先通过NTP同步时间。

我的经验:在握手失败时,最好能记录下具体的错误码。比如OpenSSL的ERR_get_error()返回的值,这样排查问题会快很多。别只打印个"握手失败",那等于没信息。

2.5 HTTP状态码异常

连接建好了,握手也成功了,HTTP请求发出去了。结果服务器返回了个状态码,告诉你出问题了。

常见的HTTP状态码异常:

  • 4xx:客户端错误。比如401未授权、403禁止访问、404找不到资源、429请求过多
  • 5xx:服务器错误。比如500内部错误、502网关错误、503服务不可用、504网关超时

我记得有一次,设备升级时总是返回503。查了半天,原来是服务器在做维护,负载均衡器把请求都拒绝了。但设备没有处理503的逻辑,一直在那傻傻地重试,浪费带宽和电量。

处理策略

  • 4xx错误:一般是设备端的问题,检查请求参数、认证信息、URL是否正确
  • 5xx错误:服务器的问题,可以重试,但要有退避策略
  • 429错误:请求太频繁了,需要降低请求频率

避坑指南:我曾经遇到过一个情况,服务器返回了301重定向,但设备没有处理重定向逻辑,结果一直请求旧地址,永远拿不到升级包。所以,一定要处理HTTP的重定向,至少支持跟随一次。

好了,这五种网络异常类型,基本上覆盖了OTA升级过程中90%的网络问题。每种异常的处理方式都不一样,但核心思路是一样的:识别异常类型 -> 记录错误信息 -> 执行对应的重试策略。下一节咱们就专门讲重试机制怎么设计。