白夜忘川 2024-08-09 14:46 采纳率: 20%
浏览 56
已结题

C++上传文件到SFTP

如题,需要一份C++上传文件到SFTP服务器的代码。包括:上传、检验文件是否上传成功、创建文件夹、删除文件/文件夹功能。本人抄了些代码如下,还没有成功访问到服务器,停在了libssh2_session_handshake这一步,甚至连错误里边的内容都没有打印程序就自己结束了。我在命令窗已经验证过能够访问到服务器的,见下图。希望广大朋友们都看看!不限制库类型,如有其他上传的方式,比如curl或者其他,我也可以接受

// 初始化 libssh2 库
    int rc = libssh2_init(0);
    if (rc != 0) {
        std::cerr << "libssh2 initialization failed" << std::endl;
        return 1;
    }
    std::cerr << "1" << std::endl;

    WORD wVersionRequested;
    WSADATA wsaData;
    int err;
    wVersionRequested = MAKEWORD(1, 1);
    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0)
    {
        return 1;
    }

    // 建立 TCP 连接
    const char* hostname = "10.107.33.86";
    int port = 30022;
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1) {
        std::cerr << "socket failed" << std::endl;
        libssh2_exit();
        return 1;
    }
    std::cerr << "2" << std::endl;
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(port);
    sin.sin_addr.s_addr = inet_addr(hostname);
    if (connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)) != 0) {
        std::cerr << "connect failed" << std::endl;
        close(sock);
        libssh2_exit();
        return 1;
    }
    std::cerr << "3" << std::endl;

    // 建立 SFTP 会话
    LIBSSH2_SESSION* session = libssh2_session_init();
    if (!session) {
        std::cerr << "libssh2_session_init failed" << std::endl;
        close(sock);
        libssh2_exit();
        return 1;
    }
    std::cerr << "4" << std::endl;

    rc = libssh2_session_handshake(session, sock);
    if (rc != 0) {
        std::cerr << "libssh2_session_handshake failed" << std::endl;
        close(sock);
        libssh2_session_free(session);
        libssh2_exit();
        return 1;
    }
    std::cerr << "5" << std::endl;

    const char* user = "ftp01";
    const char* password = "ggAe763@123!";
    rc = libssh2_userauth_password(session, user, password);
    if (rc != 0) {
        std::cerr << "libssh2_userauth_password failed" << std::endl;
        close(sock);
        libssh2_session_free(session);
        libssh2_exit();
        return 1;
    }
    std::cerr << "6" << std::endl;

    LIBSSH2_SFTP* sftp = libssh2_sftp_init(session);
    if (!sftp) {
        std::cerr << "libssh2_sftp_init failed" << std::endl;
        close(sock);
        libssh2_session_free(session);
        libssh2_exit();
        return 1;
    }


img

  • 写回答

26条回答 默认 最新

  • 栗筝i Java领域优质创作者 2024-08-09 15:03
    关注
    获得0.90元问题酬金

    以下内容参考自 AICG 生成结果,并由 '栗筝i' 整理回复,相关结果及代码方法已验证可行,有用望采纳:


    你的问题中提到的 libssh2_session_handshake 失败可能有几个原因。这里我将提供一些可能的解决步骤和调试建议,同时也会补充完成SFTP上传文件、创建文件夹、删除文件/文件夹功能的代码示例。

    解决 libssh2_session_handshake 失败

    1. 检查SFTP服务器配置

      • 确保SFTP服务器(如OpenSSH)已正确安装并配置为允许SFTP连接。
      • 检查服务器的防火墙设置,确保端口30022(或你配置的任何端口)是开放的。
    2. 验证服务器地址和端口

      • 确认你使用的IP地址和端口号是正确的。
    3. 检查服务器SSH版本和配置

      • 有些SSH服务器配置可能不支持某些libssh2的特性或版本。
    4. 使用网络抓包工具(如Wireshark):

      • 抓包查看客户端和服务器之间的通信,检查是否有明显的错误或断开的连接。
    5. 检查libssh2库

      • 确保你使用的libssh2库是最新的,或者至少是与你的SSH服务器兼容的版本。
    6. 增加错误处理

      • 使用 libssh2_session_last_errorlibssh2_strerror 来获取更详细的错误信息。

    SFTP操作代码示例

    以下是一个简化的代码示例,展示了如何使用libssh2库进行SFTP文件上传、文件夹创建和文件/文件夹删除:

    #include <libssh2.h>
    #include <libssh2_sftp.h>
    #include <iostream>
    
    // ... (你的连接代码)
    
    // 上传文件
    int sftp_upload(LIBSSH2_SFTP* sftp, const char* localpath, const char* remotepath) {
        LIBSSH2_SFTP_HANDLE* sftp_handle;
        sftp_handle = libssh2_sftp_open(sftp, remotepath, LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC, LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR);
        if (!sftp_handle) {
            std::cerr << "Unable to open file with SFTP" << std::endl;
            return -1;
        }
    
        // 读取并写入文件(此处省略具体实现)
    
        libssh2_sftp_close(sftp_handle);
        return 0;
    }
    
    // 创建文件夹
    int sftp_mkdir(LIBSSH2_SFTP* sftp, const char* remotepath) {
        int rc = libssh2_sftp_mkdir(sftp, remotepath, LIBSSH2_SFTP_S_IRWXU);
        if (rc != 0) {
            std::cerr << "Failed to create directory: " << libssh2_strerror(rc) << std::endl;
            return -1;
        }
        return 0;
    }
    
    // 删除文件/文件夹
    int sftp_rm(LIBSSH2_SFTP* sftp, const char* remotepath) {
        int rc = libssh2_sftp_unlink(sftp, remotepath);
        if (rc != 0) {
            std::cerr << "Failed to delete: " << libssh2_strerror(rc) << std::endl;
            return -1;
        }
        return 0;
    }
    
    // ... (继续你的代码,并在适当位置调用这些函数)
    
    libssh2_exit();
    

    注意

    • 上面的代码示例中,文件读写部分(在 sftp_upload 函数中)需要你根据实际需求实现。
    • 对于删除文件夹,SFTP协议本身没有直接的删除文件夹命令,你可能需要递归地删除文件夹内的所有文件和子文件夹。
    • 确保在调用 libssh2_exit() 之前释放所有分配的资源,如SFTP句柄、会话等。

    希望这些信息能帮助你解决问题!如果问题依旧存在,请提供更多的错误信息和上下文。

    评论

报告相同问题?

问题事件

  • 系统已结题 8月17日
  • 赞助了问题酬金15元 8月9日
  • 修改了问题 8月9日
  • 修改了问题 8月9日
  • 展开全部

悬赏问题

  • ¥15 C++ 句柄后台鼠标拖动如何实现
  • ¥15 有人会SIRIUS 5.8.0这个软件吗
  • ¥30 comsol仿真等离激元
  • ¥15 静电纺丝煅烧后如何得到柔性纤维
  • ¥15 (标签-react native|关键词-镜像源)
  • ¥100 照片生成3D人脸视频
  • ¥15 伪装视频时长问题修改MP4的时长问题,
  • ¥15 JETSON NANO
  • ¥15 VS开发qt时如何在paintgl函数中用pushbutton控制切换纹理
  • ¥20 关于 openpyxl 处理excel文件地问题