Received close_notify during handshake 错误解决

本文介绍了解决Android Studio中因无法访问JCenter导致的编译错误的方法。通过将build.gradle文件中的JCenter源替换为阿里云Maven源,可以有效避免因网络限制引发的依赖下载失败问题。

1、翻译过来的意思是 :握手时收到关闭通知。如图:
在这里插入图片描述

因为Android studio 在编译工程的build.gradle时 ,Jcenter里面的数据无法下载,(注:我的报这个错误可能是公司对访问的网络有权限,所以无法访问jcenter的数据)

解决:打开工程的build.gradle文件 ,把buildscript和allprojects中的Jcenter 替换成阿里云的就可以了。如图:
在这里插入图片描述

 maven{ url'http://maven.aliyun.com/nexus/content/groups/public/' }
 maven{ url'http://maven.aliyun.com/nexus/content/repositories/jcenter'}

作者:黑芝麻胡
链接:https://www.jianshu.com/p/6ad5f499e418
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你问的是: ```c if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { ssl_log(SSL_ERROR, "MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY"); break; } ``` > ❓ 这个 `MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY` 是什么错误?它真的是“错误”吗? --- ## ✅ 答案:这不是一个真正的“错误”,而是一个 **正常的连接关闭通知** ### 🔍 它的含义是: > 对端(客户端或服务器)**正常地发送了 TLS 关闭通知(close_notify)**,表示:“我要安全关闭这个连接了”。 --- ## 📘 TLS 协议中的 `close_notify` 详解 在 TLS 协议中,`close_notify` 是 **告警消息(alert message)** 的一种,属于 **正常通信流程的一部分**。 ### 类型: - 告警级别:`warning` 或 `fatal` - 此处为:`close_notify`(值为 `0`) 当一端调用 `mbedtls_ssl_close_notify(&ssl)` 时,就会发送: ```text [Alert Protocol] → close_notify ``` 接收方收到后,`mbedtls_ssl_read()` 或 `mbedtls_ssl_handshake()` 就会返回: ```c MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY ``` --- ## ✅ 所以你应该怎么处理? ### ✔️ 正确做法:把它当作 **正常断开连接** 来处理,而不是错误! ```c if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { ssl_log(SSL_INFO, "Peer sent close_notify - connection closed gracefully"); break; // 正常退出读循环 } ``` 📌 建议日志级别用 `INFO` 或 `DEBUG`,不要用 `ERROR` --- ## ⚠️ 为什么很多人误以为这是“错误”? 因为它的名字里有 `ERR_`,看起来像错误码,但实际上: | 名称 | 实际意义 | |------|----------| | `MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY` | ❌ 不是传输错误<br>✅ 是对端主动关闭连接的通知 | 👉 它只是 **通过返回负数来通知上层协议状态的一种机制**,不是网络异常或加密失败。 --- ## 🧩 其他常见 TLS 告警(Alerts) | 告警名称 | 错误码 | 含义 | 是否严重 | |--------|-------|------|---------| | `close_notify` | `0` | 对端关闭连接 | ✅ 正常 | | `unexpected_message` | `10` | 协议乱序 | ❌ 异常 | | `bad_record_mac` | `20` | 解密失败/MAC 校验错 | ❌ 严重 | | `handshake_failure` | `40` | 握手失败 | ❌ 失败 | | `decrypt_error` | `51` | 解密失败 | ❌ 可能攻击 | 这些都会导致 `mbedtls_ssl_read()` 返回不同的负值。 但只有 `close_notify` 是预期中的正常行为。 --- ## ✅ 最佳实践建议 ### 1. 区分对待 `close_notify` 和其他错误 ```c while (1) { ret = mbedtls_ssl_read(&ssl, buf, sizeof(buf)); if (ret > 0) { // 成功读取数据 handle_data(buf, ret); } else if (ret == 0) { // 连接被对端关闭(TCP FIN) ssl_log(SSL_INFO, "Connection closed by peer (EOF)"); break; } else if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { // TLS 层正常关闭通知 ssl_log(SSL_INFO, "Peer sent close_notify"); mbedtls_ssl_close_notify(&ssl); // 可选:回送 close_notify break; } else if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) { // 非阻塞等待更多数据 continue; } else { // 真正的错误:证书问题、解密失败等 ssl_log(SSL_ERROR, "SSL read failed: %d", ret); break; } } ``` ### 2. (可选)回送 `close_notify` 你可以礼貌地回应一个关闭通知: ```c mbedtls_ssl_close_notify(&ssl); // 发送 close_notify 给对端 ``` 这符合 TLS 规范的“双工关闭”流程。 --- ## ✅ 总结 | 问题 | 回答 | |------|------| | `MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY` 是错误吗? | ❌ 不是!它是正常的关闭通知 | | 应该记录为 ERROR 日志吗? | ❌ 不推荐,应使用 INFO/DEBUG | | 收到后是否需要中断连接? | ✅ 是的,但属于正常断开 | | 是否必须回复 `close_notify`? | ⚠️ 推荐但非强制(RFC 要求) | | 如何避免误判为异常? | ✅ 在代码中单独判断并优雅处理 | --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值