【问题标题】:perfomance libssh2 sftp upload multiple files性能 libssh2 sftp 上传多个文件
【发布时间】:2014-05-15 08:21:42
【问题描述】:

我尝试通过 libssh2 sftp 子系统将多个文件上传到远程服务器。我的问题是我必须在传输一个文件后始终关闭 sftp 句柄和 sftp 会话,否则函数 libssh2_sftp_open() 将失败,“FXP_STATUS 4,无法打开/创建文件”。由于会话和文件的重新初始化,我失去了宝贵的时间。

有没有办法在不重新初始化会话和/或句柄的情况下循环上传多个文件?我希望这段代码 sn-p 能告诉你我的问题, 这里在一个循环通过后重新初始化,但需要 4 秒来上传 4 kbytes:

 // Transfer at most MAXTRANSFER files
    for (i=0;(i < ((MAXTRANSFER<nfiles)?MAXTRANSFER:nfiles)) && (iRet == SSHH_OK); i++) {
        localfile = malloc(sizeof(char) * (strlen(directory) + strlen(fnames[i]) + 2));
        strcpy(localfile, directory);
        strcat(localfile, "/");
        strcat(localfile, fnames[i]);

        local = fopen(localfile, "rb");
        if (!local) {
            dbgPrintFormat(DEBUG_WARNING, "dir_sftp: Can't open local file %s", localfile);
            iRet = SSHH_ERR_SETTINGS;
        }

        // Init SFTP
        if (iRet == SSHH_OK) {
            sftp_session = libssh2_sftp_init(session);
            if (!sftp_session) {
                dbgPrintFormat(DEBUG_ERROR, "dir_sftp: Unable to init SFTP session (%d)", sftp_session);
                iRet = SSHH_ERR_SETTINGS;
            }
        }

        if (iRet == SSHH_OK) {
            stat(localfile, &fileinfo);
            char *dstfile = malloc(sizeof(char) * (strlen(destdir) + strlen(fnames[i]) + 2));
            strcpy(dstfile, destdir);
            strcat(dstfile, "/");
            strcat(dstfile, fnames[i]);

            dbgPrintFormat(DEBUG_FINE, "dir_sftp: Start sending file %s", localfile);

            // Request a file via SFTP
            sftp_handle = libssh2_sftp_open(sftp_session, dstfile,
                             LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC,
                             LIBSSH2_SFTP_S_IRWXU|LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IXGRP);

            if (!sftp_handle) {
                dbgPrintFormat(DEBUG_ERROR, "dir_sftp: Unable to open file with SFTP");
                iRet = SSHH_ERR_SETTINGS;
            }

            if (iRet == SSHH_OK) {
                dbgPrintFormat(DEBUG_FINE, "dir_sftp: SFTP session waiting to send file %s",localfile);
                do {
                    nread = fread(mem, 1, sizeof(mem), local);
                    if (nread <= 0) {
                       /* end of file */
                       break;
                    }
                    ptr = mem;

                    do {
                        /* write the same data over and over, until EOF */
                        rc = libssh2_sftp_write(sftp_handle, ptr, nread);
                        // EOF
                        if(rc < 0)
                            break;
                        ptr += rc;
                        nread -= rc;
                    } while (nread);

                } while (rc > 0);
            }

            ulSftpTxTryCount[iSftpTxTryCountIdx]++;

            if (iRet == SSHH_OK) {
                // Remove localfile *** if no error
                if (remove(localfile) == -1) {
                    dbgPrintFormat(DEBUG_WARNING,"dir_sftp: Error removing file: %s", localfile);
                }
                if( successCnt ) {
                    (*successCnt)++;
                }
                dbgPrintFormat(DEBUG_FINE, "dir_sftp: File sent after %lu tries", ulSftpTxTryCount[iSftpTxTryCountIdx]);
                iSftpTxTryCountIdx = (iSftpTxTryCountIdx + 1) % SCP_TRYCNT_NOF;
                ulSftpTxTryCount[iSftpTxTryCountIdx] = 0;
            }

            free (dstfile);


        }
        if (local)
            fclose(local);
        free (localfile);

        // Close file sftp handle
        if (libssh2_sftp_close(sftp_handle) < 0) {
            dbgPrintFormat(DEBUG_WARNING, "dir_sftp: Error closing SFTP handle ");
        }
        // Close sftp session
        libssh2_sftp_shutdown(sftp_session);
    }

【问题讨论】:

  • 它本来可以工作的,听起来你遇到了一个错误......
  • 我不知道它是如何工作的,因为我在网络或 libssh2 的手册中找不到示例,他们正在上传/打开多个文件...但是我认为我必须关闭 sftp_session 才能打开另一个文件是没有意义的?

标签: c upload ftp sftp libssh2


【解决方案1】:

你有几个问题。第一个问题(您要问的问题)是服务器似乎不喜欢客户端同时打开一个以上的文件。 IE。这可能是特定于服务器的问题(以及 libssh2 的问题)。

更大的问题是你发送一个块,等待结果然后发送另一个块的方法非常慢。当多个块并行异步发送时,第三方 SFTP 库实现了我们所说的流水线。这显着加快了文件传输速度。

我的建议是找一些专门为文件传输编写的第三方库。这会给你更好的速度。

【讨论】:

    【解决方案2】:

    以下是尝试最大化 SFTP 传输速度时要检查的项目:

    您的网络上是否有防火墙或网络设备检查或限制 SSH2 流量?这可能会减慢速度。检查你的防火墙设置。我们有用户报告通过修改他们的防火墙规则来解决极其缓慢的 SFTP 文件传输。 您使用的 SFTP 客户端可以带来很大的不同。尝试几个不同的 SFTP 客户端,看看是否会得到不同的结果。 网络延迟将极大地影响 SFTP。如果您所在的链接具有高度延迟,那么这将成为快速传输的问题。 服务器机器有多强大?使用 SFTP 加密非常密集。确保您有一台足够强大的机器,并且在 SFTP 文件传输期间不会超负荷(高 CPU 利用率)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-29
      • 2012-03-23
      • 1970-01-01
      • 1970-01-01
      • 2021-09-17
      • 2019-03-23
      • 2013-05-07
      相关资源
      最近更新 更多