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

发布于:2025-03-05 ⋅ 阅读:(9) ⋅ 点赞:(0)
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();
}