基于QSSH开源库实现SSH远程连接和SFTP文件传输

1.QSSH简介

QSsh 是一个基于 Qt 的库,提供了 SSH 和 SFTP 支持。它允许 Qt 应用程序在不依赖于 openssh 或其他类似工具的情况下,轻松集成 SSH 和 SFTP 功能。QSsh 项目的目标是为任何 Qt 应用程序提供一个简单的方法来使用这些协议。

github下载地址:GitHub - dushibaiyu/QSsh: SSH and SFTP support for Qt. This project is based on Qt Creator's libQtcSsh.so

gitcode下载地址:GitCode - 全球开发者的开源社区,开源代码托管平台

2.代码实现

mainwindow.h

复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDebug>
#include <QSharedPointer>
#include "ssh/sftpchannel.h"
#include "ssh/sshconnection.h"
#include "ssh/sshremoteprocess.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

using namespace QSsh;

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_pushButton_connect_clicked();
    void on_pushButton_send_clicked();

    void handleRemoteStdout();
    void handleConnected();
    void handleShellStarted();
    void handleRemoteStderr();

    void handleChannelInitialized();
    void handleChannelInitializationFailure(const QString &reason);

    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;

    SshConnection *m_connection;
    QSharedPointer<SshRemoteProcess> m_shell;
    SftpChannel::Ptr m_channel;
};
#endif // MAINWINDOW_H

mainwindow.cpp

复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    m_connection = nullptr;

    ui->lineEdit_command->setEnabled(false);
    ui->pushButton_send->setEnabled(false);
    ui->pushButton->setEnabled(false);

    ui->lineEdit_ip->setEnabled(true);
    ui->lineEdit_passwd->setEnabled(true);
    ui->lineEdit_user->setEnabled(true);
    ui->pushButton_connect->setEnabled(true);
}

MainWindow::~MainWindow()
{
    delete ui;
}

 //读取ssh的数据
void MainWindow::handleRemoteStdout()
{
    QString str_out = QString::fromUtf8(m_shell->readAll());
    if(!str_out.isEmpty()){
        str_out = str_out.replace("\r","");
        str_out = str_out.replace("\n","");
        ui->textBrowser->append(str_out);
        qDebug().noquote()<< "str out:" << str_out;
    }
}

 //远程连接
void MainWindow::handleConnected()
{
    //sftp连接
    m_channel = m_connection->createSftpChannel();
    connect(m_channel.data(), SIGNAL(initialized()), this, SLOT(handleChannelInitialized()));
    connect(m_channel.data(), SIGNAL(channelError(QString)), this, SLOT(handleChannelInitializationFailure(QString)));
    
     //ssh连接
    m_shell = m_connection->createRemoteShell();
    m_shell->open(QIODevice::ReadWrite);
    connect(m_shell.data(), SIGNAL(started()), this,SLOT(handleShellStarted()));
    connect(m_shell.data(), SIGNAL(readyReadStandardOutput()), this,SLOT(handleRemoteStdout()));
    connect(m_shell.data(), SIGNAL(readyReadStandardError()), this,SLOT(handleRemoteStderr()));

    ui->lineEdit_command->setEnabled(true);
    ui->pushButton_send->setEnabled(true);
    ui->pushButton->setEnabled(true);

    ui->lineEdit_ip->setEnabled(false);
    ui->lineEdit_passwd->setEnabled(false);
    ui->lineEdit_user->setEnabled(false);
    ui->pushButton_connect->setEnabled(false);
                   
    
}

void MainWindow::handleShellStarted()
{
    m_shell->write(QString("%1\n").arg(ui->lineEdit_command->text()).toLatin1().data());
    ui->lineEdit_command->clear();
}

void MainWindow::handleRemoteStderr()
{
    qDebug() << "shell standard err"<< QString::fromLocal8Bit(m_shell->readAllStandardError());
}


void MainWindow::on_pushButton_connect_clicked()
{
    SshConnectionParameters parameters;
    parameters.port = 22;
    parameters.userName = ui->lineEdit_user->text();
    parameters.password = ui->lineEdit_passwd->text();
    parameters.host = ui->lineEdit_ip->text();
    parameters.timeout = 10;
    parameters.authenticationType = QSsh::SshConnectionParameters::AuthenticationTypePassword;
    if(m_connection == nullptr) {
        m_connection = new SshConnection(parameters);
        connect(m_connection,SIGNAL(connected()),this,SLOT(handleConnected()));
    }
    m_connection->connectToHost();
}

void MainWindow::on_pushButton_send_clicked()
{
    m_shell->start();
    
}

void MainWindow::handleChannelInitialized()
{
    const SftpJobId uploadJob =  m_channel->uploadFile(QString("/home/xmr/test.txt").toLatin1().data(), "/home/xmr/test/test.txt", SftpOverwriteExisting);
    if (uploadJob == SftpInvalidJob) {
        qDebug()<<"error upload file";
    }
    ui->pushButton->setEnabled(true);
}

void MainWindow::handleChannelInitializationFailure(const QString &reason)
{
    qDebug() << "Could not initialize SFTP channel: " << reason;
    ui->pushButton->setEnabled(true);
}

void MainWindow::on_pushButton_clicked()
{
    ui->pushButton->setEnabled(false);
    m_channel->initialize();
}
相关推荐
许白掰2 小时前
Linux入门篇学习——Linux 工具之 make 工具和 makefile 文件
linux·运维·服务器·前端·学习·编辑器
AmosTian8 小时前
【系统与工具】Linux——Linux简介、安装、简单使用
linux·运维·服务器
YC运维10 小时前
RIP实验以及核心原理
运维·网络·智能路由器
小和尚同志10 小时前
全网影视一网打尽!8.2K Star 的 LibreTV 让你甩开追剧烦恼
开源·github
说私域10 小时前
开源链动2+1模式与AI智能名片融合下的S2B2C商城小程序源码:重构大零售时代新生态
人工智能·重构·开源
leo__52011 小时前
自动化运维:使用Ansible简化日常任务
运维·自动化·ansible
霖0011 小时前
C++学习笔记三
运维·开发语言·c++·笔记·学习·fpga开发
国服第二切图仔11 小时前
基于文心开源大模型ERNIE-4.5-0.3B-Paddle私有化部署并构建一个企业智能客服系统
百度·开源·智能客服·知识库·文心大模型·paddle·gitcode
CodeWithMe11 小时前
【Note】《Kafka: The Definitive Guide》 第九章:Kafka 管理与运维实战
运维·分布式·kafka