概述
目标效果
下载地址
包含QSsh源码、库和测试界面
链接:https://pan.baidu.com/s/1wnAcKZmnIlZHjZhd0kKXzA
提取码:fa8u
代码
工程结构
CConnectionForSshClient.h
#ifndef CCONNECTIONFORSSHCLIENT_H
#define CCONNECTIONFORSSHCLIENT_H
/* Func:以用户密码的形式连接ssh服务器 发送命令到shell执行 需加n
* Note:定时检查连接状态的逻辑是 连接成功关闭定时器检查
* 连接断开 开启定时器检查并尝试重连 直至连接成功
* 即关闭定时器检查
* Use:绑定两个信号
* 检测状态:sigConnectStateChanged(bState,strIp,nPort);
* 接收信息:sigDataArrived(QString strMsg,QString strIp, int nPort);
* 绑定一个槽
* 发送信息:void slotSend(QString strMsg);
*/
#include <sshconnection.h>
#include <sshremoteprocess.h>
#include <sftpchannel.h>
#include <QTimer>
#include <QHostAddress>
#include <QThread>
#define RECONNET_SPAN_TIME (1000*10) //连接状态心跳
class CConnectionForSshClient : public QObject
{
Q_OBJECT
public:
explicit CConnectionForSshClient(QString strIp, int nPort = 22,QString strPwd = "17909",QString strUser = "root");
void init();
void unInit();
~CConnectionForSshClient();
private:
QThread *m_pThread = nullptr;
bool m_bConnected = false;
bool m_bIsFirstConnect = true;
bool m_bSendAble = false;
QTimer *m_pTimer;
QString m_strIp = "";
int m_nPort = -1;
QString m_strUser;
QString m_strPwd;
QString m_strIpPort;
QSsh::SshConnectionParameters m_argParameters;
QSsh::SshConnection *m_pSshSocket = nullptr;
QSharedPointer<QSsh::SshRemoteProcess> m_shell;
signals:
void sigInitForClild();
void sigConnectStateChanged(bool bState,QString strIp,int nPort);
void sigDataArrived(QString strMsg,QString strIp, int nPort);
private:
int send(QString strMessage);
QString getIpPort(){return m_strIp + ":" + QString::number(m_nPort);}
public slots:
void slotResetConnection(QString strIpPort);
void slotSend(QString strIpPort,QString strMessage);
void slotSend(QString strMsg);
void slotSendByQByteArray(QString strIpPort,QByteArray arrMsg);
void slotDisconnected();
void slotDataReceived();
private slots:
void slotInitForClild();
void slotCreateConnection();
void slotConnected();
void slotThreadFinished();
void slotSshConnectError(QSsh::SshError sshError);
void slotShellStart();
void slotShellError();
};
#endif // CCONNECTIONFORSSHCLIENT_H
CConnectionForSshClient.cpp
#include "CConnectionForSshClient.h"
#include <QDebug>
CConnectionForSshClient::CConnectionForSshClient(QString strIp, int nPort, QString strPwd, QString strUser)
{
m_strIp = strIp;
m_nPort = nPort;
m_strUser = strUser;
m_strPwd = strPwd;
m_strIpPort = m_strIp + ":" + QString::number(m_nPort);
}
void CConnectionForSshClient::init()
{
m_pThread = new QThread();
connect(m_pThread,SIGNAL(finished()),this,SLOT(slotThreadFinished()));
this->moveToThread(m_pThread);
m_pThread->start();
//之后的逻辑都得通过信号和槽接通
connect(this,SIGNAL(sigInitForClild()),this,SLOT(slotInitForClild()));
emit sigInitForClild();
}
void CConnectionForSshClient::unInit()
{
m_pThread->quit();
}
int CConnectionForSshClient::send(QString strMessage)
{
qDebug()<<"CConnectionForSshClient ssh send "<<strMessage;
int nSize = 0;
if(m_bConnected && m_bSendAble){
nSize = m_shell->write(strMessage.toLatin1().data());
}else{
qDebug()<<"CConnectionForSshClient::send() ssh未连接 或 shell未连接:"<<getIpPort();
}
return nSize;
}
CConnectionForSshClient::~CConnectionForSshClient()
{
if(nullptr != m_pSshSocket){
delete m_pSshSocket;
m_pSshSocket = nullptr;
}
}
void CConnectionForSshClient::slotResetConnection(QString strIpPort)
{
if(this->getIpPort() == strIpPort){
this->slotDisconnected();
}
}
void CConnectionForSshClient::slotSend(QString strIpPort, QString strMessage)
{
if(0 != m_strIpPort.compare(strIpPort)){
return;
}
send(strMessage);
}
void CConnectionForSshClient::slotSendByQByteArray(QString strIpPort, QByteArray arrMsg)
{
if(0 != m_strIpPort.compare(strIpPort)){
return;
}
if(m_bConnected){
m_shell->write(arrMsg);
}else{
qDebug()<<"CConnectionForSshClient::send(QString strMessage) 发送失败 未建立连接:"<<getIpPort();
}
}
void CConnectionForSshClient::slotInitForClild()
{
m_argParameters.port = m_nPort;
m_argParameters.userName = m_strUser;
m_argParameters.password = m_strPwd;
m_argParameters.host = m_strIp;
m_argParameters.timeout = 10;
m_argParameters.authenticationType =
QSsh::SshConnectionParameters::AuthenticationTypePassword; //密码方式连接
slotCreateConnection(); //连接
m_pTimer = new QTimer(this);
m_pTimer->setInterval(RECONNET_SPAN_TIME);
connect(m_pTimer,SIGNAL(timeout()),this,SLOT(slotCreateConnection()));
m_pTimer->start();//启动心跳定时器,每隔一段时间进入slotCreateConnection判断是否需要重连
}
void CConnectionForSshClient::slotCreateConnection()
{
qDebug()<<"CConnectionForSshClient::slotCreateConnection检查连接" ;
if(true == m_bConnected)
return;
if(nullptr == m_pSshSocket){
m_pSshSocket = new QSsh::SshConnection(m_argParameters);
connect(m_pSshSocket,SIGNAL(connected()),SLOT(slotConnected()));
connect(m_pSshSocket,SIGNAL(error(QSsh::SshError)),SLOT(slotSshConnectError(QSsh::SshError)));
}
m_pSshSocket->connectToHost();
qDebug()<<"CConnectionForSshClient::slotCreateConnection() 以ssh方式 尝试连接:"<<getIpPort();
}
void CConnectionForSshClient::slotConnected()
{
qDebug()<<"CConnectionForSshClient::slotConnected ssh已连接到:"<<getIpPort();
m_pTimer->stop();
m_shell = m_pSshSocket->createRemoteShell();
connect(m_shell.data(), SIGNAL(started()), SLOT(slotShellStart()));
connect(m_shell.data(), SIGNAL(readyReadStandardOutput()), SLOT(slotDataReceived()));
connect(m_shell.data(), SIGNAL(readyReadStandardError()), SLOT(slotShellError()));
m_shell.data()->start();
m_bConnected = true;
emit sigConnectStateChanged(m_bConnected,m_strIp,m_nPort);
}
void CConnectionForSshClient::slotDisconnected()
{
m_pSshSocket->disconnectFromHost();
}
void CConnectionForSshClient::slotThreadFinished()
{
m_pThread->deleteLater();
this->deleteLater();
}
void CConnectionForSshClient::slotSshConnectError(QSsh::SshError sshError)
{
m_bSendAble = false;
m_bConnected = false;
emit sigConnectStateChanged(m_bConnected,m_strIp,m_nPort);
m_pTimer->start();
switch(sshError){
case QSsh::SshNoError:
qDebug()<<"slotSshConnectError SshNoError"<<getIpPort();
break;
case QSsh::SshSocketError:
qDebug()<<"slotSshConnectError SshSocketError"<<getIpPort(); //拔掉网线是这种错误
break;
case QSsh::SshTimeoutError:
qDebug()<<"slotSshConnectError SshTimeoutError"<<getIpPort();
break;
case QSsh::SshProtocolError:
qDebug()<<"slotSshConnectError SshProtocolError"<<getIpPort();
break;
case QSsh::SshHostKeyError:
qDebug()<<"slotSshConnectError SshHostKeyError"<<getIpPort();
break;
case QSsh::SshKeyFileError:
qDebug()<<"slotSshConnectError SshKeyFileError"<<getIpPort();
break;
case QSsh::SshAuthenticationError:
qDebug()<<"slotSshConnectError SshAuthenticationError"<<getIpPort();
break;
case QSsh::SshClosedByServerError:
qDebug()<<"slotSshConnectError SshClosedByServerError"<<getIpPort();
break;
case QSsh::SshInternalError:
qDebug()<<"slotSshConnectError SshInternalError"<<getIpPort();
break;
default:
break;
}
}
void CConnectionForSshClient::slotShellStart()
{
m_bSendAble = true;
qDebug()<<"CConnectionForSshClient::slotShellStart Shell已连接:"<<getIpPort();
}
void CConnectionForSshClient::slotShellError()
{
qDebug()<<"CConnectionForSshClient::slotShellError Shell发生错误:"<<getIpPort();
}
void CConnectionForSshClient::slotSend(QString strMessage)
{
send(strMessage);
}
void CConnectionForSshClient::slotDataReceived()
{
QByteArray byteRecv = m_shell->readAllStandardOutput();
QString strRecv = QString::fromUtf8(byteRecv);
// if(strRecv.contains("password for")){
// m_shell->write(m_strPwd.toLatin1().data());
// }
if(!strRecv.isEmpty()) //过滤空行
emit sigDataArrived(strRecv, m_strIp, m_nPort);
}
Widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTextEdit>
#include <QComboBox>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
#include "CConnectionForSshClient.h"
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
private:
void createConnection();
void disConnection();
void initUI();
void setConnectState(bool bState);
private slots:
void slotSshConnect();
void slotSshSendCmd();
void slotClearEdit();
void slotConnectStateChanged(bool bState,QString strIp,int nPort);
void slotDataArrived(QString strMsg,QString strIp, int nPort);
signals:
void sigSend(QString strMsg);
void sigDisconnected();
private:
QTextEdit *m_pTextEdit;
QComboBox *m_pComBoxIp;
QComboBox *m_pComBoxUser;
QLineEdit *m_pLineEditPwd;
QPushButton *m_pBtnConnect;
QLabel *m_pLabelState;
QComboBox *m_pComBoxCmd;
QPushButton *m_pBtnSend;
QPushButton *m_pBtnClearEdit;
bool m_bConnectState;
CConnectionForSshClient *m_sshSocket;
};
#endif // WIDGET_H
Widget.cpp
#include "Widget.h"
#include <QDebug>
#include <QGridLayout>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
initUI();
}
Widget::~Widget()
{
}
void Widget::initUI()
{
int nItemHeight = 30;
m_bConnectState = false;
resize(400,250);
QLabel *pLabelIp = new QLabel(this);
pLabelIp->setText("IP地址");
pLabelIp->setMinimumHeight(nItemHeight);
QLabel *pLabelUser = new QLabel(this);
pLabelUser->setText("用户名");
pLabelUser->setMinimumHeight(nItemHeight);
QLabel *pLabelPort = new QLabel(this);
pLabelPort->setText("密 码");
pLabelPort->setMinimumHeight(nItemHeight);
m_pComBoxIp = new QComboBox(this);
m_pComBoxIp->addItem("192.168.1.122");
m_pComBoxIp->setMinimumHeight(nItemHeight);
m_pComBoxIp->setEditable(true);
m_pComBoxUser = new QComboBox(this);
m_pComBoxUser->addItem("root");
m_pComBoxUser->setEditable(true);
m_pLineEditPwd = new QLineEdit(this);
m_pLineEditPwd->setEchoMode(QLineEdit::Password);
m_pLineEditPwd->setText("12346");
m_pLabelState = new QLabel(this);
m_pLabelState->setFixedSize(10,10);
setConnectState(m_bConnectState);
m_pBtnConnect = new QPushButton(this);
m_pBtnConnect->setText("连接");
connect(m_pBtnConnect,SIGNAL(clicked()),this,SLOT(slotSshConnect()));
m_pComBoxCmd = new QComboBox(this);
m_pComBoxCmd->addItem("ls -la");
m_pComBoxCmd->addItem("cd /tmp");
m_pComBoxCmd->setEditable(true);
m_pBtnSend = new QPushButton(this);
m_pBtnSend->setText("发送");
connect(m_pBtnSend,SIGNAL(clicked()),this,SLOT(slotSshSendCmd()));
m_pTextEdit = new QTextEdit(this);
m_pBtnClearEdit = new QPushButton(this);
m_pBtnClearEdit->setText("清除");
connect(m_pBtnClearEdit,SIGNAL(clicked()),this,SLOT(slotClearEdit()));
QGridLayout *layout = new QGridLayout;
layout->addWidget(pLabelIp, 0,0,1,1); //IP地址Label 坐标第0行0列 所占空间大小 1行1列
layout->addWidget(pLabelUser, 1,0,1,1);
layout->addWidget(pLabelPort, 2,0,1,1);
layout->addWidget(m_pLabelState,3,0,1,1);//连接状态Label 坐标第3行0列 所占空间大小 1行1列
layout->addWidget(m_pComBoxIp, 0,1,1,2);
layout->addWidget(m_pComBoxUser, 1,1,1,2);
layout->addWidget(m_pLineEditPwd,2,1,1,2);
layout->addWidget(m_pBtnConnect, 3,1,1,2);
layout->addWidget(m_pComBoxCmd,4,0,1,2);
layout->addWidget(m_pBtnSend, 4,2,1,1);
layout->addWidget(m_pTextEdit, 0,3,4,5);
layout->addWidget(m_pBtnClearEdit,4,3,1,5);
this->setLayout(layout);
}
void Widget::createConnection()
{
QString strIp = m_pComBoxIp->currentText();
QString strUser = m_pComBoxUser->currentText();
QString strPwd = m_pLineEditPwd->text();
m_sshSocket = new CConnectionForSshClient(strIp,22,strPwd,strUser);
m_sshSocket->init();
connect(m_sshSocket,SIGNAL(sigConnectStateChanged(bool,QString,int)),
this,SLOT(slotConnectStateChanged(bool,QString,int)));
connect(m_sshSocket,SIGNAL(sigDataArrived(QString ,QString , int )),
this,SLOT(slotDataArrived(QString ,QString , int )));
connect(this,SIGNAL(sigSend(QString)),m_sshSocket,SLOT(slotSend(QString)));
connect(this,SIGNAL(sigDisconnected()),m_sshSocket,SLOT(slotDisconnected()));
}
void Widget::disConnection()
{
emit sigDisconnected();
}
void Widget::setConnectState(bool bState)
{
if(!bState)
m_pLabelState->setStyleSheet("QLabel{background-color:#ff0000;border-radius:5px;}");
else
m_pLabelState->setStyleSheet("QLabel{background-color:#00ff00;border-radius:5px;}");
}
void Widget::slotSshConnect()
{
if(!m_bConnectState){
m_pBtnConnect->setText("连接中...");
createConnection(); //发起连接
}else{
m_pBtnConnect->setText("连接");
m_bConnectState = false;
emit sigDisconnected();//断开连接
setConnectState(m_bConnectState);
}
}
void Widget::slotSshSendCmd()
{
if(m_bConnectState){
QString strCmd = m_pComBoxCmd->currentText();
strCmd += "n"; //添加回车
emit sigSend(strCmd);
}
}
void Widget::slotClearEdit()
{
m_pTextEdit->clear();
}
void Widget::slotConnectStateChanged(bool bState, QString strIp, int nPort)
{
Q_UNUSED(strIp)
Q_UNUSED(nPort)
m_bConnectState = bState;
setConnectState(m_bConnectState);
if(m_bConnectState)
m_pBtnConnect->setText("断开");
else
m_pBtnConnect->setText("连接");
}
void Widget::slotDataArrived(QString strMsg, QString strIp, int nPort)
{
Q_UNUSED(strIp)
Q_UNUSED(nPort)
m_pTextEdit->append(strMsg);
m_pTextEdit->moveCursor(QTextCursor::End);
}
最后
以上就是壮观云朵为你收集整理的Qt QSsh 使用 windows Qt实现ssh客户端的全部内容,希望文章能够帮你解决Qt QSsh 使用 windows Qt实现ssh客户端所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复