SSH连接SFTP传输:如何使用libssh库在windows环境下进行(文件、文件夹)传输到远端服务器

这篇具有很好参考价值的文章主要介绍了SSH连接SFTP传输:如何使用libssh库在windows环境下进行(文件、文件夹)传输到远端服务器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

由于windows上的编译器一般都是没有libssh库的,所以如何我们想要使用libssh库那么我们将会使用cmake来编译libssh官网给出的源代码

libssh库下载地址:https://www.libssh.org/files/

libssh 环境变量,Windows开发小demo,ssh,windows,libssh,文件传输

配置环境

我们在编译libssh库之前需要先配置一些环境:

  • a) 安装 Visual Studio 或者 MinGW
  • b) 安装OpenSSL http://slproweb.com/products/Win32OpenSSL.htmlC:\Program Files
  • c) 安装zlib http://zlib.net/zlib128-dll.zipC:\Program Files
  • d) 安装CMake http://cmake.org/cmake/resources/software.html

有些库需要将其.dll加入环境变量,具体可自行探索

cmake编译libssh

解压压缩包,进入目录,在当前页面右键打开终端
libssh 环境变量,Windows开发小demo,ssh,windows,libssh,文件传输
执行以下命令:

mkdir build
cd build
cmake ..

如果出现一些报错很可能是配置环境的问题,可以观察报错信息逐一解决

打开libssh.sln项目(使用cmake编译的编译器与打开的编译器需一致)
libssh 环境变量,Windows开发小demo,ssh,windows,libssh,文件传输
ssh设为启动项目
libssh 环境变量,Windows开发小demo,ssh,windows,libssh,文件传输
Ctrl + B生成解决项目,生成dlllib文件
libssh 环境变量,Windows开发小demo,ssh,windows,libssh,文件传输

如何使用生成的dll与lib文件

配置lib 方法一

打开vs工程 -》 项目 -》 属性

  1. 将头文件也就是进入include下的路径添加进入附加包含目录
    G:\xxx\libssh-0.10.0\include
    libssh 环境变量,Windows开发小demo,ssh,windows,libssh,文件传输
  2. .lib文件所在目录添加进入附加库目录
    G:\xxx\libssh-0.10.0\build\src\Debug
    libssh 环境变量,Windows开发小demo,ssh,windows,libssh,文件传输
  3. ssh.lib添加进入附加依赖项
    libssh 环境变量,Windows开发小demo,ssh,windows,libssh,文件传输

配置lib 方法二

ssh.lib文件复制到当前项目所在路径下
libssh 环境变量,Windows开发小demo,ssh,windows,libssh,文件传输

ssh.lib导入项目即可,同理头文件也可直接复制进入项目路径
libssh 环境变量,Windows开发小demo,ssh,windows,libssh,文件传输

  • 如果是第一种方法,头文件引入可以#include <libssh/libssh.h> #include <libssh/sftp.h>
  • 如果是第二种方法,头文件引入必须#include "libssh/libssh.h" #include "libssh/sftp.h"

如果编译报错缺少这个文件libssh_version.h
这个文件在这个路径下G:\xxx\libssh-0.10.0\build\include\libssh,可以直接复制到libssh/下使用
libssh 环境变量,Windows开发小demo,ssh,windows,libssh,文件传输

配置dll方法一 将dll配置进入环境变量

点击此电脑 -》右键属性 -》 点击高级系统设置
libssh 环境变量,Windows开发小demo,ssh,windows,libssh,文件传输
libssh 环境变量,Windows开发小demo,ssh,windows,libssh,文件传输
dll文件所在路径添加进入环境变量
G:\xxx\libssh-0.10.0\build\src\Debug
libssh 环境变量,Windows开发小demo,ssh,windows,libssh,文件传输
libssh 环境变量,Windows开发小demo,ssh,windows,libssh,文件传输

配置dll方法二 在编译过后将dll直接与可执行文件.exe文件放在同一目录下

要使得用libssh库的项目能通过编译,需要将头文件以及.lib配置进入项目

如果出现__imp__ xxx类型的链接错误很有很可能是当前项目是X86环境,而libssh库是X64的库,需要将vs执行环境改为X64文章来源地址https://www.toymoban.com/news/detail-856697.html

传输文件、文件夹代码(适配windows)

