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

相关文章

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

使用Python实现可恢复式多线程下载器

《使用Python实现可恢复式多线程下载器》在数字时代,大文件下载已成为日常操作,本文将手把手教你用Python打造专业级下载器,实现断点续传,多线程加速,速度限制等功能,感兴趣的小伙伴可以了解下... 目录一、智能续传:从崩溃边缘抢救进度二、多线程加速:榨干网络带宽三、速度控制:做网络的好邻居四、终端交互

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

java实现docker镜像上传到harbor仓库的方式

《java实现docker镜像上传到harbor仓库的方式》:本文主要介绍java实现docker镜像上传到harbor仓库的方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 前 言2. 编写工具类2.1 引入依赖包2.2 使用当前服务器的docker环境推送镜像2.2

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Java easyExcel实现导入多sheet的Excel

《JavaeasyExcel实现导入多sheet的Excel》这篇文章主要为大家详细介绍了如何使用JavaeasyExcel实现导入多sheet的Excel,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录1.官网2.Excel样式3.代码1.官网easyExcel官网2.Excel样式3.代码

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

python实现对数据公钥加密与私钥解密

《python实现对数据公钥加密与私钥解密》这篇文章主要为大家详细介绍了如何使用python实现对数据公钥加密与私钥解密,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录公钥私钥的生成使用公钥加密使用私钥解密公钥私钥的生成这一部分,使用python生成公钥与私钥,然后保存在两个文

浏览器插件cursor实现自动注册、续杯的详细过程

《浏览器插件cursor实现自动注册、续杯的详细过程》Cursor简易注册助手脚本通过自动化邮箱填写和验证码获取流程,大大简化了Cursor的注册过程,它不仅提高了注册效率,还通过友好的用户界面和详细... 目录前言功能概述使用方法安装脚本使用流程邮箱输入页面验证码页面实战演示技术实现核心功能实现1. 随机