Qt C++调用libssh2实现sftp传输文件

2024-04-07 17:12

本文主要是介绍Qt C++调用libssh2实现sftp传输文件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 1.重点说明
    • 1.1SFTP
    • 1.2 FTPS
    • 1.3 FTP
  • 2.测试环境搭建
    • 2.1 Xlight FTP工具
  • 3.简单说明libssh2编译
    • 3.1 windows下编译成功后得到:
    • 3.2 Linux下成功编译后得到:
    • 3.3 cmake输出信息参考:
  • 4.直接上代码
    • 调用

1.重点说明

FTP、FTPS、SFTP不要混淆,我们这里是SFTP

1.1SFTP

  • SFTP(SSH File Transfer Protocol,也称 Secret File Transfer Protocol)是一种安全的文件传输协议,一种通过网络传输文件的安全方法;它确保使用私有和安全的数据流来安全地传输数据。

1.2 FTPS

  • FTPS是一种对常用的文件传输协议(FTP)添加传输层安全(TLS)和安全套接层(SSL)加密协议支持的扩展协议。FTPS不应与基于SSH的SSH文件传输协议或是Secure FTP协议相混淆。

1.3 FTP

  • FTP(File Transfer Protocol,文件传输协议) 是 TCP/IP 协议组中的协议之一。FTP协议包括两个组成部分,其一为FTP服务器,其二为FTP客户端。其中FTP服务器用来存储文件,用户可以使用FTP客户端通过FTP协议访问位于FTP服务器上的资源。在开发网站的时候,通常利用FTP协议把网页或程序传到Web服务器上。此外,由于FTP传输效率非常高,在网络上传输大的文件时,一般也采用该协议。
  • 默认情况下FTP协议使用TCP端口中的 20和21这两个端口,其中20用于传输数据,21用于传输控制信息。但是,是否使用20作为传输数据的端口与FTP使用的传输模式有关,如果采用主动模式,那么数据传输端口就是20;如果采用被动模式,则具体最终使用哪个端口要服务器端和客户端协商决定。

2.测试环境搭建

2.1 Xlight FTP工具

Xlight FTP服务器是非常容易使用的FTP服务器。 为了保证高性能,FTP服务器全部用C语言写成,服务器运行时占用很少的系统资源。它具有高效网络算法,在大量用户情况下, 可以充分利用FTP服务器带宽, 能够轻松处理数千用户的同时下载。

  • 我们使用了Xlight FTP工具,具体安装和配置这里不提供!
    在这里插入图片描述

3.简单说明libssh2编译

3.1 windows下编译成功后得到:

在这里插入图片描述

3.2 Linux下成功编译后得到:

在这里插入图片描述

3.3 cmake输出信息参考:

-- The following features have been enabled:* Static library, creating libssh2 static library* Shared library, creating libssh2 shared library (.so/.dll)* Crypto backend, OpenSSL-- The following OPTIONAL packages have been found:* OpenSSL* ZLIB-- The following features have been disabled:* Logging, Logging of execution with debug trace* Without deprecated APIs* Compression, using zlib for compression-- Configuring done (0.0s)
-- Generating done (0.1s)
-- Build files have been written to: 

4.直接上代码

