98 lines
2.6 KiB
C
98 lines
2.6 KiB
C
|
#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;
|
|||
|
}
|