簡體   English   中英

C++ [Libcurl] 從 php 服務器下載文件並將其保存到 memory

[英]C++ [Libcurl] Downloading a file from a php server and save it on memory

您好,我正在嘗試使用從我的 php 文件中檢索的 libcurl 下載文件,該文件檢查用戶是否在檢索下載文件之前登錄 c++ 客戶端,問題是客戶端永遠無法到達下載文件以將其保存到 ZCD69B49357F06BDE8198D7而不是將它寫入磁盤我能做什么? 我正在使用此示例進行測試。 我還需要補充一點,我已經測試過無需登錄即可直接下載文件,一切都很好,但登錄大小永遠為 0,我永遠無法訪問該文件。 提前致謝。

    struct MemoryStruct {
  char *memory;
  size_t size;
};

static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;

  char *ptr = realloc(mem->memory, mem->size + realsize + 1);
  if(ptr == NULL) {
    /* out of memory! */ 
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }

  mem->memory = ptr;
  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;

  return realsize;
}

int main(void)
{
  CURL *curl_handle;
  CURLcode res;

  struct MemoryStruct chunk;

  chunk.memory = malloc(1);  /* will be grown as needed by the realloc above */ 
  chunk.size = 0;    /* no data at this point */ 

  curl_global_init(CURL_GLOBAL_ALL);

  /* init the curl session */ 
  curl_handle = curl_easy_init();

  /* specify URL to get */ 
  curl_easy_setopt(curl_handle, CURLOPT_URL, "https://www.example.com/");

  /* send all data to this function  */ 
  curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);

  /* we pass our 'chunk' struct to the callback function */ 
  curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);

  /* some servers don't like requests that are made without a user-agent
     field, so we provide one */ 
  curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");

  /* get it! */ 
  res = curl_easy_perform(curl_handle);

  /* check for errors */ 
  if(res != CURLE_OK) {
    fprintf(stderr, "curl_easy_perform() failed: %s\n",
            curl_easy_strerror(res));
  }
  else {
    /*
     * Now, our chunk.memory points to a memory block that is chunk.size
     * bytes big and contains the remote file.
     *
     * Do something nice with it!
     */ 

    printf("%lu bytes retrieved\n", (unsigned long)chunk.size);
  }

  /* cleanup curl stuff */ 
  curl_easy_cleanup(curl_handle);

  free(chunk.memory);

  /* we're done with libcurl, so clean it up */ 
  curl_global_cleanup();

  return 0;
}

php 代碼是這個

$path = '../file.dll';

                    if (file_exists($path))
                    {
                        $mm_type="application/octet-stream";
                        header("Pragma: public");
                        header("Expires: 0");
                        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
                        header("Cache-Control: public");
                        header("Content-Description: File Transfer");
                        header("Content-Type: " . $mm_type);
                        header("Content-Length: " .(string)(filesize($path)) );
                        header('Content-Disposition: attachment; filename="'.basename($path).'"');
                        header("Content-Transfer-Encoding: binary\n");
                        readfile($path);
                        }

php片段中很難說,但我會添加選項以跟蹤重定向並打開詳細模式,以便能夠更詳細地跟蹤libcurl所做的事情。 我還將刪除所有手動 memory 管理。 你所做的一切都可以用一個簡單的std::string代替。

此示例適用於您發送的php但我無法測試您提到的登錄內容:

#include <curl/curl.h>

#include <iostream>
#include <sstream>
#include <string>

static size_t WriteMemoryCallback(void* contents, size_t size, size_t nmemb,
                                  void* userp) {
    size_t realsize = size * nmemb;
    auto& mem = *static_cast<std::string*>(userp);
    mem.append(static_cast<char*>(contents), realsize);
    return realsize;
}

int main(void) {
    CURL* curl_handle;
    CURLcode res;

    std::string chunk;

    curl_global_init(CURL_GLOBAL_ALL);

    curl_handle = curl_easy_init();
    curl_easy_setopt(curl_handle, CURLOPT_URL, "https://www.example.com/");
    curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
    curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &chunk);
    curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");

    // added options that may be required
    curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);  // redirects
    curl_easy_setopt(curl_handle, CURLOPT_HTTPPROXYTUNNEL, 1L); // corp. proxies etc.
    curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L); // we want it all
    // curl_easy_setopt(curl_handle, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);

    res = curl_easy_perform(curl_handle);

    if(res != CURLE_OK) {
        std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << '\n';
    } else {
        std::cout << chunk.size() << " bytes retrieved\n";
    }

    curl_easy_cleanup(curl_handle);
    curl_global_cleanup();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM