基于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();
}
相关推荐
cui_win1 小时前
每日一令:Linux 极简通关指南 - 汇总
linux·运维·服务器
知星小度S2 小时前
Linux权限探秘:驾驭权限模型,筑牢系统安全
linux·运维·服务器
说私域2 小时前
基于定制开发开源AI智能名片S2B2C商城小程序的首屏组件优化策略研究
人工智能·小程序·开源·零售
Kaede64 小时前
如何应对Linux云服务器磁盘空间不足的情况
linux·运维·服务器
token-go5 小时前
[特殊字符] 革命性AI提示词优化平台正式开源!
人工智能·开源
Kookoos7 小时前
Dynamics 365 Finance + Power Automate 自动化凭证审核
运维·自动化·dynamics 365·power automate
DevSecOps选型指南11 小时前
2025软件供应链安全最佳实践︱证券DevSecOps下供应链与开源治理实践
网络·安全·web安全·开源·代码审计·软件供应链安全
努力学习的小廉11 小时前
深入了解linux系统—— 进程池
linux·运维·服务器
秃头菜狗11 小时前
各个主要目录的功能 / Linux 常见指令
linux·运维·服务器
jiunian_cn12 小时前
【Linux】centos软件安装
linux·运维·centos