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 …...

第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...

Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用
中达瑞和自2005年成立以来,一直在光谱成像领域深度钻研和发展,始终致力于研发高性能、高可靠性的光谱成像相机,为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...

sshd代码修改banner
sshd服务连接之后会收到字符串: SSH-2.0-OpenSSH_9.5 容易被hacker识别此服务为sshd服务。 是否可以通过修改此banner达到让人无法识别此服务的目的呢? 不能。因为这是写的SSH的协议中的。 也就是协议规定了banner必须这么写。 SSH- 开头,…...
文件上传漏洞防御全攻略
要全面防范文件上传漏洞,需构建多层防御体系,结合技术验证、存储隔离与权限控制: 🔒 一、基础防护层 前端校验(仅辅助) 通过JavaScript限制文件后缀名(白名单)和大小,提…...
FOPLP vs CoWoS
以下是 FOPLP(Fan-out panel-level packaging 扇出型面板级封装)与 CoWoS(Chip on Wafer on Substrate)两种先进封装技术的详细对比分析,涵盖技术原理、性能、成本、应用场景及市场趋势等维度: 一、技术原…...