libcurlの実用例

5785 ワード

公式の例:https://curl.haxx.se/libcurl/c/example.html実際、統合して使用する場合は1.ブロックされていないので、いつでもキャンセルするのに便利です.進捗を見る3.ダウンロード
他のものはしばらくくわえていません.公式サイトの例を融合して、自分で作ったテストコードは以下のようにして、パッケージを変更して使用することができます:

#include "stdio.h"
#include "stdlib.h"
#include "string.h"

#ifdef _WIN32
#define WAITMS(x) Sleep(x)
#else
/* Portable sleep for platforms other than Windows. */
#define WAITMS(x)                               \ 
struct timeval wait = { 0, (x) * 1000 };      \
	(void)select(0, NULL, NULL, NULL, &wait);
#endif


#define HTTPURL "http://abc.efg.com/ddd.php"

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

static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
	printf("WriteMemoryCallback
"); size_t realsize = size * nmemb; struct MemoryStruct *mem = (struct MemoryStruct *)userp; size_t totolsize = realsize + mem->size; if (mem->length < totolsize) { char *ptr = (char*)realloc(mem->memory, totolsize); if (ptr == NULL) { /* out of memory! */ printf("not enough memory (realloc returned NULL)
"); return 0; } mem->memory = ptr; } memcpy(&(mem->memory[mem->size]), contents, realsize); mem->size = totolsize; //mem->memory[mem->size] = 0; return realsize; } #define TIME_IN_US 1 #define TIMETYPE curl_off_t #define TIMEOPT CURLINFO_TOTAL_TIME_T #define MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL 3000000 #define STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES 600000000 struct myprogress { TIMETYPE lastruntime; /* type depends on version, see above */ CURL *curl; }; /* this is how the CURLOPT_XFERINFOFUNCTION callback works */ static int xferinfo(void *p, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow) { //printf("xferinfo
"); struct myprogress *myp = (struct myprogress *)p; CURL *curl = myp->curl; TIMETYPE curtime = 0; curl_easy_getinfo(curl, TIMEOPT, &curtime); /* under certain circumstances it may be desirable for certain functionality to only run every N seconds, in order to do this the transaction time can be used */ if ((curtime - myp->lastruntime) >= MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL) { myp->lastruntime = curtime; #ifdef TIME_IN_US fprintf(stderr, "TOTAL TIME: %" CURL_FORMAT_CURL_OFF_T ".%06ld\r
", (curtime / 1000000), (long)(curtime % 1000000)); #else fprintf(stderr, "TOTAL TIME: %f \r
", curtime); #endif } fprintf(stderr, "UP: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T " DOWN: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T "\r
", ulnow, ultotal, dlnow, dltotal); if (dlnow > STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES) return 1; return 0; } #define INIT_SIZE (1024*1024) /* * Simply download a HTTP file. */ int main(void) { CURL *http_handle; CURLM *multi_handle; int still_running = 0; /* keep number of running handles */ int repeats = 0; struct MemoryStruct chunk; chunk.memory = (char*)malloc(INIT_SIZE); /* will be grown as needed by the realloc above */ chunk.size = 0; /* no data at this point */ chunk.length = INIT_SIZE; curl_global_init(CURL_GLOBAL_DEFAULT); http_handle = curl_easy_init(); /* set the options (I left out a few, you'll get the point anyway) */ curl_easy_setopt(http_handle, CURLOPT_URL, HTTPURL); /* some servers don't like requests that are made without a user-agent field, so we provide one */ curl_easy_setopt(http_handle, CURLOPT_USERAGENT, "live95xiu"); /* send all data to this function */ curl_easy_setopt(http_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); /* we pass our 'chunk' struct to the callback function */ curl_easy_setopt(http_handle, CURLOPT_WRITEDATA, (void *)&chunk); struct myprogress prog; prog.lastruntime = 0; prog.curl = http_handle; curl_easy_setopt(http_handle, CURLOPT_XFERINFOFUNCTION, xferinfo); /* pass the struct pointer into the xferinfo function, note that this is an alias to CURLOPT_PROGRESSDATA */ curl_easy_setopt(http_handle, CURLOPT_XFERINFODATA, &prog); curl_easy_setopt(http_handle, CURLOPT_NOPROGRESS, 0L); /* init a multi stack */ multi_handle = curl_multi_init(); /* add the individual transfers */ curl_multi_add_handle(multi_handle, http_handle); /* we start some action by calling perform right away */ curl_multi_perform(multi_handle, &still_running); while (still_running) { CURLMcode mc; /* curl_multi_wait() return code */ int numfds; /* wait for activity, timeout or "nothing" */ mc = curl_multi_wait(multi_handle, NULL, 0, 1000, &numfds); if (mc != CURLM_OK) { fprintf(stderr, "curl_multi_wait() failed, code %d.
", mc); break; } /* 'numfds' being zero means either a timeout or no file descriptors to wait for. Try timeout on first occurrence, then assume no file descriptors and no file descriptors to wait for means wait for 100 milliseconds. */ if (!numfds) { repeats++; /* count number of repeated zero numfds */ if (repeats > 1) { WAITMS(100); /* sleep 100 milliseconds */ } } else repeats = 0; curl_multi_perform(multi_handle, &still_running); } curl_multi_remove_handle(multi_handle, http_handle); curl_easy_cleanup(http_handle); curl_multi_cleanup(multi_handle); curl_global_cleanup(); FILE *savefile; /* open the file */ errno_t err = fopen_s(&savefile,"savefile", "wb"); size_t written = fwrite(chunk.memory, 1, chunk.size, (FILE *)savefile); /* close the header file */ fclose(savefile); free(chunk.memory); return 0; }