基于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();
}
相关推荐
想你依然心痛4 小时前
嵌入式容器:Docker与BalenaOS在边缘设备上的实践——容器运行时与OTA
运维·docker·容器
竣达技术4 小时前
NAS / 服务器断电数据丢失?UPS 配套 USB关机保护板,市电断电池低自动提示服务器/电脑关机
运维·服务器·电脑
Lottie20264 小时前
京东电商进阶运营:精准定价+安全铺货+竞品监控+利润管控全自动化方案
运维·安全·自动化
章老师说4 小时前
NGINX官方谈Lua风险:这其实是两条网关技术路线之争
运维·nginx·负载均衡·lua·openresty
GitCode官方5 小时前
openJiuwen 总 Star 突破 3.3 万,与 AtomGit 携手构筑 AI Agent 的开源“生态飞轮”
人工智能·开源
wbs_scy5 小时前
仿 muduo 高并发服务器项目:实现 Any 通用容器并理解 std::any
运维·服务器
沐曦股份MetaX5 小时前
沐曦股份曦云 C 系列GPU率先 Day 0 适配美团新一代万亿参数大模型 LongCat-2.0
开源
做个文艺程序员5 小时前
Linux第11篇:存储管理——磁盘分区、LVM 与文件系统
linux·运维·服务器
懂AI的老郑5 小时前
工业检测场景下智能体的应用:从自动化到智能化
运维·自动化