#include "ip.h" 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) { /* 内存不足! */ 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; } // 获取公网IP char *GET_PUBLIC_IP(char *URL) { CURL *curl_handle; CURLcode res; struct curl_slist *headers = NULL; struct MemoryStruct chunk; chunk.memory = malloc(1); /* 将根据上述再分配的需要增长 */ chunk.size = 0; /* 此时没有数据 */ curl_global_init(CURL_GLOBAL_ALL); /* 初始化curl会话 */ curl_handle = curl_easy_init(); char *p = NULL; char *buff; p = strstr(URL, "-H"); if (p) { buff = (char *)alloca(p - URL + 1); if (buff == NULL) perror("out of memory."); memset(buff, 0, p - URL + 1); memcpy(buff, URL, (int)(p - URL - 1)); // 赋值header值 headers = curl_slist_append(headers, p + 3); // 设置header curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl_handle, CURLOPT_URL, buff); } else { /* 指定要获取的URL */ curl_easy_setopt(curl_handle, CURLOPT_URL, URL); } /* 将所有数据发送到此函数 */ //对于同一次阻塞的curl_easy_perform而言,在写完获取的数据之前,会多次调用 WriteMemoryCallback curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); /* 将"chunk"结构传递给回调函数 */ curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk); curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0"); //对于同一次阻塞的curl_easy_perform而言,在写完获取的数据之前,会多次调用 WriteMemoryCallback res = curl_easy_perform(curl_handle); if (res != CURLE_OK) { fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); } else { //printf("%lu bytes retrieved\n", (unsigned long)chunk.size); //printf("%s", chunk.memory); ; } curl_easy_cleanup(curl_handle); curl_global_cleanup(); return chunk.memory; }