[C/C++] Mit Curl mehrfach Downloaden

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von space24, 10. April 2009 .

  1. 10. April 2009
    Mit Curl mehrfach Downloaden

    Hi Leute

    Ich habe vor kurzem nochmal mit C/C++ angefangen und wollte mir jetzt mal ein Tool schreiben um meinen Root bzw. die Shoutcast Server darauf zu testen.

    Das Prog soll mit Curl immer den Stream als Download anfordern und sofort speichern, dass klappt auch aber ich bekomm immer nur 1 Download gleichzeitig ans laufen, weil Curl mit dem Download das ganze Programm blockiert.

    Für meinen ersten Test hab ich mich ans Curl Beispiel gehalten.

    Code:
     #include <stdio.h>
     
     #include <curl/curl.h>
     #include <curl/types.h>
     #include <curl/easy.h>
     
     struct FtpFile {
     const char *filename;
     FILE *stream;
     };
     
     static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
     {
     struct FtpFile *out=(struct FtpFile *)stream;
     if(out && !out->stream) {
     /* open file for writing */
     out->stream=fopen(out->filename, "wb");
     if(!out->stream)
     return -1; /* failure, can't open file to write */
     }
     return fwrite(buffer, size, nmemb, out->stream);
     }
     
     
     int main(void)
     {
     int i;
     
     for(i=1; i < 10; i++)
    
     CURL *curl;
     CURLcode res;
     struct FtpFile ftpfile={
     "curl.mp3", /* name to store the file as if succesful */
     NULL
     };
     
     curl_global_init(CURL_GLOBAL_DEFAULT);
     
     curl = curl_easy_init();
     if(curl) {
    
     curl_easy_setopt(curl, CURLOPT_URL,
     "http://STREAMADRESSE");
     /* Define our callback to get called when there's data to be written */
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
     /* Set a pointer to our struct to pass to the callback */
     curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
     
     // curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
    
     struct curl_slist *slist=NULL;
    
     slist = curl_slist_append(slist, "GET / HTTP/1.0\r\n");
     slist = curl_slist_append(slist, "Host: STREAMADRESSE\r\n");
     slist = curl_slist_append(slist, "User-Agent: WinampMPEG/2.8\r\n");
     slist = curl_slist_append(slist, "Accept: */*\r\n");
     slist = curl_slist_append(slist, "Icy-MetaData:0\r\n");
     slist = curl_slist_append(slist, "Connection: close\r\n\r\n ");
     
    
     
     
     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist); 
     
     res = curl_easy_perform(curl);
    
     curl_easy_cleanup(curl);
     
     if(CURLE_OK != res) {
     /* we failed */
     fprintf(stderr, "curl told us %d\n", res);
     }
     }
     
     if(ftpfile.stream)
     fclose(ftpfile.stream); /* close the local file */
     
     curl_global_cleanup();
     
     return 0;
     }
     
    Weis einer wie ich das Programm dazu bringen kann meherere Downloads gleichzeitig zu laden?


    Gruß Space
     
  2. 10. April 2009
    AW: Mit Curl mehrfach Downloaden

    Die erste Möglichkeit wäre, das curl-Multi-Interface (libcurl - multi interface overview) zu benutzen.

    Die zweite Möglichkeit wären Threads, unter Windows gäbe es da die CreateThread()-Funktion, unter Unix pthread_create() oder so ähnlich ^^
     
  3. 10. April 2009
    AW: Mit Curl mehrfach Downloaden

    Hi

    Haste vielleicht ein Beispiel für libcurl - multi interface overview ?
    Auf der Curl Seite gibts nur nen Beispiel mit der Funktion pthread_create, aber ich möchte das ganze gerne Plattformunabhängig haben...


    Gruß Space
     
  4. 11. April 2009
    AW: Mit Curl mehrfach Downloaden

    Die Read Funktion von Curl musste an eine weitere von dir weitergeben (kannst du per curl_easy_setup machen), dann kannst du das ganze auch per easy-lib lösen.

    PS: Komme gerade von 'ner Party, also net übel nehmen ^^ :d
     
  5. 11. April 2009
    AW: Mit Curl mehrfach Downloaden

    Hey!

    Geht nur mit Threads oder dem Multi-Interface.
    Ich wuerde das Multi-Interface benutzen, wenn du nicht gerade eine Bibliothek hast, die dir crossplatforme Threads unterstuetzt.

    curl_easy_setup (); gibts nicht... und curl_easy_perform (); blockiert, egal, welche Read-Funktion du mit curl_easy_setopt (); einstellst.

    Mfg,

    Kolazomai
     
  6. 11. April 2009
    AW: Mit Curl mehrfach Downloaden

    Ja, curl_easy_setopt meinte ich ja, dass es allerdings Blockiert hatte ich nicht mehr in Erinnerung
     
  7. 11. April 2009
    AW: Mit Curl mehrfach Downloaden

    Hi

    Vielen Dank Leute unter Linux hab ich das ganze jetzt hinbekommen klappt auch ganz gut

    Eine Frage hab ich noch wenn ich dir URL auf einen Webserver mit einem PHP Script setzen und das PHP Script einen 301 Redirect macht. Gibts da ne Option zu das Curl darauf reagiert und sich auch weiterleitet?
    Sonst läd er ja nur die Ausgabe des PHP Scripts herunter...

    Gruß Space
     
  8. 11. April 2009
    AW: Mit Curl mehrfach Downloaden

    Probiers mal mit curl_easy_setopt ( Wenn easy verwendet ) und setzte
    CURLOPT_FOLLOWLOCATION auf true:

    curl_easy_setopt( handle, CURLOPT_FOLLOWLOCATION, 1 );

    Wie's beim Multi-Interface ausieht weiß ich nicht.
    Hab auf anhieb nichts direktes erkennen können, sieht aber so aus als müsstest du
    das ganze selber regeln.
     
  9. 11. April 2009
    AW: Mit Curl mehrfach Downloaden

    Hi

    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1 ); hab ich schon versucht bringt leider nix
     
  10. 12. April 2009
    AW: Mit Curl mehrfach Downloaden

    Hey!

    Mach mal CURL_VERBOSE an und zeig uns den Output bzw. schau mal, ob sich da was nuetzliches findet

    Auch der Sourcecode waere hilfreich.

    Mfg,

    Kolazomai
     
  11. 12. April 2009
    AW: Mit Curl mehrfach Downloaden

    Hi

    Hier der Fehler:

    Code:
    <br />
    <b>Warning</b>: fopen(/home/verteiler/empty-useragent-main-high.r*utem*si*.fm) [<a href='function.fopen'>function.fopen</a>]: failed to open stream: No such file or directory in <b>/home/applications/verteiler/lb/musik_find_server.php</b> on line <b>66</b><br />
    <br />
    <b>Warning</b>: fputs(): supplied argument is not a valid stream resource in <b>/home/applications/verteiler/lb/musik_find_server.php</b> on line <b>67</b><br />
    <br />
    <b>Warning</b>: fclose(): supplied argument is not a valid stream resource in <b>/home/applications/verteiler/lb/musik_find_server.php</b> on line <b>68</b><br />
    <br />
    <b>Warning</b>: Cannot modify header information - headers already sent by (output started at /home/applications/verteiler/lb/musik_find_server.php:66) in <b>/home/applications/verteiler/lb/musik_find_server.php</b> on line <b>603</b><br />
    
    Ich frag mich wieso ein PHP Fehler auftrit wenn ich es im Browser und Live Http Headers mache klappt das ganze.

    Das Radio hab ich nur aus Test mal eingetragen ^^ also ich will niemandem Schaden xD

    Das ganze teste ich mommentan noch auf dem einfachen Code welches nur 1 Verbindung aufbaut.

    Code:
     #include <stdio.h>
     
     #include <curl/curl.h>
     #include <curl/types.h>
     #include <curl/easy.h>
     
     /*
     * This is an example showing how to get a single file from an FTP server.
     * It delays the actual destination file creation until the first write
     * callback so that it won't create an empty file in case the remote file
     * doesn't exist or something else fails.
     */
     
     struct FtpFile {
     const char *filename;
     FILE *stream;
     };
     
     static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
     {
     struct FtpFile *out=(struct FtpFile *)stream;
     if(out && !out->stream) {
     /* open file for writing */
     out->stream=fopen(out->filename, "wb");
     if(!out->stream)
     return -1; /* failure, can't open file to write */
     }
     return fwrite(buffer, size, nmemb, out->stream);
     }
     
     
     int main(void)
     {
     
    
     CURL *curl;
     CURLcode res;
     struct FtpFile ftpfile={
     "curl2.mp3", /* name to store the file as if succesful */
     NULL
     };
     
     curl_global_init(CURL_GLOBAL_DEFAULT);
     
     curl = curl_easy_init();
     if(curl) {
     /*
     * Get curl 7.9.2 from sunet.se's FTP site. curl 7.9.2 is most likely not
     * present there by the time you read this, so you'd better replace the
     * URL with one that works!
     */
     curl_easy_setopt(curl, CURLOPT_URL,
     "http://main-high.*autem*si*.fm");
     /* Define our callback to get called when there's data to be written */
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
     /* Set a pointer to our struct to pass to the callback */
     curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
     
     /* Switch on full protocol/debug output */
     curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
    
     struct curl_slist *slist=NULL;
    
     
     slist = curl_slist_append(slist, "GET / HTTP/1.0\r\n");
     slist = curl_slist_append(slist, "Host: main-high.*autem*si*.fm\r\n");
     slist = curl_slist_append(slist, "User-Agent: WinampMPEG/5.55, Ultravox/2.1\r\n");
     slist = curl_slist_append(slist, "Ultravox-transport-type: TCP\r\n");
     slist = curl_slist_append(slist, "Accept: *//*\r\n");
     slist = curl_slist_append(slist, "Icy-MetaData:1\r\n");
     slist = curl_slist_append(slist, "Connection: close\r\n\r\n ");
     
     
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1 );
     
    
     
     
     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist); 
     
     res = curl_easy_perform(curl);
    
     
     /* always cleanup */
     curl_easy_cleanup(curl);
     
     if(CURLE_OK != res) {
     /* we failed */
     fprintf(stderr, "curl told us %d\n", res);
     }
     }
     
     if(ftpfile.stream)
     fclose(ftpfile.stream); /* close the local file */
     
     curl_global_cleanup();
     
     return 0;
     }
     
    
    Gruß Space
     
  12. 13. April 2009
    AW: Mit Curl mehrfach Downloaden

    Hey!

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #include <unistd.h>
    #include <errno.h>
    
    #include <curl/curl.h>
    #include <curl/types.h>
    #include <curl/easy.h>
    
    
    #define OUT_FILENAME "out.mp3"
    
    #define URL "http://musik.com/existiert_nicht.mp3"
    
    
    int main (void)
    {
     FILE *stream = NULL;
     CURL *curl = NULL;
     CURLcode res = 0;
     
     /* Die Datei zum Schreiben oeffnen */
     stream = fopen (OUT_FILENAME, "wb");
     if (!stream)
     {
     perror ("fopen ()");
     return EXIT_FAILURE;
     }
     
     /* Curl initialisieren */
     curl_global_init (CURL_GLOBAL_ALL);
     
     /* Curl-Handle initialisieren */
     curl = curl_easy_init ();
     if (!curl)
     {
     printf ("curl_easy_init () failed!\n");
     return EXIT_FAILURE;
     }
     
     /* Das Curl-Handle einstellen */
     curl_easy_setopt (curl, CURLOPT_URL, URL);
     
     curl_easy_setopt (curl, CURLOPT_READFUNCTION, fwrite);
     curl_easy_setopt (curl, CURLOPT_READDATA, stream);
     
     curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1);
     
     curl_easy_setopt (curl, CURLOPT_VERBOSE, 1);
     
     /* Und dann mal laufen lassen */
     res = curl_easy_perform (curl);
     
     /* Aufraeumen */
     curl_easy_cleanup (curl);
     fclose (stream);
     
     /* Gabs einen Fehler? */
     if (res)
     {
     printf ("curl_easy_perform (): %s\n", curl_easy_strerror (res));
     return EXIT_FAILURE;
     }
     
     return EXIT_SUCCESS;
    }
    Anpassen, compilen, ausfuehren und Output (des Compilers & Programms) geben bitte

    Vielleicht funktionierts nicht wegen READFUNCTION "fwrite ()". Dann loes es einfach, indem du eine Funktion erstellst, die dann einfach "fwrite ()" aufruft! Sollte aber so auch gehen

    Mfg,

    Kolazomai
     
  13. 13. April 2009
    AW: Mit Curl mehrfach Downloaden

    Hi beim Kompilieren bekomm ich immer folgenden Fehler

    Code:
    main.cpp:21: error: invalid conversion from `int' to `CURLcode'
    Code:
    CURLcode res = 0;
    Weiste woran das liegt? Sorry falls das ne doofe Frage ist Variablen in C/C++ sind für mich ein graus xD

    Edit: Hab die 0 mal weggemacht dann gehts aber er schreibt nichts in die Datei.

    Folgendes wird im Programm ausgegeben:
    Code:
    * About to connect() to main-high.*autem*si*.fm port 80 (#0)
    * Trying 195.13.63.136... * connected
    * Connected to main-high.*autem*si*.fm (195.13.63.136) port 80 (#0)
    > GET / HTTP/1.1
    Host: main-high.*autem*si*.fm
    Accept: */*
    
    < HTTP/1.1 200 OK
    < Date: Mon, 13 Apr 2009 12:08:09 GMT
    < Server: Apache/2.2.9 (Debian) DAV/2 SVN/1.5.1 PHP/5.2.6-1+lenny2 with Suhosin-
    Patch mod_perl/2.0.4 Perl/v5.10.0
    < X-Powered-By: PHP/5.2.6-1+lenny2
    < Content-Length: 861
    < Content-Type: text/html
    <
    <br />
    <b>Warning</b>: fopen(/home/verteiler/empty-useragent-main-high.*autem*si*.fm)
    [<a href='function.fopen'>function.fopen</a>]: failed to open stream: No such fi
    le or directory in <b>/home/applications/verteiler/lb/musik_find_server.php</b>
    on line <b>66</b><br />
    <br />
    <b>Warning</b>: fputs(): supplied argument is not a valid stream resource in <b
    >/home/applications/verteiler/lb/musik_find_server.php</b> on line <b>67</b><br
    />
    <br />
    <b>Warning</b>: fclose(): supplied argument is not a valid stream resource in <
    b>/home/applications/verteiler/lb/musik_find_server.php</b> on line <b>68</b><br
     />
    <br />
    <b>Warning</b>: Cannot modify header information - headers already sent by (out
    put started at /home/applications/verteiler/lb/musik_find_server.php:66) in <b>/
    home/applications/verteiler/lb/musik_find_server.php</b> on line <b>603</b><br /
    >
    * Connection #0 to host main-high.*autem*si*.fm left intact
    * Closing connection #0
    
     
  14. 13. April 2009
    AW: Mit Curl mehrfach Downloaden

    Hey!

    Kannst du die Datei denn per Browser ueberhaupt herunterladen?
    Fuer mich schaut das so aus, als wuerde er die Datei auf dem Server nicht finden...

    Mfg,

    Kolazomai
     
  15. 13. April 2009
    AW: Mit Curl mehrfach Downloaden

    Hi

    Ja wenn ich main-high.*autemusik.fm im Browser ausführe bekomm ich die listen.pls datei für den Media Player zum Download zurück. Wenn ich die passenden Http Header für Utravox mitsende bekomm ich den mp3 Stream als mp3 datei zurück.
    Aber ich frag mich wieso es bei Curl nicht geht.


    *=r
     
  16. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.