问题
我尝试使用libssh libssh-C++-wrapper进行本地端口转发。我的目的是通过SSH将服务器上的端口localhost:3306
转发到我的机器上的localhost:3307
,以通过MySQL连接到localhost:3307
。
void ssh_session::forward(){
ssh::Channel channel(this->session);
//remotehost, remoteport, localhost, localport
channel.openForward("localhost",3306,"localhost",3307);
std::cout<< "Channel is " << (channel.isOpen()?"open!":"closed!") << std::endl;
}
session
的构造函数中的ssh::Channel
属于ssh::Session
类型。
上面的代码打印Channel is open!
。如果我尝试使用MySQL Connector/C++
localhost:3307
ERROR 2003(HY000):无法在&#39; 127.0.0.1&#39;上连接到MySQL服务器(61)
观察
$ ssh -L 3307:localhost:3306 me@myserver.com
,一切正常,我可以连接。ssh::Session session
或ssh::Channel channel
执行远程shell命令,那么一切正常,会话就可以了!libsshpp.hpp
的完全废话)显示ssh::Channel::openForward()
是一个C函数ssh_channel_open_forward()
ssh_channel_open_forward()
个documentation个州
警告
此功能不绑定本地端口,也不会自动将套接字的内容转发到通道。您仍然必须使用channel_read和channel_write。
我认为这可能会导致问题。通过读写ssh:Channel
我没有问题,但这不是MySQL Connector / C ++的工作方式。
问题
如何实现common shell命令
产生的相同行为$ ssh -L 3307:localhost:3306 me@myserver.com
使用libssh?
答案 0 :(得分:3)
警告
此功能不绑定本地端口,也不会自动将套接字的内容转发到该通道。您 仍然必须使用channel_read和channel_write。
这告诉您需要编写自己的本地套接字代码。不幸的是,它并没有为你做到这一点。
最简单的实现是bind
本地套接字,并使用ssh_select
监听事件(例如,与accept
的新连接,套接字或通道事件)。您可以将套接字fd
和ssh_channel
保存在向量中,以便于管理。
当您收到任何事件时,只需以非阻塞方式循环所有操作,即
accept
一个新连接,并将fd和一个新的ssh_channel(在您的问题中创建)附加到您的向量。read
所有套接字fd
,并使用ssh_channel_write
将任何内容转发到相应的ssh频道(确保将SOKC_VOMEO设置为0)ssh_channel_read_nonblocking
阅读所有频道,然后使用fd
转发至套接字write
。您还需要在任何地方处理错误,并关闭相应的fd和ssh_channel。
总的来说,StackOverflow的答案可能会有太多代码,但如果我有时间的话,我可以回来加入。
使用ssh -L ...
&amp; amp;运行fork
作为子流程的所有方法的诱人替代品exec
,避免使用所有样板插槽代码,并从高效,无错误的实现中受益。