Ich habe meinen Kopf darüber stundenlang kratzen, ich versuche, meine Struktur von CURLINFO_PRIVATE zugreifen, aber gcc scheint es nicht als eine Struktur zu erkennen: esWie Zugriff auf Struktur mit CURLINFO_PRIVATE in libcurl?
10-at-a-time.c: In function 'main':
10-at-a-time.c:148:48: error: request for member 'size' in something not a structure or union
printf("%lu bytes retrieved\n", (long)chunk->size);
^
10-at-a-time.c:152:15: error: request for member 'memory' in something not a structure or union
free(chunk->memory);
In der Libcurl Dokumentation sagt Es gibt einen char-Zeiger zurück: https://curl.haxx.se/libcurl/c/CURLINFO_PRIVATE.html
Soweit ich verstanden habe, sollte ich in der Lage sein, diesen Zeiger mit der "->" Syntax zu dereferenzieren und die Struktur Instanz zu bekommen. Aber das scheint nicht zu funktionieren.
Hier ist mein Code, ich hoffe, es ist leicht zu verstehen: btw
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <curl/multi.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;
mem->memory = realloc(mem->memory, mem->size + realsize + 1);
if(mem->memory == NULL) {
/* out of memory! */
printf("not enough memory (realloc returned NULL)\n");
return 0;
}
memcpy(&(mem->memory[mem->size]), contents, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
return realsize;
}
static const char *urls[] = {
"http://www.microsoft.com",
"http://www.opensource.org",
"http://www.google.com",
"http://www.bbc.co.uk",
"http://www.newslink.org",
"http://www.un.org",
"http://www.news.com",
"http://www.cnn.com",
"http://www.wikipedia.org",
"http://www.dell.com",
"http://www.hp.com",
"http://www.cert.org",
"http://www.mit.edu",
"http://www.nist.gov",
"http://www.ebay.com",
"http://www.playstation.com",
"http://www.uefa.com",
"http://www.ieee.org",
"http://www.apple.com",
"http://www.symantec.com"
};
#define count sizeof(urls)/sizeof(char*)
static void init(CURLM *cm, int i)
{
CURL *eh = curl_easy_init();
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_easy_setopt(eh, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(eh, CURLOPT_WRITEDATA, (void *)&chunk);
curl_easy_setopt(eh, CURLOPT_HEADER, 0L);
curl_easy_setopt(eh, CURLOPT_URL, urls[i]);
curl_easy_setopt(eh, CURLOPT_PRIVATE, (void *)&chunk);
curl_easy_setopt(eh, CURLOPT_VERBOSE, 0L);
curl_multi_add_handle(cm, eh);
}
int main(void)
{
int bots = 10;
if (count < bots) {
bots = count;
}
CURLM *cm;
CURLMsg *msg;
long L;
struct timeval timeout;
unsigned int current = 0;
int msg_queue = -1;
int handles = -1;
int maxfd = -1;
fd_set fdread;
fd_set fdwrite;
fd_set fdexcep;
curl_global_init(CURL_GLOBAL_ALL);
cm = curl_multi_init();
curl_multi_setopt(cm, CURLMOPT_MAXCONNECTS, (long)bots);
for (current = 0; current < bots; ++current) {
init(cm, current);
}
while (handles) {
curl_multi_perform(cm, &handles);
if (handles) {
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);
if (curl_multi_fdset(cm, &fdread, &fdwrite, &fdexcep, &maxfd)) {
fprintf(stderr, "E: curl_multi_fdset\n");
return EXIT_FAILURE;
}
if (curl_multi_timeout(cm, &L)) {
fprintf(stderr, "E: curl_multi_timeout\n");
return EXIT_FAILURE;
}
if (L == -1) {
L = 100;
}
if (maxfd == -1) {
sleep((unsigned int)L/1000);
}
else {
timeout.tv_sec = L/1000;
timeout.tv_usec = (L % 1000) * 1000;
if (0 > select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout)) {
fprintf(stderr, "E: select(%i,,,,%li): %i: %s\n", maxfd + 1, L, errno, strerror(errno));
return EXIT_FAILURE;
}
}
}
while ((msg = curl_multi_info_read(cm, &msg_queue))) {
if (msg->msg == CURLMSG_DONE) {
char *chunk;
CURL *e = msg->easy_handle;
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &chunk);
fprintf(stderr, "R: %d - %s\n", msg->data.result, curl_easy_strerror(msg->data.result));
printf("%lu bytes retrieved\n", (long)chunk->size);
curl_multi_remove_handle(cm, e);
curl_easy_cleanup(e);
free(chunk->memory);
}
else {
fprintf(stderr, "E: CURLMsg (%d)\n", msg->msg);
}
if (current < count) {
init(cm, current++);
handles++;
}
}
}
curl_multi_cleanup(cm);
curl_global_cleanup();
return EXIT_SUCCESS;
}
Ich bin neu in C.
Vielen Dank Daniel, das funktioniert perfekt. Ich dachte nicht, dass es so einfach wäre :) – sasha