/*** SFTP download by libssh2*/#include <fcntl.h>
#include <errno.h>
#include <stdio.h>#include <ctype.h>#ifdef Q_OS_LINUX
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#else
#include <winsock2.h>
#include <Windows.h>
#endif#include "sftp_get.h"using namespace std;SftpGet::SftpGet(): m_socket(0), m_sshSession(NULL), m_sftpSession(NULL)
{
}SftpGet::~SftpGet()
{
}int SftpGet::Connect(const char* host, int port, const char* username, const char* password)
{int rc = libssh2_init(0);if (rc != 0){snprintf(m_lastError, sizeof(m_lastError), "libssh2 initialization failed: %d", rc);return rc;}m_socket = socket(AF_INET, SOCK_STREAM, 0);sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(port);sin.sin_addr.s_addr = inet_addr(host);if (::connect(m_socket, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)) != 0){snprintf(m_lastError, sizeof(m_lastError), "failed to connect!");return -1;}// Create a session instancem_sshSession = libssh2_session_init();if(!m_sshSession){snprintf(m_lastError, sizeof(m_lastError), "libssh2_session_init failed!");return -1;}// Since we have set non-blocking, tell libssh2 we are blockinglibssh2_session_set_blocking(m_sshSession, 1);rc = libssh2_session_handshake(m_sshSession, m_socket);if (rc != 0){snprintf(m_lastError, sizeof(m_lastError), "Failure establishing SSH session: %d", rc);return rc;}// const char* fingerprint =libssh2_hostkey_hash(m_sshSession, LIBSSH2_HOSTKEY_HASH_SHA1);// check what authentication methods are availableconst char* userauthlist = libssh2_userauth_list(m_sshSession, username, strlen(username));if (strstr(userauthlist, "password") == NULL){snprintf(m_lastError, sizeof(m_lastError), "Authentication by password not supported");return 1;}// authenticate via passwordif (libssh2_userauth_password(m_sshSession, username, password)){snprintf(m_lastError, sizeof(m_lastError), "Authentication by password failed");return 2;}m_sftpSession = libssh2_sftp_init(m_sshSession);if (!m_sftpSession){snprintf(m_lastError, sizeof(m_lastError), "Unable to init SFTP session");return -1;}return 0;
}int SftpGet::SFtpRead(const char* remoteFile, char* data_buf, int* data_len)
{// Request a file via SFTPLIBSSH2_SFTP_HANDLE* sftpHandle = libssh2_sftp_open(m_sftpSession, remoteFile, LIBSSH2_FXF_READ, 0);if (!sftpHandle){snprintf(m_lastError, sizeof(m_lastError), "Unable to open file with SFTP: %ld\n",libssh2_sftp_last_error(m_sftpSession));return -1;}// libssh2_sftp_open() is done, now receive data!int len = 0;while(1){if (len < *data_len){int sz = libssh2_sftp_read(sftpHandle, data_buf + len, *data_len - len);if (sz > 0){len += sz;}else{break;}}else{snprintf(m_lastError, sizeof(m_lastError), "The data buffer is too small for the file data");return 1;}}*data_len = len;libssh2_sftp_close(sftpHandle);return 0;
}int SftpGet::Download(const char* remoteFile, const char* localPath)
{// Request a file via SFTPLIBSSH2_SFTP_HANDLE* sftpHandle = libssh2_sftp_open(m_sftpSession, remoteFile, LIBSSH2_FXF_READ, 0);if (!sftpHandle){snprintf(m_lastError, sizeof(m_lastError), "Unable to open file with SFTP: %ld\n",libssh2_sftp_last_error(m_sftpSession));return -1;}// libssh2_sftp_open() is done, now receive data!FILE* fp = fopen(localPath, "w");if (!fp){snprintf(m_lastError, sizeof(m_lastError), "Fail to create file: %s", localPath);return 2;}char buf[1024];while(1){int sz = libssh2_sftp_read(sftpHandle, buf, sizeof(buf));if (sz > 0){fwrite(buf, 1, sz, fp);}else{break;}}fclose(fp);libssh2_sftp_close(sftpHandle);return 0;
}void SftpGet::Close()
{if (m_sftpSession){libssh2_sftp_shutdown(m_sftpSession);m_sftpSession = NULL;}if (m_sshSession){libssh2_session_disconnect(m_sshSession, "Shutdown");libssh2_session_free(m_sshSession);m_sshSession = NULL;}if (m_socket){::close(m_socket);m_socket = 0;}libssh2_exit();
}string SftpGet::GetLastError()
{return m_lastError;
}

调用

