/*
* 這個例子說明如何寫Libcurl中的Callback 程式,這Callback將把 URL回傳的資料,放到記憶體當中。
* Shows how the write callback function can be used to download data into a
* chunk of memory instead of storing it in a file.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
struct MemoryStruct {
char *memory;
size_t size;
};
/*
這個例子的就是存取一個URL,傳回內容與CONTENT SIZE。
size_t callback_function( void *ptr, size_t size, size_t nmemb, void *stream);
這函數將在libcurl接收到數據後被調用,用來儲存http送回的資料。
程式在處理回傳資料最難的就是不知道回傳的資料量有多少? 所以記憶體也不知道要需告多大。所以就設計了這個Callback。
*ptr 是一快記憶體空間,裡面放著 http 傳回的資訊。
size :說明 Contents 所指到的記憶體有多大?
memb :這是一個有趣的參數,因為網路上每個字的單位有多大? 所以利用這個變數來做通知 Callback。實際的記憶體SIZE = size * memb
userp:這個參數主要回傳一個應用程式可以使用的資料結構,
struct MemoryStruct {
char *memory;
size_t size;
};
*memory 之中放著由 ptr 送進來的 HTTP 回傳的資料。
size 是 memory 的 SIZER。
CURLOPT_WRITEDATA用於表明CURLOPT_WRITEFUNCTION函數中的stream指針的來源。
如果你沒有通過CURLOPT_WRITEFUNCTION屬性给easy handle設置回調函數,libcurl會提供一個預設的回調函數,它只是簡單的將接收到的數據印到標准輸出。
你也可以通過 CURLOPT_WRITEDATA屬性之中的Callback,將資訊寫到記憶體之中,傳給Libcurl,然後透過 HTTP傳送出去。
*/
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);
/*
將curl Library進行初始化,init the curl session
*/
curl_handle = curl_easy_init();
/*
設定要存取的URL
*/
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
chunk 就會傳給 WriteMemoryCallback 之中的第四個參數 userp
*/
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
/*
這一行如果不寫,有時有問題,有的SERVER會有問題,所以務必要寫
*/
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
/* get it down ! */
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;
}
* 這個例子說明如何寫Libcurl中的Callback 程式,這Callback將把 URL回傳的資料,放到記憶體當中。
* Shows how the write callback function can be used to download data into a
* chunk of memory instead of storing it in a file.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
struct MemoryStruct {
char *memory;
size_t size;
};
/*
這個例子的就是存取一個URL,傳回內容與CONTENT SIZE。
size_t callback_function( void *ptr, size_t size, size_t nmemb, void *stream);
這函數將在libcurl接收到數據後被調用,用來儲存http送回的資料。
程式在處理回傳資料最難的就是不知道回傳的資料量有多少? 所以記憶體也不知道要需告多大。所以就設計了這個Callback。
*ptr 是一快記憶體空間,裡面放著 http 傳回的資訊。
size :說明 Contents 所指到的記憶體有多大?
memb :這是一個有趣的參數,因為網路上每個字的單位有多大? 所以利用這個變數來做通知 Callback。實際的記憶體SIZE = size * memb
userp:這個參數主要回傳一個應用程式可以使用的資料結構,
struct MemoryStruct {
char *memory;
size_t size;
};
*memory 之中放著由 ptr 送進來的 HTTP 回傳的資料。
size 是 memory 的 SIZER。
CURLOPT_WRITEDATA用於表明CURLOPT_WRITEFUNCTION函數中的stream指針的來源。
如果你沒有通過CURLOPT_WRITEFUNCTION屬性给easy handle設置回調函數,libcurl會提供一個預設的回調函數,它只是簡單的將接收到的數據印到標准輸出。
你也可以通過 CURLOPT_WRITEDATA屬性之中的Callback,將資訊寫到記憶體之中,傳給Libcurl,然後透過 HTTP傳送出去。
*/
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);
/*
將curl Library進行初始化,init the curl session
*/
curl_handle = curl_easy_init();
/*
設定要存取的URL
*/
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
chunk 就會傳給 WriteMemoryCallback 之中的第四個參數 userp
*/
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
/*
這一行如果不寫,有時有問題,有的SERVER會有問題,所以務必要寫
*/
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
/* get it down ! */
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;
}
沒有留言:
張貼留言