Received close_notify during handshake

本文介绍了一种常见的Android编译错误及其解决方案。错误源于jcenter无法下载所需资源,通过替换为阿里云的Maven仓库,可以有效解决此问题。文章提供了具体的Gradle配置示例,帮助开发者快速定位并修复错误。

问题存在原因:这是Android编译错误,jcenter里面的东西下载不了引起的。

问题解决:在项目的build.gradle文件中将jcenter()换成阿里的源,具体示例代码如下。修改之后再重新Sync Project即可。

buildscript {
    ext.kotlin_version = '1.3.50'
    repositories {
        google()
        // jcenter()
        maven{ url'http://maven.aliyun.com/nexus/content/groups/public/' }
        maven{ url'http://maven.aliyun.com/nexus/content/repositories/jcenter'}
        
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.3'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        // jcenter()
        maven{ url'http://maven.aliyun.com/nexus/content/groups/public/' }
        maven{ url'http://maven.aliyun.com/nexus/content/repositories/jcenter'}
        
    }
}
你问的是: ```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 要求) | | 如何避免误判为异常? | ✅ 在代码中单独判断并优雅处理 | --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值