// 测试从SFtp,上传、下载文件
int Upload2DownloadFile_SFtp()
{SftpGet fg;int ret = fg.Connect("127.0.0.1", 22, "root", "johnshao");if (ret){std:string errmsg = fg.GetLastError();qDebug() << errmsg.c_str();return -1;}int len = 1024 * 1024;char buf[len] = { 0 };ret = fg.SFtpRead("interview/binary_find.cpp", buf, &len);if (ret){std::string errmsg = fg.GetLastError();qDebug() << errmsg.c_str();return -1;}qDebug() << buf;ret = fg.Download("interview/binary_find.cpp", "binary_find.cpp");if (ret){std::string errmsg = fg.GetLastError();qDebug() << errmsg.c_str();return -1;}return 0;
}

这篇关于Qt C++调用libssh2实现sftp传输文件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/883191

相关文章

C#实现将Excel表格转换为图片(JPG/ PNG)

《C#实现将Excel表格转换为图片(JPG/PNG)》Excel表格可能会因为不同设备或字体缺失等问题,导致格式错乱或数据显示异常,转换为图片后,能确保数据的排版等保持一致,下面我们看看如何使用C... 目录通过C# 转换Excel工作表到图片通过C# 转换指定单元格区域到图片知识扩展C# 将 Excel

基于Java实现回调监听工具类

《基于Java实现回调监听工具类》这篇文章主要为大家详细介绍了如何基于Java实现一个回调监听工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录监听接口类 Listenable实际用法打印结果首先,会用到 函数式接口 Consumer, 通过这个可以解耦回调方法,下面先写一个

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

Qt中QGroupBox控件的实现

《Qt中QGroupBox控件的实现》QGroupBox是Qt框架中一个非常有用的控件,它主要用于组织和管理一组相关的控件,本文主要介绍了Qt中QGroupBox控件的实现,具有一定的参考价值,感兴趣... 目录引言一、基本属性二、常用方法2.1 构造函数 2.2 设置标题2.3 设置复选框模式2.4 是否

QT进行CSV文件初始化与读写操作

《QT进行CSV文件初始化与读写操作》这篇文章主要为大家详细介绍了在QT环境中如何进行CSV文件的初始化、写入和读取操作,本文为大家整理了相关的操作的多种方法,希望对大家有所帮助... 目录前言一、CSV文件初始化二、CSV写入三、CSV读取四、QT 逐行读取csv文件五、Qt如何将数据保存成CSV文件前言

Qt中QUndoView控件的具体使用

《Qt中QUndoView控件的具体使用》QUndoView是Qt框架中用于可视化显示QUndoStack内容的控件,本文主要介绍了Qt中QUndoView控件的具体使用,具有一定的参考价值,感兴趣的... 目录引言一、QUndoView 的用途二、工作原理三、 如何与 QUnDOStack 配合使用四、自

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

springboot整合阿里云百炼DeepSeek实现sse流式打印的操作方法

《springboot整合阿里云百炼DeepSeek实现sse流式打印的操作方法》:本文主要介绍springboot整合阿里云百炼DeepSeek实现sse流式打印,本文给大家介绍的非常详细,对大... 目录1.开通阿里云百炼,获取到key2.新建SpringBoot项目3.工具类4.启动类5.测试类6.测

pytorch自动求梯度autograd的实现

《pytorch自动求梯度autograd的实现》autograd是一个自动微分引擎,它可以自动计算张量的梯度,本文主要介绍了pytorch自动求梯度autograd的实现,具有一定的参考价值,感兴趣... autograd是pytorch构建神经网络的核心。在 PyTorch 中,结合以下代码例子,当你

SpringBoot集成Milvus实现数据增删改查功能

《SpringBoot集成Milvus实现数据增删改查功能》milvus支持的语言比较多,支持python,Java,Go,node等开发语言,本文主要介绍如何使用Java语言,采用springboo... 目录1、Milvus基本概念2、添加maven依赖3、配置yml文件4、创建MilvusClient