int sftp_normal_upload(ssh_session session, sftp_session sftp, const char* local_file_path, const char* remote_file_path)
{
    sftp_file file = sftp_open(sftp, remote_file_path, O_WRONLY | O_CREAT, 0666);
    if (!file) {
        fprintf(stderr, "Failed to open remote file: %s:sftp_get_error(%d)\n", remote_file_path, sftp_get_error(sftp));
        fprintf(stderr, "Can't create directory: %s\n", ssh_get_error(session));
        return -1;
    }

    FILE* local_file = fopen(local_file_path, "rb");
    if (!local_file) {
        fprintf(stderr, "Failed to open local file: %s\n", local_file_path);
        sftp_close(file);
        return -1;
    }

    // 上传文件内容
    char buffer[1024];
    size_t bytes_read;
    while ((bytes_read = fread(buffer, 1, sizeof(buffer), local_file)) > 0) {
        sftp_write(file, buffer, bytes_read);
    }

    fclose(local_file);
    sftp_close(file);
    return 1;
}



int sftp_recursive_upload(ssh_session session, sftp_session sftp, const char* local_path, const char* remote_path) {

    // 计算转换后的宽字符所需缓冲区大小
    int bufferSize_local = MultiByteToWideChar(CP_ACP, 0, local_path, -1, NULL, 0);
    int bufferSize_remote = MultiByteToWideChar(CP_ACP, 0, remote_path, -1, NULL, 0);

    // 分配缓冲区
    wchar_t* local_path_to_wchar = (wchar_t*)malloc(bufferSize_local * sizeof(wchar_t));
    wchar_t* remote_path_to_wchar = (wchar_t*)malloc(bufferSize_remote * sizeof(wchar_t));
    if (local_path_to_wchar == NULL || local_path_to_wchar == NULL) {
        fprintf(stderr, "Failed to memory\n");
        // 处理内存分配失败的情况
        return -1;
    }

    // 执行转换
    MultiByteToWideChar(CP_ACP, 0, local_path, -1, local_path_to_wchar, bufferSize_local);
    MultiByteToWideChar(CP_ACP, 0, remote_path, -1, remote_path_to_wchar, bufferSize_remote);

    //给local_path追加通配符
    const wchar_t* str = L"\\*";
    wchar_t local_current[MAX_PATH];

    if (wcslen(local_path_to_wchar) + 3 >= MAX_PATH - 1)
    {
        fprintf(stderr, "Failed to strcat wildcard character\n");
        return -1;
    }
    // 将str1复制到result中
    wcscpy(local_current, local_path_to_wchar);
    // 追加str2到result中
    wcscat(local_current, str);


    // 打开本地目录
    WIN32_FIND_DATA FindFileData;
    HANDLE hFind = INVALID_HANDLE_VALUE;
    hFind = FindFirstFile(local_current, &FindFileData);
    if (hFind == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "Failed to open local directory: %s\n", local_current);
        return -1;
    }

    // 创建服务器目录
    sftp_mkdir(sftp, remote_path, 0777);

    // 遍历本地目录项
    do {
        if (wcscmp(FindFileData.cFileName, L".") != 0 && wcscmp(FindFileData.cFileName, L"..") != 0) {
            // 构造全路径
            wchar_t local_file_path[MAX_PATH];
            _snwprintf(local_file_path, sizeof(local_file_path), L"%s\\%s", local_path_to_wchar, FindFileData.cFileName);
            wchar_t remote_file_path[MAX_PATH];
            _snwprintf(remote_file_path, sizeof(remote_file_path), L"%s/%s", remote_path_to_wchar, FindFileData.cFileName);

            // 将宽字符字符串转换为多字节字符字符串
            char local_next[MAX_PATH];
            char remote_next[MAX_PATH];
            if (wcstombs(local_next, local_file_path, sizeof(local_next)) == (size_t)-1 ||
                wcstombs(remote_next, remote_file_path, sizeof(remote_next)) == (size_t)-1) {
                fprintf(stderr, "wchar_t conversion to char failed\n");
                return -1;
            }

            // 如果本地条目是一个目录,递归上传它
            if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                sftp_recursive_upload(session, sftp, local_next, remote_next);
            }
            else { // 如果本地条目是一个普通文件,上传它
                sftp_normal_upload(session, sftp, local_next, remote_next);
            }
        }
    } while (FindNextFile(hFind, &FindFileData) != 0);

    free(local_path_to_wchar);
    free(remote_path_to_wchar);
    FindClose(hFind);
    return 1;
}


