qssh使用

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

qssh使用_第1张图片

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

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

封装如下:

// .h
#ifndef SSHCLIENT_H
#define SSHCLIENT_H
#include 
#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 mpShell; // ssh的shell用于发送与回显消息
};

#endif // SSHCLIENT_H


// .cpp
#include 
#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());
	}*/
}

你可能感兴趣的:(qt,开发语言)