SslConnection::SslConnection()详解
一、🔍 SslConnection::SslConnection() 详解
这个构造函数的主要作用是:
- 创建 SSL 对象
- 创建 BIO(I/O 缓冲区)
- 初始化 SSL 服务器模式
- 绑定回调函数(
onRead()处理接收数据)
📌 1. 初始化 SSL 相关对象
SslConnection::SslConnection(const TcpConnectionPtr& conn, SslContext* ctx): ssl_(nullptr) // SSL对象(加密/解密), ctx_(ctx) // SSL 上下文, conn_(conn) // Muduo 连接对象(底层网络传输), state_(SSLState::HANDSHAKE) // 初始状态:TLS 握手, readBio_(nullptr) // 读 BIO(接收加密数据), writeBio_(nullptr) // 写 BIO(存储加密数据), messageCallback_(nullptr) // 业务逻辑的回调(不一定用得上)
💡 这里主要是初始化了一些成员变量,确保构造对象时数据是干净的。
📌 2. 创建 SSL 上下文
ssl_ = SSL_new(ctx_->getNativeHandle());
if (!ssl_) {LOG_ERROR << "Failed to create SSL object: " << ERR_error_string(ERR_get_error(), nullptr);return;
}
📍 作用
- 通过
SSL_new(ctx_->getNativeHandle())创建 SSL 对象,用于加解密。 - 如果失败,打印日志并返回。
🔹 ctx_->getNativeHandle() 是什么?
- 这里的
ctx_是SslContext*,表示 SSL 的全局上下文。 ctx_->getNativeHandle()返回的是 OpenSSL 的SSL_CTX*,它管理 证书、加密方式、TLS 版本等。SSL_new()基于SSL_CTX*创建一个 新的 SSL 会话对象,用于该 TCP 连接的数据加解密。
📌 3. 创建 BIO(I/O 缓冲区)
readBio_ = BIO_new(BIO_s_mem());
writeBio_ = BIO_new(BIO_s_mem());if (!readBio_ || !writeBio_) {LOG_ERROR << "Failed to create BIO objects";SSL_free(ssl_);ssl_ = nullptr;return;
}
📍 作用
readBio_ = BIO_new(BIO_s_mem()):创建 读 BIO,用于存放接收的加密数据(网络数据)。writeBio_ = BIO_new(BIO_s_mem()):创建 写 BIO,用于存放加密后的待发送数据。- 这里使用
BIO_s_mem(),表示创建的是 内存 BIO(不会自动关联 socket,手动读写)。 - 如果创建 BIO 失败,则释放 SSL 资源,防止内存泄露。
📌 4. 绑定 SSL 和 BIO
SSL_set_bio(ssl_, readBio_, writeBio_);
📍 作用
- 让 OpenSSL 通过 BIO 读写数据,而不是直接操作 socket。
readBio_存放接收到的加密数据(模拟 OpenSSL 的SSL_read())。writeBio_存放加密后的待发送数据(模拟SSL_write())。SSL_set_bio()绑定 BIO 后,SSL_read()会自动从readBio_读取数据,SSL_write()会把加密数据存入writeBio_。
💡 这样就实现了 OpenSSL 和 Muduo 的解耦:
- Muduo 只管传输数据(读写
readBio_和writeBio_)。 - SSL 只管加密/解密(不直接接触网络)。
📌 5. 设置服务器模式
SSL_set_accept_state(ssl_); // 设置为服务器模式
📍 作用
- 服务器模式:在 TLS 握手时,服务器等待客户端发起
Client Hello。 - 服务器通过
SSL_accept()进行 TLS 握手,成功后才能进行加密通信。
📌 6. 设置 SSL 选项
SSL_set_mode(ssl_, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE);
📍 作用
🔹 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER
- 允许
SSL_write()使用动态内存,不要求数据缓冲区保持固定位置(适用于异步网络)。
🔹 SSL_MODE_ENABLE_PARTIAL_WRITE
- 允许
SSL_write()部分写入,在数据较长时,不会阻塞,而是先写入部分数据,后续继续发送。
📌 7. 绑定数据接收回调
conn_->setMessageCallback(std::bind(&SslConnection::onRead, this, std::placeholders::_1,std::placeholders::_2, std::placeholders::_3));
📍 作用
conn_是 Muduo 的 TCP 连接,它接收加密数据后,会调用onRead()处理。onRead()主要作用:- 先把 加密数据 写入
readBio_。 - 调用
SSL_read()解密数据。 - 解密后的数据交给业务逻辑处理。
- 先把 加密数据 写入
🎯 8. 总结
🚀 整个 SslConnection 的构造逻辑可以总结如下:
- 创建 SSL 对象(用于加密/解密)。
- 创建 BIO(
readBio_存接收数据,writeBio_存待发送数据)。 - 绑定 BIO(让
SSL_read()/SSL_write()读写 BIO)。 - 设置 SSL 服务器模式(
SSL_set_accept_state())。 - 设置 SSL 选项(允许
SSL_write()使用动态内存、支持部分写入)。 - 绑定
onRead()回调,处理 Muduo 网络层的数据。
💡 9. 你的代码和 Muduo/SSL 之间的关系
- Muduo 负责底层的
TCP连接和数据收发。 - SSL 负责 TLS/SSL 加解密,但不直接读写 socket,而是通过
BIO缓冲区进行数据交互。 - Muduo 只管传输,SSL 只管加解密,BIO 作为中间桥梁。
🚀 这套架构解耦了网络层和加密层,这样可以:
- 更灵活:BIO 让 SSL 适配不同的 I/O(可以换成文件、内存等)。
- 更高效:Muduo 依旧是 非阻塞 IO,BIO 负责数据缓存,不阻塞线程。
- 更安全:SSL 加密的数据 Muduo 无法直接解读,避免安全漏洞。
🛠 10. 你可以改进的地方
✅ 异常处理更全面
- 目前如果
SSL_new()失败,只是打印日志并return,可以抛出异常或者返回错误码,更容易排查问题。
✅ 考虑 BIO_set_mem_eof_return()
BIO_s_mem()可能会在BIO_read()读取完数据后返回 0,导致SSL_read()误以为连接断开。可以用:
这样BIO_set_mem_eof_return(readBio_, -1); BIO_set_mem_eof_return(writeBio_, -1);SSL_read()还能继续读取新数据。
这部分代码设计得 很合理,核心逻辑非常清晰,已经符合 高性能、可扩展、解耦的要求!🚀
二、为什么使用BIO_s_mem()
OpenSSL 里 BIO(Basic I/O) 有多种类型,而 BIO_s_mem() 只是其中之一。
你可以理解 BIO 就是 OpenSSL 里数据的输入/输出缓冲区,不同类型的 BIO 代表不同的 I/O 方式。
📌 1. OpenSSL 里的 BIO 类型
OpenSSL 提供了 三种主要 BIO,分别是:
| BIO 类型 | 描述 | 适用于 |
|---|---|---|
BIO_s_socket() | 直接操作 socket 读写 | 阻塞式网络编程 |
BIO_s_mem() | 纯内存缓冲区,需要手动传输数据 | 非阻塞网络、框架 |
BIO_s_ssl() | 直接包裹 SSL*,自动处理 | 内部封装更简单 |
🚀 你这里用了 BIO_s_mem(),它的特点是:
✅ 不会自动关联 socket(灵活,可适配任何网络框架)
✅ 手动读写数据(Muduo 负责收发,BIO 只是缓存)
✅ 适用于事件驱动框架(如 Muduo)
📌 2. BIO_s_mem() 为什么适合 Muduo?
Muduo 是 非阻塞 + 事件驱动 的框架,而 OpenSSL 默认的 SSL_read() / SSL_write() 设计成了 阻塞式,所以直接用 OpenSSL 的 BIO_s_socket() 会导致阻塞整个事件循环,影响服务器性能。
💡 解决方案:使用
BIO_s_mem()让 Muduo 负责数据收发,OpenSSL 只管加解密。
🌟 BIO_s_mem() 允许这样做:
- Muduo 读取 TCP 数据,然后 写入
readBio_:BIO_write(readBio_, encryptedData, len); - OpenSSL 从
readBio_里读取数据并解密:SSL_read(ssl_, decryptedBuffer, len); - OpenSSL 处理完数据,调用
SSL_write()生成加密数据,存入writeBio_:SSL_write(ssl_, plaintextData, len); - Muduo 负责从
writeBio_读取加密数据并发送给客户端:BIO_read(writeBio_, encryptedBuffer, len); sendToClient(encryptedBuffer, len);
✅ 这样,Muduo 仍然是非阻塞的,BIO 只是一个中间缓冲区,不会影响 Muduo 的事件循环。
📌 3. 其他 BIO 方式为什么不合适?
🚫 BIO_s_socket() 直接绑定 socket
如果你用了 BIO_s_socket(),那么:
SSL_read()/SSL_write()会直接阻塞,导致 Muduo 线程被卡住。- 影响服务器性能,不能高并发处理多个连接。
🚫 BIO_s_ssl() 让 OpenSSL 直接处理 I/O
- 这个 BIO 适用于简单场景,适合自己管理 socket 的程序,比如同步服务器。
- 但你用的是 Muduo 事件驱动,要自己控制数据流动,所以不适合。
📌 4. 总结
你这里使用 BIO_s_mem() 的原因:
- 适配 Muduo 非阻塞模型,不会让
SSL_read()阻塞线程。 - 灵活控制数据流动,BIO 只是缓冲区,Muduo 仍然管理 TCP 读写。
- 高性能,避免 OpenSSL 直接操作 socket 导致的效率问题。
🚀 这就是 BIO_s_mem() 在 Muduo 里的最佳应用场景!
相关文章:
SslConnection::SslConnection()详解
一、🔍 SslConnection::SslConnection() 详解 这个构造函数的主要作用是: 创建 SSL 对象创建 BIO(I/O 缓冲区)初始化 SSL 服务器模式绑定回调函数(onRead() 处理接收数据) 📌 1. 初始化 SSL 相…...
unity lua属性绑定刷新
我们现在有一个 角色属性类叫heroModel,内容如下,当heroModel中的等级发生变化的时候,我们需要刷新界面显示等级信息,通常我们是在收到等级升级成功的协议的时候,发送一个事件,UI界面接受到这个事件的时候,刷新一下等级…...
Self-Pro: A Self-Prompt and Tuning Framework for Graph Neural Networks
Self-Pro: A Self-Prompt and Tuning Framework for Graph Neural Networks #paper/GFM/GNN-BASED# #paper/⭐⭐⭐# 注意:这篇文章是每个图一个GCN模型,而不是所有图一个GCN 模型 算是最早的涉及异配图的prompt了 贡献和动机: 非对…...
企业级-数据分类分级详细方案
一、方案背景 在数字化时代,数据成为企业和组织的核心资产。随着数据量的快速增长和数据应用场景的不断拓展,如何有效地管理和保护数据,确保数据的安全性、合规性和可用性,成为了亟待解决的问题。数据分类分级作为数据管理的基础工作,能够帮助企业清晰地了解自身的数据资…...
本地部署Qwen2.5-VL-7B-Instruct模型
本地部署Qwen2.5-VL-7B-Instruct模型 本地部署Permalink **创建环境** conda create -n qwenvl python3.11 -y# 报错: Solving environment: failedPackagesNotFoundError: The following packages are not available from current channels:# 处理: c…...
【前端】简单原生实例合集html,css,js
长期补充,建议关注收藏点赞。 目录 a标签设置不一样的花样(图片但不用img)侧边固定box分栏input各种类型iframe表单拖拽 a标签设置不一样的花样(图片但不用img) a标签里面不用嵌套img,直接设置为其bg-img即可 <!DOCTYPE html…...
【Spring】配置文件的使用
在Spring框架中,application.properties(或application.yml)文件用于配置Spring应用程序的各种属性。我们可以通过多种方式来使用这些配置,包括使用Value和ConfigurationProperties注解来绑定配置到Java对象。 下面是对不同配置类…...
MOM成功实施分享(七)电力电容制造MOM工艺分析与解决方案(第一部分)
声明:文章仅用于交流学习,不用于商业项目实施,图片来源于网络,如有侵犯权利,请联系作者及时删除。 本方案旨在对电力电容(PEC和PQM型号)制造工艺深度分析,结合管理要求设计MOM相关功…...
计算机毕业设计SpringBoot+Vue.js航空机票预定系统(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
Python 爬取唐诗宋词三百首
你可以使用 requests 和 BeautifulSoup 来爬取《唐诗三百首》和《宋词三百首》的数据。以下是一个基本的 Python 爬虫示例,它从 中华诗词网 或类似的网站获取数据并保存为 JSON 文件。 import requests from bs4 import BeautifulSoup import json import time# 爬取…...
【二.提示词工程与实战应用篇】【3.Prompt调优:让AI更懂你的需求】
最近老张在朋友圈秀出用AI生成的国风水墨画,隔壁王姐用AI写了份惊艳全场的年终总结,就连楼下小卖部老板都在用AI生成营销文案。你看着自己跟AI对话时满屏的"我不太明白您的意思",是不是怀疑自己买了台假电脑?别慌,这可能是你的打开方式不对。今天咱们就聊聊这个…...
商城源码的框架
商城源码的框架通常是基于某种Web开发框架或者电子商务平台来构建的。以下是一些常见的商城源码框架: WooCommerce:基于WordPress的电子商务插件,适用于小型到中型的在线商店。 Magento:一个功能强大和灵活的开源电子商务平台&am…...
WordPress如何防Webshell、防篡改、防劫持,提升WP漏洞防护能力
WordPress是一款世界知名的CMS系统,不仅可以创建博客网站,还可以用于建设企业网站、下载网站、商城等各类网站。功能非常强大、结构科学合理,深受广大用户喜欢。 虽然WordPress非常优秀,但是为了保障网站安全,我们还是…...
Android Flow 示例
在Android开发的世界里,处理异步数据流一直是一个挑战。随着Kotlin的流行,Flow作为Kotlin协程库的一部分,为开发者提供了一种全新的方式来处理这些问题。今天,我将深入探讨Flow的设计理念,并通过具体的例子展示如何在实…...
刚安装docker并启动docker服务: systemctl restart docker报错解决
root:/home/lzw# sudo systemctl restart docker Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xeu docker.service" for details. 1、问题描述 启动doc…...
xss笔记与打靶(更新中)
这个文章好 https://blog.csdn.net/huangyongkang666/article/details/123624164?fromshareblogdetail&sharetypeblogdetail&sharerId123624164&sharereferPC&sharesource2401_88818565&sharefromfrom_link 什么是xss XSS(跨站脚本攻击&…...
游戏引擎学习第133天
仓库:https://gitee.com/mrxiao_com/2d_game_3 回顾并设定今天的主题 今天的任务是进一步优化背景资源的流式加载,尤其是在内存管理方面。昨天,我们实现了资源流式加载,让游戏在加载时可以动态地加载背景,而不是一开始就把所有资…...
【鸿蒙操作系统】- 1:实习阶段的一些总结
本文目录 1. 序2.鸿蒙与欧拉的概念微内核LiteOS鸿蒙微内核POSIX标准 3.实习干了些什么身份鉴别访问控制恶意代码防范安全审计入侵防范性能压测检查系统版本网络测试常见的linux测试命令 1. 序 之前在某国企实习的时候,有幸参与了鸿蒙系统、鸿蒙欧拉的项目ÿ…...
Qt基础入门-详解
前言 qt之路正式开启 💓 个人主页:普通young man-CSDN博客 ⏩ 文章专栏:C_普通young man的博客-CSDN博客 ⏩ 本人giee: 普通小青年 (pu-tong-young-man) - Gitee.com 若有问题 评论区见📝 🎉欢迎大家点赞ὄ…...
【前端】HTML 备忘清单(超级详细!)
文章目录 入门hello.html注释 Comment段落 ParagraphHTML 链接Image 标签文本格式标签标题Section Divisions内部框架HTML 中的 JavaScriptHTML 中的 CSS HTML5 标签页面标题导航HTML5 TagsHTML5 VideoHTML5 AudioHTML5 RubyHTML5 kdiHTML5 progressHTML5 mark HTML 表格Table …...
万象视界灵坛快速部署:GitLab CI流水线自动触发镜像构建与K8s滚动更新
万象视界灵坛快速部署:GitLab CI流水线自动触发镜像构建与K8s滚动更新 1. 项目概述 万象视界灵坛(Omni-Vision Sanctuary)是一款基于OpenAI CLIP技术的高级多模态智能感知平台。该平台通过创新的像素风格界面,将复杂的语义对齐过…...
告别图库!用LiuJuan Z-Image为文章博客自动生成配图(保姆级教程)
告别图库!用LiuJuan Z-Image为文章博客自动生成配图(保姆级教程) 1. 为什么你需要这个工具? 作为一名内容创作者,我深知找配图的痛苦。记得上周为了给一篇技术文章配图,我花了整整40分钟在图库里翻找&…...
如何突破思维导图协作瓶颈?云端协同与知识管理新方案
如何突破思维导图协作瓶颈?云端协同与知识管理新方案 【免费下载链接】kityminder 百度脑图 项目地址: https://gitcode.com/gh_mirrors/ki/kityminder 在数字化办公环境中,思维导图作为梳理思路、规划项目的重要工具,其价值已得到广泛…...
Ubuntu 20.04上为Franka Panda安装libfranka 0.8.0:我如何绕开实时内核的版本陷阱
Ubuntu 20.04下Franka Panda的libfranka 0.8.0安装实战:实时内核版本选择的深度解析 当我在实验室第一次启动Franka Panda机械臂时,完全没预料到会在看似简单的环境配置环节耗费整整三天时间。作为一款广泛应用于科研和工业场景的协作机器人,…...
Qt Network 模块中的 TCP/IP 网络编程详解
Qt 是一个功能强大的跨平台 C 框架,其 Qt Network 模块为应用程序提供了丰富的网络通信能力,极大地简化了网络编程的复杂性。在众多网络协议中,TCP/IP 协议栈是互联网通信的基础,Qt Network 提供了 QTcpSocket 和 QTcpServer 等类…...
重装系统后的环境快速恢复:包含BERT模型部署的自动化脚本
重装系统后的环境快速恢复:包含BERT模型部署的自动化脚本 重装系统,对开发者来说,就像一场“数字大扫除”。清爽是清爽了,但看着空空如也的终端和待部署的一长串服务列表,那种从头再来的疲惫感瞬间涌上心头。尤其是当…...
3分钟掌握的网盘密码解析黑科技:让提取码自动获取效率提升10倍
3分钟掌握的网盘密码解析黑科技:让提取码自动获取效率提升10倍 【免费下载链接】baidupankey 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经因为寻找百度网盘分享链接的提取码而浪费大量时间?传统方式下,用户…...
怎样避免网站因 SEO 优化而被搜索引擎惩罚
<h2>怎样避免网站因 SEO 优化而被搜索引擎惩罚</h2> <p>在当今数字化时代,搜索引擎优化(SEO)已经成为了任何网站想要获得流量和提升知名度的关键因素。SEO 优化的过程并不是一帆风顺,特别是在过度优化时&#x…...
AI读脸术备份恢复指南:手把手教你搭建高可用人脸识别服务
AI读脸术备份恢复指南:手把手教你搭建高可用人脸识别服务 1. 项目背景与需求分析 人脸识别技术已经成为现代数字服务的重要组成部分,从电商个性化推荐到智能安防系统,都依赖这项技术的稳定运行。AI读脸术镜像基于OpenCV DNN深度神经网络构建…...
共享图书借阅系统 Java 源码 + 数据库设计完整方案
以下是一个共享图书借阅系统的Java源码与数据库设计的完整方案,涵盖系统架构、核心功能实现、数据库设计以及安全防护措施等方面:一、系统架构技术栈:后端:Spring Boot 2.x MyBatis-Plus(简化数据库操作)前…...
