C++如何通过SSH实现跨网络MySQL连接 含mysql_real_connect使用疑问
实现C++通过SSH连接MySQL的方案
核心逻辑说明:你用到的mysql -L本质是依赖SSH本地端口转发实现跨网络访问,MySQL官方C API的mysql_real_connect()本身不内置SSH隧道能力,需要先打通SSH隧道再调用数据库连接接口,和你给出的命令效果完全一致的实现方案如下:
方案1:手动/自动建立SSH隧道后调用mysql_real_connect
第一步:建立SSH本地端口转发
mysql -L的底层依赖提前配置的SSH端口转发规则,对应SSH命令为:
ssh -L <本地自定义端口>:127.0.0.1:<MySQL服务端端口> <SSH登录用户名>@<数据库服务器公网IP>
举个实际示例:如果服务器上MySQL运行在默认3306端口,本地3306端口已被占用,你可以选择用3307做转发端口,命令为:
ssh -L 3307:127.0.0.1:3306 root@111.222.333.444
只要保持这个SSH会话不关闭,访问本地127.0.0.1的3307端口就等价于访问服务器内部的3306端口。
第二步:配置mysql_real_connect参数
此时直接配置连接本地转发端口即可,参数示例如下:
MYSQL *conn = mysql_init(NULL); MYSQL* res = mysql_real_connect( conn, "127.0.0.1", // host固定填本地回环地址 "<MySQL用户名>", // 对应你命令里的<local database username> "<MySQL密码>", // 执行mysql -p后输入的密码 "<要连接的库名>", // 不需要指定库可以填NULL 3307, // 填你第一步自定义的本地转发端口 NULL, // unix_socket参数填NULL 0 // client_flag默认填0即可 );
程序自动建隧道的补充实现
如果不想手动执行SSH命令维持会话,可以在C++代码中集成libssh库自动完成隧道建立,步骤为:
- 引入libssh头文件,链接libssh库
- 初始化SSH会话,连接服务器SSH端口(默认22),完成身份认证(支持密码/SSH密钥两种方式)
- 调用libssh的端口转发接口,监听本地指定端口,绑定到远端MySQL的3306端口
- 后续按上面第二步的参数调用
mysql_real_connect即可
其他可行方案
- 配置MySQL公网访问+IP白名单:直接将
mysql_real_connect的host参数填服务器公网IP、port填MySQL开放的公网端口即可,优点是不需要额外配置隧道,缺点是安全性低,不推荐生产环境使用 - 走Socks5代理:MySQL 8.0及以上版本的C API支持配置Socks5代理参数,你可以在服务器上搭建Socks5代理,然后通过
mysql_options()设置MYSQL_OPT_SOCK_PROXY相关参数,直接通过代理连接远端MySQL
注意事项
- SSH隧道断开会直接导致MySQL连接中断,需要做好异常重连逻辑
- 本地转发端口不要和本地其他服务的端口冲突
- 生产环境不要在代码中硬编码SSH、MySQL的明文密码,建议用加密配置文件存储或者密钥认证
内容的提问来源于stack exchange,提问作者Philipp
相关产品推荐
相关产品推荐

