基于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();
}
相关推荐
江华森1 小时前
操作系统与 Linux 内核实战教程
linux·运维·服务器
带娃的IT创业者1 小时前
穿越回 1980:解读微软开源的“最早 DOS 源码”与操作系统的原点
microsoft·微软·开源·操作系统·dos·源码解析·计算机历史
xixingzhe21 小时前
AI运维注意点
运维·人工智能
大树882 小时前
PUE 超 1.35 要多交多少?存量机房液冷改造 3 张算账表
大数据·运维·服务器·人工智能
创世宇图2 小时前
Cherry-Studio 深度实践:当你的桌面变成一个 AI 指挥中心
开源·agent·studio
X54先生(人文科技)2 小时前
《元创力》纪实录·卷宗 2.2烛火传递:硅基纪元的第一个黎明
人工智能·深度学习·开源·ai写作
小此方2 小时前
Re:Linux系统篇(二十八)文件篇·一:理解 Linux 文件基础I/O、Linux 文件操作与系统调用机制
linux·运维·服务器
likerhood2 小时前
Linux 服务器基础资源查看:CPU、GPU、内存、磁盘与一键检测脚本
linux·运维·服务器
极客先躯2 小时前
高级java每日一道面试题-2026年01月19日-实战篇[Docker]-如何配置镜像仓库的垃圾回收 (GC)?
java·运维·docker·容器
AOwhisky2 小时前
学习自测与解析:MySQL 系列第三期与第四期
linux·运维·数据库·学习·mysql·云计算