之前练习QT编写桌面程序,在添加ssh终端时使用的是QSsh。现在来看看它的代码。我在ubuntu下使用的是sshd,即openssh。
先摘抄下
“
QSsh是从Qt-Creator里面提取的ssh协议的连接和shell命令执行。最近项目需要自己连接ssh服务器,进行shell输出捕获和自动回应。
简单说下我的使用:
单独提取的地址:https://github.com/dushibaiyu/QSsh (更新到最新qt-creator里的。)
首先说下QSsh流程,首先连接:
新建SshConnectionParameters对象,初始化连接信息。这个类很简单,看下就懂了、、
其次就是连接:SshConnection类,新建时必须指定连接信息、、、调用connectToHost()函数去连接,连接成功发送connected()信号。
断开连接是:disconnectFromHost()函数,也会发送信号的、、
真正处理交互的是SshRemoteProcessRunner类和SshRemoteProcess类、、、sftp和ssh隧道的类项目没用到也没怎么看,可以自己研究下、、
先说SshRemoteProcessRunner类,这个类是为执行单挑或者单串命令准备的、、期间交互比较麻烦、、、
SshRemoteProcess类是很强大的类,但是他的构造函数却是私有的、、不能直接定义的、、只有通过SshConnection类的createRemoteProcess(const QByteArray &command)函数或者createRemoteShell()来得到指向他的智能指针。
通过createRemoteProcess(const QByteArray &command)函数生成的和SshRemoteProcessRunner类执行单条命令类似,执行完立刻退出的、、你可以通过信号捕获输出的结果、、、
最强大的是createRemoteShell()得到的SshRemoteProcess对象,其直接就是一个shell、、、类似putty的那样的,功能一点也不如弱的,二级命令,ssh跳板都支持的、、、通过readyReadStandardOutput()信号,得知服务端有输出,通过readAllStandardOutput()得到shell输出的内容、、、SshRemoteProcess是继承QIODevice的,当初找不到怎么向远程shell发送命令,最后居然是通过write(…)函数、、、千万注意,命令后面别忘跟着换行符(博主傻瓜,因为这个细节失误研究了两天)、、、
操作sftp的 SftpChannel类和TCP隧道的SshDirectTcpIpTunnel类和SshRemoteProcess一样的,同样不能直接定义的都需要通过SshConnection类的函数来生成,返回只能指针、、而这两个类我在项目中没用到,也就没自己看就研究其他项目中的难点了、、
在QSsh项目的github中里面有Qt-creator官方的例子,和提取作者的一个sftp的例子,我也加了个ssh shell的例子、、如果您在项目中使用了QSsh,欢迎一起探讨、、您可以留言或者给我邮件、、、
Ps:没有逻辑,写的很差、、、、大牛们轻喷、、、
”
看下QSsh是怎么使用的。
par.port = 22;
par.userName = "ghost";
par.password = "ghost";
par.timeout = 500;
par.authenticationType = QSsh::SshConnectionParameters::AuthenticationTypePassword;
this->ui->lineip->setText("192.168.134.130");
用起来很简单,首先设置连接时需要的参数,有端口、用户名和密码(ssh认证设置为密码登入方式)、超时时间、认证方式、host主机IP地址。par.host = this->ui->lineip->text();con = new QSsh::SshConnection(par);connect(con,&QSsh::SshConnection::connected,this,&MainWindow::sshcon);connect(con,&QSsh::SshConnection::dataAvailable,[this](const QString & mse){this->ui->textEdit->append(mse);});connect(con,&QSsh::SshConnection::disconnected,[this](){this->ui->textEdit->append("SSH disconnect");});con->connectToHost();------------------------------------------------------------------------------------------m_shell.data()->write(str.toStdString().c_str());
------------------------------------------------------------------------------------------void MainWindow::sshcon(){m_shell = con->createRemoteShell();connect(m_shell.data(),&QSsh::SshRemoteProcess::started,[this](){this->ui->textEdit->append("SshRemoteProcess start succsess");});connect(m_shell.data(),&QSsh::SshRemoteProcess::readyReadStandardOutput,[this](){this->ui->textEdit->append(QString(this->m_shell.data()->readAllStandardOutput()));});
connect(m_shell.data(),&QSsh::SshRemoteProcess::readyRead,[this](){this->ui->textEdit->append(QString(this->m_shell.data()->readAllStandardOutput()));});connect(m_shell.data(),&QSsh::SshRemoteProcess::readyReadStandardError,[this](){this->ui->textEdit->append(QString(this->m_shell.data()->readAll()));});connect(m_shell.data(),&QSsh::SshRemoteProcess::closed,[this](){this->ui->textEdit->append("SshRemoteProcess stop");});m_shell.data()->start();}
使用QSsh::SshConection来使用这些参数初始化一个连接对象,然后为这个连接对象设置好事件处理,再去连接。
连接成功,connected ---> sshcon,执行连接成功后的处理。请求创建一个远程SHELL,设定好shell事件的处理,然后启动shell。这里shell启动成功,提示启动成功信息。此后远端shell会传输登录的信息过来。这里设置有信息过来直接显示。
这里使用一个按键来触发发送shell命令,使用m_shell.data()->write()来发送输入的shell命令,如ls -l, ifconfig等。
启动成功后基本都是“有命令数据就write发送,有数据到来就read”这样的循环操作了。
一个SHELL就是这样的流程。后面看代码理解。