qssh使用

news2024/11/18 21:30:29

到官网下载qssh的源码QSsh-botan-1,使用qtcreator打开后,直接编译,即可得到qssh的库

 头文件将QSsh-botan-1\src\libs\ssh目录下的.h文件拷到include文件夹下,即为库头文件。

qssh有个问题,如果你将qssh的类放在子线程中调用,将获取不到服务器发送回来的数据。故只能放在主线程调用。如有需要从子线程调用的话,可通过在子线程发送信号来调用主线程的槽,从而调用到qssh的功能,使得qssh在主线程调用,即能正常使用。

封装如下:

// .h
#ifndef SSHCLIENT_H
#define SSHCLIENT_H
#include <qobject.h>
#include "sshconnection.h"
#include "sshremoteprocess.h"


class SshClient : public QObject
{
    Q_OBJECT
public:
    SshClient();
    ~SshClient();

    void ConnectToHost(const QString &host, const QString &user, const QString &pwd);
    void DisConnectFromHost();
    void SendCmd(const QByteArray &data);

signals:
    void SendDataRecv(const QByteArray &data);
    void SendConnected(bool bConned);
    void SendShellStarted(bool bStarted);
    void SendRetMsg(const QString &msg);

private slots:
    void OnConnected();
    void onConnectionError(QSsh::SshError);

    void OnShellStarted();
    void OnShellDataRecieved();
    void OnShellError();

private:
    QString mIp;
    QString mUserName;
    QString mPwd;
    QSsh::SshConnection *mpConnection = Q_NULLPTR; // 连接ssh服务器
    QSharedPointer<QSsh::SshRemoteProcess> mpShell; // ssh的shell用于发送与回显消息
};

#endif // SSHCLIENT_H


// .cpp
#include <qcoreapplication.h>
#include "sshclient.h"
#include "log.h"

SshClient::SshClient()
{

}

SshClient::~SshClient()
{
    DisConnectFromHost();
}

void SshClient::ConnectToHost(const QString &host, const QString &username, const QString &pwd)
{
    QSsh::SshConnectionParameters params;
    params.setHost(host);
    params.setUserName(username);
    params.setPassword(pwd);
    params.authenticationType = QSsh::SshConnectionParameters::AuthenticationTypePassword;
    params.timeout = 10;//30;
    params.setPort(22);

    if(mpConnection == Q_NULLPTR)
    {
        mpConnection = new QSsh::SshConnection(params, this); // TODO free this pointer!
    }

    connect(mpConnection, SIGNAL(connected()), SLOT(OnConnected()));
    connect(mpConnection, SIGNAL(error(QSsh::SshError)), SLOT(onConnectionError(QSsh::SshError)));

    mpConnection->disconnectFromHost();
    mpConnection->connectToHost();
    LOG_INFO("conneting to host:%s user:%s pwd:%s",qPrintable(host),qPrintable(username),qPrintable(pwd));
}

void SshClient::DisConnectFromHost()
{
    if(mpShell)
    {
        emit SendShellStarted(false);
        mpShell->close();
        mpShell.reset();
    }

    if(mpConnection != Q_NULLPTR)
    {
        emit SendConnected(false);
        mpConnection->disconnectFromHost();
        delete mpConnection;
        mpConnection = Q_NULLPTR;
    }
}

void SshClient::OnConnected()
{
    emit SendConnected(true);
    LOG_INFO("ssh is connected");

    mpShell = mpConnection->createRemoteShell();
    connect(mpShell.get(), SIGNAL(started()), SLOT(OnShellStarted()));
    connect(mpShell.get(), SIGNAL(readyReadStandardOutput()), SLOT(OnShellDataRecieved()));
    connect(mpShell.get(), SIGNAL(readyReadStandardError()), SLOT(OnShellError()));
    mpShell->start();
}

void SshClient::onConnectionError(QSsh::SshError)
{
	QString errStr = mpConnection->errorString();
    emit SendRetMsg(QString::fromLocal8Bit("连接出错:%1").arg(errStr));
    LOG_ERROR("ssh connected err:%s",mpConnection->errorString().toLocal8Bit().data());
    
	//mpConnection->disconnectFromHost();
   // mpConnection->connectToHost();
}

void SshClient::OnShellStarted()
{
    LOG_INFO("shell is started");
    SendShellStarted(true);
}

void SshClient::OnShellDataRecieved()
{
   QByteArray data = mpShell->readAll();
   if (data.isEmpty())
	   return;
   emit SendDataRecv(data);
   LOG_DEBUG("recv from shell data:%s",data.data());
}

