首页 > 解决方案 > 在 Windows 10 Visual Studio 2017 上为 FTPS 设置 Curl

问题描述

我正在尝试设置 Curl 以在 Windows 10 上的 Visual Studio 2017(社区)上与 FTPS 一起使用,但我不断收到奇怪的错误(错误包含在我尝试过的不同事物中)。我目前有 Curl 在 Mac 上为 FTPS 工作,目前我在 Linux 上不需要它。

我尝试过的事情:

  1. 在Curls 下载页面下载二进制文件 要为 MacOs 设置 Curl,我所要做的就是下载 MacOs 二进制文件并链接它,所以这是我开始为 Windows 设置 Curl 的地方。然而,在下载二进制文件时,它只包含 .dll。它缺少标头和 .lib 文件。我尝试下载了大约 5 个其他二进制文件,每个都缺少至少一个基本文件。

  2. 通过 vcpkg 安装 在获取二进制文件失败后,我意识到 Curl 可能在 vcpkg 上。我 ./vcpkg install curl从 vcpkg master 跑了。编译了几分钟,就成功了。然后我转到我的项目并将其链接到 curl,并进行了测试 ftps 传输。这是来自Curls 示例页面的示例

    #include <stdio.h>
    
    #include <curl/curl.h>
    
    /* <DESC>
     * Get a single file from an FTP server.
     * </DESC>
     */ 
    
    struct FtpFile {
      const char *filename;
      FILE *stream;
    };
    
    static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
    {
      struct FtpFile *out = (struct FtpFile *)stream;
      if(out && !out->stream) {
       /* open file for writing */ 
         out->stream = fopen(out->filename, "wb");
        if(!out->stream)
          return -1; /* failure, can't open file to write */ 
      }
      return fwrite(buffer, size, nmemb, out->stream);
    }
    
    
    int main(void)
    {
      CURL *curl;
      CURLcode res;
      struct FtpFile ftpfile = {
        "C:\Users\myUser\Desktop\file.png", /* name to store the file as if successful */ 
        NULL
      };
    
      curl_global_init(CURL_GLOBAL_DEFAULT);
    
      curl = curl_easy_init();
      if(curl) {
        /*
         * You better replace the URL with one that works!
         */ 
        curl_easy_setopt(curl, CURLOPT_URL,
                     "ftp://my.ip.adress.here/path/to/file.png"); //Not actual address
        /* Define our callback to get called when there's data to be written */ 
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
        /* Set a pointer to our struct to pass to the callback */ 
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
    
        /* Switch on full protocol/debug output */ 
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
    
        //Extra options to enable ssl (not included in example)
        curl_easy_setopt(FTPAgent,CURLOPT_USE_SSL,CURLUSESSL_ALL);
        curl_easy_setopt(FTPAgent,CURLOPT_SSL_VERIFYPEER,0L);
        curl_easy_setopt(FTPAgent,CURLOPT_USERNAME,"Username"); //Not actual username
        curl_easy_setopt(FTPAgent,CURLOPT_PASSWORD,"Password"); //Not actual password for obvious reasons
    
        res = curl_easy_perform(curl);
    
        /* always cleanup */ 
        curl_easy_cleanup(curl);
    
        if(CURLE_OK != res) {
          /* we failed */ 
          fprintf(stderr, "curl told us %d\n", res);
        }
      }
    
      if(ftpfile.stream)
        fclose(ftpfile.stream); /* close the local file */ 
    
      curl_global_cleanup();
    
      return 0;
    }
    

    该项目编译并运行,但是当它尝试下载文件时,调试控制台中出现错误,提示 Curl 与 FTPS 协议不兼容。我有意使用显式 FTPS,因为这是我将服务器配置为接受的内容,我可以使用 Mac 上的 Curl 和 Mac 和 Windows 的 FileZilla 的显式 FTPS 连接到它。如果有人知道如何解决这个问题,请lmk。暂时我已经放弃通过 vcpkg 使用 curl

  3. 编译源代码我最后保存了这个,因为我找不到任何构建 Curl 的说明,但最终我找到了这个并按照答案中的说明进行操作,其中使用 curl 的版本来消除任何变量,而不是事实我在 VS2017 而不是 VS2013 上。我第二次这样做时,有人看着我这样做,以确保我正确地执行了所有步骤,所以我大约 90% 确定我正确地执行了这些说明。完成说明后,我使用了与上面相同的代码。它编译并运行没有错误,但是每当我尝试下载任何显着大小的文件时(我不太确定截止值,但 4kb 文件有效而 78kb 文件无效)它说解密数据失败需要更多数据约 20 次然后挂起:

    *   Trying my.ip.adress.here...
    * TCP_NODELAY set
    * Connected to my.ip.adress.here (my.ip.adress.here) port 21 (#0)
    < 220 (vsFTPd 2.2.2)
    > AUTH SSL
    < 234 Proceed with negotiation.
    * schannel: SSL/TLS connection with my.ip.adress.here port 21 (step 1/3)
    * schannel: disabled server certificate revocation checks
    * schannel: using IP address, SNI is not supported by OS.
    * schannel: sending initial handshake data: sending 147 bytes...
    * schannel: sent initial handshake data: sent 147 bytes
    * schannel: SSL/TLS connection with my.ip.adress.here port 21 (step 2/3)
    * schannel: failed to receive handshake, need more data
    * schannel: SSL/TLS connection with my.ip.adress.here port 21 (step 2/3)
    * schannel: encrypted data got 1034
    * schannel: encrypted data buffer: offset 1034 length 4096
    * schannel: a client certificate has been requested
    * schannel: SSL/TLS connection with my.ip.adress.here port 21 (step 2/3)
    * schannel: encrypted data buffer: offset 1034 length 4096
    * schannel: sending next handshake data: sending 349 bytes...
    * schannel: SSL/TLS connection with my.ip.adress.here port 21 (step 2/3)
    * schannel: encrypted data got 250
    * schannel: encrypted data buffer: offset 250 length 4096
    * schannel: SSL/TLS handshake complete
    * schannel: SSL/TLS connection with my.ip.adress.here port 21 (step 3/3)
    * schannel: stored credential handle in session cache
    > USER Username
    * schannel: client wants to read 16384 bytes
    * schannel: encdata_buffer resized 17408
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: encrypted data got 85
    * schannel: encrypted data buffer: offset 85 length 17408
    * schannel: decrypted data length: 34
    * schannel: decrypted data added: 34
    * schannel: decrypted data cached: offset 34 length 16384
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: decrypted data buffer: offset 34 length 16384
    * schannel: schannel_recv cleanup
    * schannel: decrypted data returned 34
    * schannel: decrypted data buffer: offset 0 length 16384
    < 331 Please specify the password.
    > PASS Password
    * schannel: client wants to read 16384 bytes
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: encrypted data got 69
    * schannel: encrypted data buffer: offset 69 length 17408
    * schannel: decrypted data length: 23
    * schannel: decrypted data added: 23
    * schannel: decrypted data cached: offset 23 length 16384
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: decrypted data buffer: offset 23 length 16384
    * schannel: schannel_recv cleanup
    * schannel: decrypted data returned 23
    * schannel: decrypted data buffer: offset 0 length 16384
    < 230 Login successful.
    > PBSZ 0
    * schannel: client wants to read 16384 bytes
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: encrypted data got 69
    * schannel: encrypted data buffer: offset 69 length 17408
    * schannel: decrypted data length: 20
    * schannel: decrypted data added: 20
    * schannel: decrypted data cached: offset 20 length 16384
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: decrypted data buffer: offset 20 length 16384
    * schannel: schannel_recv cleanup
    * schannel: decrypted data returned 20
    * schannel: decrypted data buffer: offset 0 length 16384
    < 200 PBSZ set to 0.
    > PROT P
    * schannel: client wants to read 16384 bytes
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: encrypted data got 69
    * schannel: encrypted data buffer: offset 69 length 17408
    * schannel: decrypted data length: 23
    * schannel: decrypted data added: 23
    * schannel: decrypted data cached: offset 23 length 16384
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: decrypted data buffer: offset 23 length 16384
    * schannel: schannel_recv cleanup
    * schannel: decrypted data returned 23
    * schannel: decrypted data buffer: offset 0 length 16384
    < 200 PROT now Private.
    > PWD
    * schannel: client wants to read 16384 bytes
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: encrypted data got 53
    * schannel: encrypted data buffer: offset 53 length 17408
    * schannel: decrypted data length: 9
    * schannel: decrypted data added: 9
    * schannel: decrypted data cached: offset 9 length 16384
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: decrypted data buffer: offset 9 length 16384
    * schannel: schannel_recv cleanup
    * schannel: decrypted data returned 9
    * schannel: decrypted data buffer: offset 0 length 16384
    < 257 "/"
    * Entry path is '/'
    > CWD path
    * ftp_perform ends with SECONDARY: 0
    * schannel: client wants to read 16384 bytes
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: encrypted data got 85
    * schannel: encrypted data buffer: offset 85 length 17408
    * schannel: decrypted data length: 37
    * schannel: decrypted data added: 37
    * schannel: decrypted data cached: offset 37 length 16384
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: decrypted data buffer: offset 37 length 16384
    * schannel: schannel_recv cleanup
    * schannel: decrypted data returned 37
    * schannel: decrypted data buffer: offset 0 length 16384
    < 250 Directory successfully changed.
    > CWD to
    * schannel: client wants to read 16384 bytes
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: encrypted data got 85
    * schannel: encrypted data buffer: offset 85 length 17408
    * schannel: decrypted data length: 37
    * schannel: decrypted data added: 37
    * schannel: decrypted data cached: offset 37 length 16384
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: decrypted data buffer: offset 37 length 16384
    * schannel: schannel_recv cleanup
    * schannel: decrypted data returned 37
    * schannel: decrypted data buffer: offset 0 length 16384
    < 250 Directory successfully changed.
    > EPSV
    * Connect data stream passively
    * schannel: client wants to read 16384 bytes
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: encrypted data got 101
    * schannel: encrypted data buffer: offset 101 length 17408
    * schannel: decrypted data length: 48
    * schannel: decrypted data added: 48
    * schannel: decrypted data cached: offset 48 length 16384
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: decrypted data buffer: offset 48 length 16384
    * schannel: schannel_recv cleanup
    * schannel: decrypted data returned 48
    * schannel: decrypted data buffer: offset 0 length 16384
    < 229 Entering Extended Passive Mode (|||1040|).
    *   Trying my.ip.adress.here...
    * TCP_NODELAY set
    * Connecting to my.ip.adress.here (my.ip.adress.here) port 1040
    * Connected to my.ip.adress.here (my.ip.adress.here) port 21 (#0)
    > TYPE I
    * schannel: client wants to read 16384 bytes
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: encrypted data got 85
    * schannel: encrypted data buffer: offset 85 length 17408
    * schannel: decrypted data length: 31
    * schannel: decrypted data added: 31
    * schannel: decrypted data cached: offset 31 length 16384
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: decrypted data buffer: offset 31 length 16384
    * schannel: schannel_recv cleanup
    * schannel: decrypted data returned 31
    * schannel: decrypted data buffer: offset 0 length 16384
    < 200 Switching to Binary mode.
    > SIZE file.png
    * schannel: client wants to read 16384 bytes
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: encrypted data got 53
    * schannel: encrypted data buffer: offset 53 length 17408
    * schannel: decrypted data length: 11
    * schannel: decrypted data added: 11
    * schannel: decrypted data cached: offset 11 length 16384
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: decrypted data buffer: offset 11 length 16384
    * schannel: schannel_recv cleanup
    * schannel: decrypted data returned 11
    * schannel: decrypted data buffer: offset 0 length 16384
    < 213 84381
    > RETR file.png
    * schannel: client wants to read 16384 bytes
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: encrypted data got 117
    * schannel: encrypted data buffer: offset 117 length 17408
    * schannel: decrypted data length: 68
    * schannel: decrypted data added: 68
    * schannel: decrypted data cached: offset 68 length 16384
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: decrypted data buffer: offset 68 length 16384
    * schannel: schannel_recv cleanup
    * schannel: decrypted data returned 68
    * schannel: decrypted data buffer: offset 0 length 16384
    < 150 Opening BINARY mode data connection for 001.png (84381 bytes).
    * Maxdownload = -1
    * Getting file with size: 84381
    * Doing the SSL/TLS handshake on the data stream
    * schannel: SSL/TLS connection with my.ip.adress.here port 21 (step 1/3)
    * schannel: re-using existing credential handle
    * schannel: incremented credential handle refcount = 3
    * schannel: using IP address, SNI is not supported by OS.
    * schannel: sending initial handshake data: sending 307 bytes...
    * schannel: sent initial handshake data: sent 307 bytes
    * schannel: SSL/TLS connection with my.ip.adress.here port 21 (step 2/3)
    * schannel: failed to receive handshake, need more data
    * schannel: SSL/TLS connection with my.ip.adress.here port 21 (step 2/3)
    * schannel: encrypted data got 129
    * schannel: encrypted data buffer: offset 129 length 4096
    * schannel: sending next handshake data: sending 75 bytes...
    * schannel: SSL/TLS handshake complete
    * schannel: SSL/TLS connection with my.ip.adress.here port 21 (step 3/3)
    * schannel: client wants to read 16384 bytes
    * schannel: encdata_buffer resized 17408
    * schannel: encrypted data buffer: offset 0 length 17408
    * schannel: encrypted data got 10220
    * schannel: encrypted data buffer: offset 10220 length 17408
    * schannel: failed to decrypt data, need more data
    * schannel: schannel_recv cleanup
    * schannel: client wants to read 16384 bytes
    * schannel: encrypted data buffer: offset 10220 length 17408
    * schannel: encrypted data got 4380
    * schannel: encrypted data buffer: offset 14600 length 17408
    * schannel: failed to decrypt data, need more data
    * schannel: schannel_recv cleanup
    * schannel: client wants to read 16384 bytes
    * schannel: encrypted data buffer: offset 14600 length 17408
    * schannel: encrypted data got 1460
    * schannel: encrypted data buffer: offset 16060 length 17408
    * schannel: decrypted data length: 15872
    * schannel: decrypted data added: 15872
    * schannel: decrypted data cached: offset 15872 length 16384
    * schannel: encrypted data length: 135
    * schannel: encrypted data cached: offset 135 length 17408
    * schannel: failed to decrypt data, need more data
    * schannel: schannel_recv cleanup
    * schannel: decrypted data returned 15872
    * schannel: decrypted data buffer: offset 0 length 16384
    * schannel: client wants to read 16384 bytes
    * schannel: encrypted data buffer: offset 135 length 17408
    * schannel: encrypted data got 16060
    * schannel: encrypted data buffer: offset 16195 length 17408
    * schannel: decrypted data length: 15872
    * schannel: decrypted data added: 15872
    * schannel: decrypted data cached: offset 15872 length 16384
    * schannel: encrypted data length: 270
    * schannel: encrypted data cached: offset 270 length 17408
    * schannel: failed to decrypt data, need more data
    * schannel: schannel_recv cleanup
    * schannel: decrypted data returned 15872
    * schannel: decrypted data buffer: offset 0 length 16384
    * schannel: client wants to read 16384 bytes
    * schannel: encrypted data buffer: offset 270 length 17408
    * schannel: encrypted data got 16060
    * schannel: encrypted data buffer: offset 16330 length 17408
    * schannel: decrypted data length: 15872
    * schannel: decrypted data added: 15872
    * schannel: decrypted data cached: offset 15872 length 16384
    * schannel: encrypted data length: 405
    * schannel: encrypted data cached: offset 405 length 17408
    * schannel: failed to decrypt data, need more data
    * schannel: schannel_recv cleanup
    * schannel: decrypted data returned 15872
    * schannel: decrypted data buffer: offset 0 length 16384
    * schannel: client wants to read 16384 bytes
    * schannel: encrypted data buffer: offset 405 length 17408
    * schannel: encrypted data got 14600
    * schannel: encrypted data buffer: offset 15005 length 17408
    * schannel: failed to decrypt data, need more data
    * schannel: schannel_recv cleanup
    * schannel: client wants to read 16384 bytes
    * schannel: encrypted data buffer: offset 15005 length 17408
    * schannel: encrypted data got 2403
    * schannel: encrypted data buffer: offset 17408 length 17408
    * schannel: decrypted data length: 15872
    * schannel: decrypted data added: 15872
    * schannel: decrypted data cached: offset 15872 length 16384
    * schannel: encrypted data length: 1483
    * schannel: encrypted data cached: offset 1483 length 17408
    * schannel: failed to decrypt data, need more data
    * schannel: schannel_recv cleanup
    * schannel: decrypted data returned 15872
    * schannel: decrypted data buffer: offset 0 length 16384
    * schannel: client wants to read 16384 bytes
    * schannel: encrypted data buffer: offset 1483 length 17408
    * schannel: encrypted data got 15925
    * schannel: encrypted data buffer: offset 17408 length 17408
    * schannel: decrypted data length: 2048
    * schannel: decrypted data added: 2048
    * schannel: decrypted data cached: offset 2048 length 16384
    * schannel: encrypted data length: 15307
    * schannel: encrypted data cached: offset 15307 length 17408
    * schannel: failed to decrypt data, need more data
    * schannel: schannel_recv cleanup
    * schannel: decrypted data returned 2048
    * schannel: decrypted data buffer: offset 0 length 16384
    * schannel: client wants to read 16384 bytes
    * schannel: encrypted data buffer: offset 15307 length 17408
    * schannel: encrypted data got 2101
    * schannel: encrypted data buffer: offset 17408 length 17408
    * schannel: decrypted data length: 16384
    * schannel: decrypted data added: 16384
    * schannel: decrypted data cached: offset 16384 length 16384
    * schannel: encrypted data length: 971
    * schannel: encrypted data cached: offset 971 length 17408
    * schannel: encrypted data buffer: offset 971 length 17408
    * schannel: decrypted data buffer: offset 16384 length 16384
    * schannel: schannel_recv cleanup
    * schannel: decrypted data returned 16384
    * schannel: decrypted data buffer: offset 0 length 16384
    * schannel: client wants to read 2461 bytes
    * schannel: encrypted data buffer: offset 971 length 17408
    * schannel: encrypted data got 1599
    * schannel: encrypted data buffer: offset 2570 length 17408
    * schannel: decrypted data length: 2461
    * schannel: decrypted data added: 2461
    * schannel: decrypted data cached: offset 2461 length 16384
    * schannel: encrypted data length: 53
    * schannel: encrypted data cached: offset 53 length 17408
    * schannel: encrypted data buffer: offset 53 length 17408
    * schannel: decrypted data buffer: offset 2461 length 16384
    * schannel: schannel_recv cleanup
    * schannel: decrypted data returned 2461
    * schannel: decrypted data buffer: offset 0 length 16384
    

    同样,出于显而易见的原因,我用虚拟值替换了 IP、用户名和密码。

笔记:

  1. HTTPS 适用于方法 3(没有尝试使用方法 2,所以我不知道它是否有效) Curl 在我的服务器和谷歌上成功执行了 https 获取请求。
  2. 我假设问题出在我的 curl 安装或我的代码上,但它可能与我的服务器有关,因为我没有另一个 ftps 服务器来测试它。我知道我可以从 Mac 上的 Curl 以及 Mac 和 Windows 上的 Filezilla 使用我的服务器进行 ftps。
  3. 方法2试了3次,方法3试了2次。

如果我可以提供更多信息,请告诉我。感谢您提供的任何帮助。如果我能在一周后完成这项工作,我会很高兴...

标签: c++windowsvisual-studio-2017libcurl

解决方案


推荐阅读