libcurl: Manchmal "unhandled exception" bei download
-
Hey!
In seltenen Fällen bekomme ich eine unhandled exception, wenn ich mit libcurl etwas downloaden möchte.
Hier der Code:int OnDownloadWrite(char* data, unsigned int size, unsigned int nmemb, std::string* buffer) { int returnValue = 0; if(buffer) { buffer->append(data, size * nmemb); returnValue = size * nmemb; } return returnValue; } // main() string data1, data2; void* easyDownloadHandles[2]; easyDownloadHandles[0] = curl_easy_init(); easyDownloadHandles[1] = curl_easy_init(); void* multiDownloadHandle = curl_multi_init(); curl_easy_setopt(easyDownloadHandles[0], CURLOPT_URL, "http://www.***.com/file.zip"); curl_easy_setopt(easyDownloadHandles[0], CURLOPT_WRITEFUNCTION, OnDownloadWrite); curl_easy_setopt(easyDownloadHandles[0], CURLOPT_WRITEDATA, &data1); curl_easy_setopt(easyDownloadHandles[1], CURLOPT_URL, "http://www.***.com/file2.zip"); curl_easy_setopt(easyDownloadHandles[1], CURLOPT_WRITEFUNCTION, OnDownloadWrite); curl_easy_setopt(easyDownloadHandles[1], CURLOPT_WRITEDATA, &data2); curl_multi_add_handle(multiDownloadHandle, easyDownloadHandles[0]); curl_multi_add_handle(multiDownloadHandle, easyDownloadHandles[1]); int running = true; while(running) { while(curl_multi_perform(multiDownloadHandle, &running) == CURLM_CALL_MULTI_PERFORM); timeval timeoutVal = { 8 }; fd_set readFileDescriptor; fd_set writeFileDescriptor; fd_set exceptionFileDescriptor; FD_ZERO(&readFileDescriptor); FD_ZERO(&writeFileDescriptor); FD_ZERO(&exceptionFileDescriptor); int maxFileDescriptors; if(curl_multi_fdset(multiDownloadHandle, &readFileDescriptor, &writeFileDescriptor, &exceptionFileDescriptor, &maxFileDescriptors)) break; if(maxFileDescriptors > -1) { int result = select(maxFileDescriptors + 1, &readFileDescriptor, &writeFileDescriptor, &exceptionFileDescriptor, &timeoutVal); if(result == -1) break; } else Sleep(100); } curl_multi_cleanup(multiDownloadHandle); curl_easy_cleanup(easyDownloadHandles[0]); curl_easy_cleanup(easyDownloadHandles[1]);
Was mache ich falsch? Es funktioniert meistens, aber manchmal nicht:
http://www.bilder-hochladen.net/files/bq9q-5-jpg.html
Danke!
MfG
-
^^lass es im debugger laufen. der hält an, wenn die exception auftritt.
-
Hält an genau derselben Stelle mit:
ptd 0x0054a388 _tiddata *
_initaddr 0x00474b60 void *
_initarg 0x00549b50 void *
-
Amboss der Rabiator schrieb:
Hält an genau derselben Stelle mit:
ptd 0x0054a388 _tiddata *
_initaddr 0x00474b60 void *
_initarg 0x00549b50 void *wo im quelltext iss'n das? du musst die stelle im source code finden, wo das passiert.
-
Genau dort, wie man es auf dem Bild sieht.
(Im file threadex.c)
-
Amboss der Rabiator schrieb:
Genau dort, wie man es auf dem Bild sieht.
(Im file threadex.c)ok, dann mach 'nen backtrace, also rückwärts steppen bis du in dem von dir geschriebenen code bist.
-
Wie "backtrace" ich denn (VS 2008)?
Ist es "Step Out" (Shift+F11)?Danke für deine Geduld.
-
Mist!
Das Problem scheint bekannt zu sein.
Deshalb hasse ich es, externe libs zu benutzen. 100.000 Funktionen aber beinahe unbrauchbar jetzt, der Glump...Workaround ist, maximal ein easy-handle zum mutli-handle hinzuzufügen, sprich maximal eine Datei gleichzeitig runterzuladen.
(Das Problem liegt angeblich im gleichzeitigen internen host-resolve).Kennt ihr vllt. ne Alternative zu libcurl?
-
Amboss der Rabiator schrieb:
Kennt ihr vllt. ne Alternative zu libcurl?
naja, direkt mit sockets. 'nen HTTP-request abschicken und die zurückkommenden daten einsammeln. ist eigentlich garnicht so schwer. beispiel (getestet unter VS 2005):
#include <windows.h> #include <stdio.h> #pragma comment (lib, "ws2_32.lib") void bye (char *s) { printf ("abort due to error in: %s\n", s); exit(0); } int main() { WSADATA wsa; SOCKET sock; SOCKADDR_IN sin; char *req = "GET /cms/index.php HTTP/1.0\r\n\r\n"; if (0 != WSAStartup (MAKEWORD(2,0), &wsa)) bye ("WSAStartup"); sock = socket (AF_INET, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) bye ("socket"); memset (&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = inet_addr ("87.106.19.147"); // www.c-plusplus.net sin.sin_port = htons(80); if (SOCKET_ERROR == connect (sock, (struct sockaddr*)&sin, sizeof(sin))) bye ("connect"); if (SOCKET_ERROR == send (sock, req, (int)strlen(req), 0)) bye ("send"); // daten abholen und alles anzeigen for (;;) { char buff[1024]; int s; int r = recv (sock, buff, sizeof(buff), 0); if (r == 0 || r == SOCKET_ERROR) // verbindung vom server zugemacht oder abbruch? break; for (s=0; s<r; s++) putchar (buff[s]); } printf ("\n-- fertig ---\n"); }