void SshClient::OnShellError()
{
    emit SendRetMsg(QString::fromLocal8Bit("错误:%1").arg(mpShell->errorString()));
    LOG_ERROR("recv from shell err:%s",mpShell->errorString().toLocal8Bit().data());
}

// 发送了命令后,shell会回复两条同样的命令,用于回显
void SshClient::SendCmd(const QByteArray &data)
{
    if(!mpShell)
    {
        LOG_ERROR("shell is not start, can't sendmsg:%s",data.data());
        return;
    }

    qint64 n = mpShell->write(data);
    LOG_DEBUG("write shell data, len:%d, data:%s",n,data.data());
	static const int timeoutMs = 3000;
	int index = 0;
	bool bsucc = mpShell->waitForReadyRead(10);
	while(!bsucc && index < timeoutMs)
	{	
		index += 10;
		QCoreApplication::processEvents();
		if (!mpShell) break;
		bsucc = mpShell->waitForReadyRead(10);
	} 
	/*
	if (bsucc)
	{
		QByteArray data = mpShell->readAll();
		if (data.isEmpty())
			return;
		emit SendDataRecv(data);
		LOG_DEBUG("recv from shell data:%s", data.data());
	}*/
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/802862.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

定时发朋友圈怎么设置?

目前微信作为最大的社交平台之一&#xff0c;吸引了众多使用者。你是否听过有些朋友感叹这么多微信号&#xff0c;需要每天手动发布朋友圈&#xff0c;任务很繁琐呢&#xff1f;是否希望可以事先设置好定时发送的功能&#xff0c;让朋友圈自动更新&#xff0c;省去手动发送的麻…

sqlserver row _number函数的运用

sql语句&#xff1a; select dept_id,stcd,row_number() over (partition by dept_id ORDER BY STCD) as 排序 from tb_station_config 这段代码是使用ROW_NUMBER()函数结合窗口函数的语法&#xff0c;用于给结果集中的每一行分配一个唯一的序号。 具体解释如下&#xff1a; R…

uniapp 小程序实时且持续获取定位信息(全局设置一次)(单页面监听定位改变)(不采用定时器)

本篇文章实现了uniapp 微信小程序实时获取定位信息,小程序打开即可持续获取定位信息, 位置更新也会触发相关自定义事件 优点 只设置一次不采用定时器的方式无需多个页面调用单独页面若想获取当前位置是否变化 可单独设置监听,并调用不同逻辑事件 原理: 采用uniapp推出的: un…

基于深度强化学习的DQN模型实现自动玩俄罗斯方块游戏(附详细代码讲解)

一、DQN&#xff08;Deep Q-Network&#xff09;方法概述 DQN&#xff08;Deep Q-Network&#xff09;是一种强化学习方法&#xff0c;通过结合Q-learning算法和深度神经网络来解决强化学习问题。它是深度强化学习的里程碑之一&#xff0c;由DeepMind在2013年提出&#xff0c;被…

【SQL Server】DBCC CHECKDB只是一个数据库维护命令吗?

日期&#xff1a;2023年7月27日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xf…

【数据仓库】Apache Hive初体验

为什么使用Hive&#xff1f; 使用Hadoop MapReduce直接处理数据所面临的问题&#xff1a; 人员学习成本太高需要掌握ava语言MapReduce实现&#xff0c;复杂查询逻辑开发难度太大&#xff01; 1&#xff0c;使用Hive处理数据的好处操作接口采用类SQL语法&#xff0c;提供快速开发…

MUR2080CT- ASEMI二极管的特性和应用

编辑-Z 本文将详细介绍MUR2080CT二极管的特性和应用。首先&#xff0c;将介绍MUR2080CT二极管的基本结构和工作原理。然后&#xff0c;将探讨MUR2080CT二极管的特性&#xff0c;包括正向电压降、反向漏电流和反向恢复时间等。接下来&#xff0c;将介绍MUR2080CT二极管在电源、…

linux环境安装mysql数据库

一&#xff1a;查看是否自带mariadb数据库 命令&#xff1a;rpm -qa | grep mariadb 如果自带数据库则卸载掉重新安装 命令&#xff1a;yum remove mariadb-connector-c-3.1.11-2.el8_3.x86_64 二&#xff1a;将压缩文件上传到/user/local/mysql文件夹 或者直接下载 命令&a…

18款iPad绘画软件推荐!iPad必备生产力工具

每当提起iPad&#xff0c;少不了会听到坊间流传已久的那句话&#xff0c;「买前生产力&#xff0c;买后爱奇艺」&#xff0c;确实有不少奔着生产力入手iPad的人&#xff0c;最终让iPad沦为煲剧神器或泡面盖&#xff0c;但我们没必要因噎废食&#xff0c;因为总有人能克服iPad上…

互联网医院系统源码实现:打造现代化医疗服务平台

摘要 本文将介绍一个基于Python的简化版互联网医院系统的源码实现&#xff0c;主要包含用户注册与登录、医生信息管理、在线预约挂号、在线问诊与咨询、电子病历管理、在线支付与结算等功能。该源码实现仅为示例&#xff0c;实际开发中需要考虑更多的业务逻辑和安全性。 1. …

摄像头m2dock(MAIX-II DOCK)

官方文档地址 https://wiki.sipeed.com/soft/maixpy3/zh/index.html 一、软件准备 1 烧录镜像软件 2 镜像 当前最近版本镜像文件 3 SDFormatter 4 Maixpy IDE 二、SD卡准备 1 格式化SD卡&#xff08;用SDFormatter&#xff09; 2 烧录 3 弹出&#xff0c;插入开发板中 出现…

会议OA项目之待开历史所有会议(使用一个dao方法完成三种会议状态的查询)

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于OA项目的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.主要功能点介绍 二.效果演示 三.前端…

多线程(JavaEE初阶系列5)

目录 前言&#xff1a; 1.什么是定时器 2.标准库中的定时器及使用 3.实现定时器 结束语&#xff1a; 前言&#xff1a; 在上一节中小编给大家介绍了多线程中的两个设计模式&#xff0c;单例模式和阻塞式队列模式&#xff0c;在单例模式中又有两种实现方式一种是懒汉模式&a…

小白如何在简单的分布式锁里反复踩坑

背景 为什么要做分布式锁&#xff1f; Java开发就逃不过多线程问题&#xff0c;而对于单个实例&#xff0c;我们可以使用synchronized锁作为基本的线程锁&#xff0c;解决多线程问题&#xff0c;但对于实际项目中集群部署&#xff0c;分布式系统&#xff08;不同的客户端&…

HTML再出发

HTML再出发 注意事项VScode相关排版标签语义化块级元素和行内元素文本标签img标签图片格式超链接 注意事项 VScode相关 vscode必须打开一个文件夹才能使用liveServer&#xff0c;只打开一个文件无法使用liveServer功能。网页编写不标准&#xff0c;缺少head&#xff0c;body等…

java springBoot 整合日志

1.在Spring Boot项目的resources目录下创建一个新的logback.xml文件。 2.logback.xml中&#xff0c;配置 代码 <?xml version"1.0" encoding"UTF-8"?> <!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL…

SpringBoot复习:(4)打成的jar包是如何启动的?

jar包通过MANIFEST的Main-Class指定了主类JarLauncher, JarLauncher的main方法代码如下&#xff1a; 其中调用的launch的代码如下&#xff1a; 首先&#xff0c;创建了一个自定义的ClassLoader,代码如下&#xff1a; 其中调用的重载的createClassLoader代码如下&#xff1…

BloomFilter

概念和由来 布隆过滤器&#xff08;英语&#xff1a;Bloom Filter&#xff09;是 1970 年由布隆提出的。它实际上是一个很长的二进制数组(00000000)一系列随机hash算法映射函数&#xff0c;主要用于判断一个元素是否在集合中。 布隆过滤器适用于对存储空间要求较高&#xff0c…

[深度学习实战]基于PyTorch的深度学习实战(下)[Mnist手写数字图像识别]

目录 一、前言二、Mnist手写数字图像识别2.1 加载数据2.1.1 下载地址2.1.2 用 numpy 读取 mnist.npz 2.2 定义卷积模型2.3 开始训练2.4 完整代码2.5 验证结果2.6 修改参数 三、后记 PyTorch——开源的Python机器学习库 一、前言 首先感谢所有点开本文的朋友们&#xff01;基于P…

js正则表达式方法学习

js正则表达式学习 1.能干嘛2.创建正则表达式3.关于正则表达式的方法3.1 正则的方法3.1.1 test3.1.2 compile3.1.3 exec捕获组对象具名捕获组对象非捕获组对象 3.2 String类型的对象的正则相关的方法3.2.1 search()3.2.2 replace()3.2.3 split()3.2.4 match()3.2.5 matchAll() 1…