[C/C++] HTTP threading mit CURL

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von meister1710, 11. August 2011 .

Schlagworte:
  1. 11. August 2011
    HTTP threading mit CURL

    Mein C bzw Cpp ist ziemlich eingerostet, und wollte mir deshalb seit ner Ewigkeit zum ersten mal wieder selbst was coden.
    Rauskommen sollte n Scanner der Header von HTTP-Servern, rausgekommen ist ne herrausforderung für meinen Denkmuskel ... wobei ich hoffentlich nur den Wald vor lauter Bäumen nicht seh.

    Ziel sollte sein, das ein B-Netz angegeben wird und mit nem OPTIONS Request die Header ausgelesen werden. Faul wie man nun mal ist, dachte ich mir, ich jag da einfach 255 Threads durch um großartiges Konvertieren der IP zu umgehen und erstmal umgeh ich die Sockets und nutze libcurl.

    Pustekuchen ... Singlethreaded läufts, und multithreadpart hab ich durch einfaches ausgeben von nem text auch schon gegen gecheckt. Hab ichs mir doch zu einfach machen wollen.
    Fehler ist ne Speicherzugriffsverletzung. Mutex anders gesetzt/größeren Bereich reingenommen, nix. Immer noch das selbe.
    WRITEFUNCTION von libcurl sollte schon durch das setzen des Mutex autonom sein und nur von einem Thread angesprochen werden. Will nicht den Umweg machen und den Header auf die Platte schreiben. Dadurch würde das weiterverarbeiten der DAten nur unnütz Zeit und Ressourcen in Anspruch nehmen.

    an Compilern nutz ich cygwin oder mingw, aber bei beiden das selbe in grün.


    genutzte libs: libcurl und pthreads

    hier mal der Übeltäter in Form des Sourcecode (Auszug da noch andere Komponenten drin sind, will ja keinen mit der Source erschlagen):
    Code:
    
    using namespace std;
    
    pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
    
    int writer(char *data, size_t size, size_t nmemb, string *buffer){
     int result = 0;
     if(buffer != NULL) {
     buffer -> append(data, size * nmemb);
     result = size * nmemb;
     }
     return result;
    }
    
    
    void *grab_header(void *url)
    {
     string buffer;
     char *urlgrab = (char *)url;
     pthread_mutex_lock(&mutex1);
     CURL *hnd = curl_easy_init();
     curl_easy_setopt(hnd, CURLOPT_URL, urlgrab);
     curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1);
     curl_easy_setopt(hnd, CURLOPT_NOBODY, 1L);
     curl_easy_setopt(hnd, CURLOPT_HEADER, 1L);
     curl_easy_setopt(hnd, CURLOPT_USERAGENT, "Gimme your head ...");
     curl_easy_setopt(hnd, CURLOPT_FILETIME, 0);
     curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
     curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "OPTIONS");
     curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, writer);
     curl_easy_setopt(hnd, CURLOPT_WRITEDATA, &buffer );
     pthread_mutex_unlock(&mutex1);
     curl_easy_perform(hnd);
     curl_easy_cleanup(hnd);
     ...
     verschiedene Stringoperationen auf den header
     ...
     return(0);
    }
    
    int main(int argc, char *argv[])
    {
     ...
     andere funktionierende funktionen
     ...
     if(argc==2)
     {
     pthread_t threadid[255];
     int i1, i2, threadstartcheck;
     char *createipthread;
     curl_global_init(CURL_GLOBAL_ALL);
     for(i1=0;i1<=255;i1++)
     {
     for(i2=1;i1<=255;i1++)
     {
     sprintf(createipthread, "http://%s%i.%i:80", argv[1], i1, i2);
     threadstartcheck=pthread_create(&threadid[i2], NULL, grab_header, (void *)createipthread);
     if(threadstartcheck!=0)
     {
     printf("Konnte Thread %i fuer %s nicht erstellen\n", i2, createipthread);
     }
     }
     for(i2=1;i1<=255;i1++)
     {
     pthread_join(threadid[i2], NULL);
     }
     }
     }
     ...
     restliches programm
     ...
     return(0);
    }
    
    
    Auch wenn mein Code nicht zu 100% sauber ist, bzw vielleicht was umständlich gecodet ist, ist der code selber lauffähig. der libcurl-part als stand alone und der threaded part ohne libcurl laufen. Füg ich beides zusammen, wirds sauber compiled, aber läuft auf Fehler.
    Entweder liegts an meiner Funktion "writer" oder daran das ich Mist mit dem mutex gebaut hab.

    Compilerbefehl war:
    g++ main.cpp -c
    g++ main.o -o main.exe -lpthread -llibcurl -D_REENTRANCE

    Will keine Ratschläge im Sinne von "benutzt doch das und das" sondern wissen, wo ich Mist gebaut hab, damit mir so n Fehler nicht nochmal passiert.

    So, dann mal her mit den Ratschlägen, Tiefschlägen, usw.
     
  2. 11. August 2011
    AW: Hilfe beim threading ... was läuft hier falsch?

    Hallo!

    Meine erste Vermutung (bin in die gleiche "Falle" getappt) ist, dass du CURLOPT_NOSIGNAL nicht auf TRUE (1L) gesetzt hast.

    Quelle: libcurl - curl_easy_setopt() - BEHAVIOR OPTIONS / CURLOPT_NOSIGNAL

    Quelle: libcurl - programming tutorial - Multi-threading Issues

    Mfg,

    Kolazomai
     
  3. 12. August 2011
    AW: Hilfe beim threading ... was läuft hier falsch?

    Danke, aber Lösung war viel trivialer, nachdem ich mich gestern Stundenlang damit rumgeschlagen hab, hab ich festgestellt, das ich depp dem Linker falsche Parameter übergeben hab. Anstelle von pthread hat der auf pthreadGC2 (Bloodsheed DEV-C++ mit MinGW/CygWin) gelinkt -> geändert und lief. fiel erst auf, nachdem ich das ganze auf ner Linux-Bash laufen lies, dabei fiel mir dann noch ein typischer copy&paste Fehler auf:

    Code:
    for(i2=1;i1<=255;i1++)
    {
    ...
    }
    for(i2=1;i1<=255;i1++)
    {
    ...
    }
    
    wobei hier die Schleife ja falsch läuft und falsch hochzählt, es müsste heissen ...


    Code:
    for(i1=1;i1<=255;i1++)
    {
    ...
    }
    for(i2=1;i2<=255;i2++)
    {
    ...
    }
    
    Was ja zu fehlern führt, wenn der Variable vorher kein Wert zugewiesen wurde.
    Aber der Tip mit NOSIGNAL ist nicht verkehrt, wäre wahrscheinlich der nächste Fehler gewesen :-D

    Ist wahrscheinlich ein ungeschriebenes Gesetz, das man sich Stunden lang mit nem Fehler auseinandersetzt, keine Lösung findet, und sobald man sich Support erfragt, fällt einem kurz darauf die Lösung in den Schoß.

    Auf jeden Fall Danke für die Mühe!
     
  4. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.