Qt使用libssh2库远程执行命令

目录

先贴代码

mainwindow.h
[cpp]
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
#include namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_runProgram_clicked();
private:
Ui::MainWindow *ui;
int run_program();
void closeChannel(LIBSSH2CHANNEL *channel);
// 参照google code上remote-cmd项目的方法执行多个语句
int initSession();
int runCommand(QString command);
int uploadFileViaScp(QString a_file_path, QString remote_file_dir);
int closeSession();
QTcpSocket *socket
;
LIBSSH2_SESSION *session_;
LIBSSH2_AGENT *agent_;
};
#endif // MAINWINDOW_H
[/cpp]
mainwindow.cpp
[cpp]
#include “mainwindow.h”
#include “ui_mainwindow.h”
#include
#include
#include
#include
#include
#include
#include
//#include #include //#include MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
session(0),
socket
(0),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
if(session_ && socket_)
{
closeSession();
}
delete ui;
}
void MainWindow::on_runProgram_clicked()
{
//qDebug()<username->text();
QString pass_word=ui->password->text();
//———- connection ————–
int libssh2_error = libssh2_init(0);
if(libssh2_error)
{
qDebug(“libssh2_init() error: %d”, libssh2_error);
return -2;
}
QTcpSocket socket;
socket.connectToHost(host_ip, 22);
if(!socket.waitForConnected())
{
qDebug(“Error connecting to host %s”, host_ip.toLocal8Bit().constData());
return -1;
}
LIBSSH2_SESSION session = libssh2_session_init();
if(!session)
{
qDebug(“libssh2_session_init() failed”);
return -2;
}
libssh2_error = libssh2_session_startup(session, socket.socketDescriptor());
if(libssh2_error)
{
qDebug(“libssh2_session_startup() error: %d”, libssh2_error);
return -3;
}
{
/
At this point we havn’t yet authenticated. The first thing to do
* is check the hostkey’s fingerprint against our known hosts Your app
* may have it hard coded, may go to a file, may present it to the
* user, that’s your call
*/
const char *fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
// qDebug( “Fingerprint: “);
// for(int i = 0; i < 20; i++) // qDebug( “%02X “, (unsigned char)fingerprint[i]); // qDebug( “\n”); } // qDebug(“Password authentication: [%s] [%s]”, user_name.toLocal8Bit().constData(), pass_word.toLocal8Bit().constData()); libssh2_userauth_list(session, user_name.toLocal8Bit().constData(), user_name.toLocal8Bit().length()); if(libssh2_userauth_password( session, user_name.toLocal8Bit().constData(), pass_word.toLocal8Bit().constData() )) { qDebug(“Password authentication failed”); socket.disconnectFromHost(); libssh2_session_disconnect(session, “Client disconnecting for error”); libssh2_session_free(session); libssh2_exit(); return -4; } // command channel //-–-–-–-–setup channel -–-–-–-–-–-–-— LIBSSH2_CHANNEL channel = NULL; channel = libssh2_channel_open_session(session); int rc; if ( channel == NULL ) { qDebug()<<“Failed to open a new channel\n”; socket.disconnectFromHost(); return -1; } libssh2_channel_set_blocking(channel, 1); while ((rc=libssh2_channel_exec(channel, commandline.toLocal8Bit().constData()))==LIBSSH2_ERROR_EAGAIN ); if (rc) { return -1; } //-–-—read channel-–-–-—- int read; QByteArray byte_array; byte_array.resize(4096); char buffer=byte_array.data(); int buffer_size=byte_array.size(); while(true) { //qDebug(“libssh2_channel_read() >>>”);
{
read = libssh2_channel_read(channel, buffer, buffer_size);
QByteArray debug = QByteArray(buffer, read);
qDebug()<<“STDOUT: “<host->text();
QString user_name=ui->username->text();
QString pass_word=ui->password->text();
//———- connection ————–
int libssh2_error = libssh2_init(0);
if(libssh2error)
{
qDebug(“libssh2_init() error: %d”, libssh2_error);
return -2;
}
socket
=new QTcpSocket(this);
socket_->connectToHost(host_ip, 22);
if(!socket_->waitForConnected())
{
qDebug(“Error connecting to host %s”, hostip.toLocal8Bit().constData());
return -1;
}
session
= libssh2_session_init();
if(!session)
{
qDebug(“libssh2_session_init() failed”);
return -2;
}
libssh2_error = libssh2_session_startup(session_, socket
->socketDescriptor());
if(libssh2_error)
{
qDebug(“libssh2_session_startup() error: %d”, libssh2error);
return -3;
}
{
/* At this point we havn’t yet authenticated. The first thing to do
* is check the hostkey’s fingerprint against our known hosts Your app
* may have it hard coded, may go to a file, may present it to the
* user, that’s your call
*/
// const char *fingerprint = libssh2_hostkey_hash(session_, LIBSSH2_HOSTKEY_HASH_SHA1);
// qDebug( “Fingerprint: “);
// for(int i = 0; i < 20; i++) // qDebug( “%02X “, (unsigned char)fingerprint[i]); // qDebug( “\n”); } // qDebug(“Password authentication: [%s] [%s]”, user_name.toLocal8Bit().constData(), pass_word.toLocal8Bit().constData()); libssh2_userauth_list(session_, user_name.toLocal8Bit().constData(), user_name.toLocal8Bit().length()); if(libssh2_userauth_password( session_, user_name.toLocal8Bit().constData(), pass_word.toLocal8Bit().constData() )) { qDebug(“Password authentication failed”); socket
->disconnectFromHost();
libssh2_session_disconnect(session, “Client disconnecting for error”);
libssh2_session_free(session
);
libssh2_exit();
return -4;
}
return 1;
}
int MainWindow::runCommand(QString command)
{
// command channel
//————setup channel ———————-
LIBSSH2CHANNEL *channel = NULL;
channel = libssh2_channel_open_session(session_);
if ( channel == NULL )
{
qDebug()<<“Failed to open a new channel\n”; socket
->disconnectFromHost();
return -1;
}
/* Force Data to on STDOUT and STDERR to be on seperate channels
* read individually with *_read and *_readstderr functions */
libssh2_channel_handle_extended_data(channel,LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL);
// ????
/* Setup Keepalive to 5 seconds */
//libssh2_keepalive_config(session
, 1, 5);
libssh2_channel_set_blocking(channel, 1);
{
int rc;
while ((rc=libssh2_channel_exec(channel, command.toLocal8Bit().constData()))==LIBSSH2_ERROR_EAGAIN );
if (rc)
{
return -1;
}
//——-read channel———–
int read;
QString stdout_str;
QString stderr_str;
while(true)
{
//qDebug(“libssh2_channel_read() >>>”);
{
QByteArray byte_array;
byte_array.resize(4096);
char* buffer=byte_array.data();
int buffer_size=byte_array.size();
read = libssh2_channel_read(channel, buffer, buffer_size-10);
if(read>0)
{
QByteArray debug = QByteArray(buffer, read);
stdout_str.append(debug);
}
if(LIBSSH2_ERROR_EAGAIN == read)
{
qDebug(“LIBSSH2_ERROR_EAGAIN”);
break;
}
else if(read < 0) { qDebug(” error reading from std channel”); closeChannel(channel); goto next_channel; } } { QByteArray byte_array; byte_array.resize(4096); char* buffer=byte_array.data(); int buffer_size=byte_array.size(); /** * 执行llq -l 命令时,此处执行时间过长,直接卡死,具体问题是什么? */ read = libssh2_channel_read_stderr(channel, buffer, buffer_size-10); if(read>0)
{
QByteArray debug = QByteArray(buffer, read);
stderr_str.append(debug);
}
if(LIBSSH2_ERROR_EAGAIN == read)
{
qDebug(“LIBSSH2_ERROR_EAGAIN”);
break;
}
else if(read < 0) { qDebug(” error reading from stderr channel”); closeChannel(channel); goto next_channel; } } int i = libssh2_channel_eof(channel); if(i) { //qDebug(“libssh2_channel_eof %i”, i); closeChannel(channel); goto next_channel; } } next_channel: if(!stdout_str.isEmpty()) { qDebug()<<“STDOUT:\n”<isOpen())
socket->disconnectFromHost();
socket
->deleteLater();
socket=0;
libssh2_session_disconnect(session
, “Client disconnecting normally”);
libssh2_session_free(session_);
libssh2_exit();
return 1;
}
[/cpp]
mianwindow.ui
[xml]
<?xml version=“1.0” encoding=“UTF-8”?>


MainWindow

0
0
275
194
MainWindow

40
40
54
12
username


40
70
54
12
passwd


90
40
113
20
username


90
70
113
20
password QLineEdit::Password


160
110
75
23
Run


40
20
54
12
host


90
10
113
20
10.20.49.131



0
0
275
23



TopToolBarArea


false








[/xml]

参考

1. remote-cmd 项目:使用libssh2库执行多条语句。执行命令的代码文件:

https://code.google.com/p/remote-cmd/source/browse/trunk/src/runcommand.c