ssh_session ssh_create(const char* target_host, const char* target_username)
{
    ssh_session session;

    // 连接SSH会话
    session = ssh_new();
    if (!session) {
        fprintf(stderr, "Failed to create SSH session\n");
        return NULL;
    }

    ssh_options_set(session, SSH_OPTIONS_HOST, target_host);
    ssh_options_set(session, SSH_OPTIONS_USER, target_username);

    if (ssh_connect(session) != SSH_OK) {
        fprintf(stderr, "Failed to connect to SSH session: %s\n", ssh_get_error(session));
        ssh_free(session);
        return NULL;
    }
    return session;
}

int sftp_run(ssh_session session, const char* local_file_dir, const char* target_path)
{
    sftp_session sftp;

    // 打开SFTP通道
    sftp = sftp_new(session);
    if (!sftp) {
        fprintf(stderr, "Failed to create SFTP session\n");
        ssh_disconnect(session);
        ssh_free(session);
        return -1;
    }

    if (sftp_init(sftp) != SSH_OK) {
        fprintf(stderr, "Failed to initialize SFTP session\n");
        sftp_free(sftp);
        ssh_disconnect(session);
        ssh_free(session);
        return -1;
    }


    // 得到当前 文件/目录 所在路径
    char local_dir[4096];
    getcwd(local_dir, sizeof(local_dir));
    int len = strlen(local_dir);
    if ((len + strlen(local_file_dir) + 2) >= 4095) {
        perror("Local filename is too long");
        return -1;
    }

    local_dir[len] = '\\';
    local_dir[len + 1] = '\0';
    strcat(local_dir, local_file_dir);

    struct _stat file_stat;

    // 获取文件的详细信息
    if (_stat(local_dir, &file_stat) != 0) {
        perror("stat");
        return -1;
    }

    // 判断文件类型

    //普通文件
    if ((file_stat.st_mode & _S_IFMT) == _S_IFREG) {
        sftp_normal_upload(session, sftp, local_dir, target_path);
    }
    //目录文件
    else if ((file_stat.st_mode & _S_IFMT) == _S_IFDIR) {
        // 递归上传本地目录到远程目录
        if (sftp_recursive_upload(session, sftp, local_dir, target_path) != 1) {
            fprintf(stderr, "Failed to recursively upload directory\n");
            sftp_free(sftp);
            ssh_disconnect(session);
            ssh_free(session);
            return -1;
        }
    }
    else {
        printf("%s 既不是普通文件,也不是目录,无法上传\n", local_dir);
    }

    // 释放
    sftp_free(sftp);
    ssh_disconnect(session);
    ssh_free(session);

    return 1;
}

int ssh_sftp_transmit_password(const char* target_host, const char* target_username,
    const char* target_password, const char* local_file_dir, const char* target_path)
{
    // ssh连接建立
    ssh_session session = ssh_create(target_host, target_username);
    if (session == NULL)return -1;

    // 身份验证 - 密码
    if (ssh_userauth_password(session, NULL, target_password) != SSH_AUTH_SUCCESS) {
        fprintf(stderr, "Failed to authenticate with password\n");
        ssh_disconnect(session);
        ssh_free(session);
        return -1;
    }

    // 传输
    int re = sftp_run(session, local_file_dir, target_path);

    return re;
}


int ssh_sftp_transmit_publickey(const char* target_host, const char* target_username,
    const char* local_file_dir, const char* target_path)
{
    // ssh连接建立
    ssh_session session = ssh_create(target_host, target_username);
    if (session == NULL)return -1;

    // 身份验证 - 密钥
    if (ssh_userauth_publickey_auto(session, NULL, NULL) != SSH_AUTH_SUCCESS) {
        fprintf(stderr, "Authentication failed: %s\n", ssh_get_error(session));
        ssh_disconnect(session);
        ssh_free(session);
        return -1;
    }

    // 传输
    int re = sftp_run(session, local_file_dir, target_path);

    return re;
}

到了这里,关于SSH连接SFTP传输:如何使用libssh库在windows环境下进行(文件、文件夹)传输到远端服务器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【全面解析】Windows 如何使用 SSH 密钥远程连接 Linux 服务器

    创建密钥 创建 linux 服务器端的终端中执行命令 ssh-keygen ,之后一直按Enter即可,这样会在将在 ~/.ssh/ 路径下生成公钥(id_rsa.pub)和私钥(id_rsa) 注意:也可以在 windows 端生成密钥,只需要保证公钥在服务器端,私钥在本地端即可。 安装 在服务器端 ~/.ssh/ 路径下执行以下命令,在

    2024年02月16日
    浏览(38)
  • 内网穿透的应用-如何在Termux 中使用SFTP 文件传输并结合内网穿透实现远程传输

    SFTP(SSH File Transfer Protocol)是一种基于SSH(Secure Shell)安全协议的文件传输协议。与FTP协议相比,SFTP使用了加密和身份验证机制来保护数据的安全性和完整性,可以在不安全的网络中传输文件,因此更加安全可靠,。 下面介绍如何在termux 中使用SFTP 文件传输并结合[cpolar内网映

    2024年02月08日
    浏览(38)
  • Windows11 - 使用 sftp连接 CentOS 7,实现文件上传与下载

    Windows系统的cmd命令实现远程连接服务器,并且使用 sftp连接 CentOS 7,实现文件上传与下载 注意:下方所有服务器ip,均为示例ip 这样就成功连接上服务器,不过命令和Linux上命令有所区别 如下(示例): 注意:sftp 表示已经进入 sftp 的交互模式。 连接成功之后,使用 pwd 命令查

    2024年02月03日
    浏览(32)
  • 如何在Linux机器上使用ssh远程连接Windows Server服务器并使用rsync同步文件

       当前在研究goploy自动化开源部署工具,该工具部署在linux机器上,而要部署服务的目标服务器有一部分是windows server服务器,goploy自动化部署,使用rsync部署方式,底层依赖于ssh远程连接目标服务器,所以,要实现自动化部署,必须先实现ssh远程连接目标windows server服务器

    2024年02月05日
    浏览(49)
  • Java通过OpenSSH(ssh2/ScpClient)远程连接Windows10实现传输文件、解压缩包、执行命令等操作

    远程机器A:Windows 10 专业版 22H2 本地环境:jdk8 设置 -- 应用 -- 应用和功能 -- 可选功能 -- 添加功能 由于我已经安装,在以安装功能里面即可找到。未安装的用户选择添加功能添加即可 启动 OpenSSH SSH Server 服务 输入ssh 出现如下提示即安装成功 编写 bat 脚本,在远程机器上面静

    2024年02月14日
    浏览(67)
  • Pycharm 远程连接docker进行远程调试,ssh测试可连接,但是sftp连接不上的问题

    docker端口配置映射都正确,自己的xshell可以成功连接,使用Pycharm就是sftp连接不上,一直在等待。ssh解释器里显示是连接成功的,但是整个配置到sftp里却是连接失败。删除本机的known_hosts文件、删除重启pycharm、重启电脑、关机重开都不行,以为是sftp的问题,但是发现xftp软件

    2024年02月04日
    浏览(43)
  • vscode远程连接服务器(remote ssh)+上传本地文件到服务器(sftp)

    一、vscode远程连接服务器 1.点击vscode右边工具栏点击拓展,搜索remote ssh并安装 2.安装完成后,左边工具栏会出现一个电脑图标的远程资源管理器,点击后选择SSH TARGETS的设置 3.然后选择第一个..sshconfig 4.向服务器管理员索要服务器的连接信息并修改ssh config文件   5.设置完成

    2024年02月01日
    浏览(33)
  • 如何利用SFTP如何实现更安全的远程文件传输 ——【内网穿透】

    🎬 鸽芷咕 :个人主页  🔥 个人专栏 : 《高效编程技巧》《cpolar》 ⛺️生活的理想,就是为了理想的生活! SFTP(SSH File Transfer Protocol)是一种基于SSH(Secure Shell)安全协议的文件传输协议。与FTP协议相比,SFTP使用了加密和身份验证机制来保护数据的安全性和完整性,可以在

    2024年02月11日
    浏览(28)
  • Kali Linux如何启动SSH并在Windows系统远程连接

    简单几步通过[cpolar 内网穿透](cpolar官网-安全的内网穿透工具 | 无需公网ip | 远程访问 | 搭建网站)软件实现ssh 远程连接kali! 默认新安装的kali系统会关闭ssh 连接服务,我们通过命令打开: 启动后我们查看ssh 状态,active 表示ssh 正常运行 通常ssh 是使用账号或者密码进行登录连接,所

    2024年02月04日
    浏览(35)
  • 如何利用SFTP协议远程实现更安全的文件传输 ——【内网穿透】

    🎬 鸽芷咕 :个人主页  🔥 个人专栏 : 《高效编程技巧》《cpolar》 ⛺️生活的理想,就是为了理想的生活! SFTP(SSH File Transfer Protocol)是一种基于SSH(Secure Shell)安全协议的文件传输协议。与FTP协议相比,SFTP使用了加密和身份验证机制来保护数据的安全性和完整性,可以在

    2024年02月11日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包