File Download



  • Hallo,
    ich bin ziemlich neu bei Linux also bitte nicht schlagen wenn die Antwort offensichtlich ist.

    Wie kann ich eine Datei vom Internet auf die Festplate runterladen? Ich will sie nachher mit einem ifstream weiter verarbeiten können. Also so ne Art:

    download_file("http://www.something.com/blablabla/test.html","temp.html");
    ifstream in("temp.html");
    

    Also so etwas ähnliches wie InternetOpenUrl unter Windows.



  • du könntest mit system("wget URL") die Datei runterladen und dann die Datei öffnen oder mittels der Lib Curl http://curl.haxx.se/ die Datei runterladen und direkt in dein Programm benutzen.

    MFG
    xmarvel



  • Hallo habe gerade mal alten Code von mir rausgekramt. Dieses kleine Programm bekommt als 1. Parameter die URL der Seite und als zweiten den Port auf dem der HTTP-Server lauscht (also in den meisten Fällen 80). Die Funktion get schneidet dann den HTTP-Header ab so dass man die reinen HTML Daten bekommt. Das Programm macht jedoch nur ein Mal recv, daher soltest du das bei größeren Seiten in eine Schleife packen.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <netdb.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    
    #define REQUEST "GET / HTTP/1.1\nHost:%s\n\n"
    
    char *get( char *pBf, int iBfLn );
    
    int main( int argc, char *argv[] )
    {
      int sd;
      int rs;
      struct sockaddr_in addr;
      struct hostent *he;
      char cBf[1024]; 
      char *pBf;
    
      if ( argc == 3 )
      {
        he = gethostbyname( argv[1] );
        if ( he )
        {
         sd = socket( AF_INET, SOCK_STREAM, 0 );
          if ( sd != -1 )
          {
            addr.sin_family = AF_INET;
            addr.sin_port = htons( (unsigned short)atoi( argv[2] ) );
            addr.sin_addr = *((struct in_addr*)he->h_addr);
            memset( &(addr.sin_zero), 0, 8 );
    
            rs = connect( sd, (struct sockaddr*)&addr, sizeof(struct sockaddr) );
            if ( rs != -1 )
            {
              sprintf( cBf, REQUEST, argv[1] );
              if ( send( sd, cBf, strlen( cBf ), 0 ) )
              {
                memset( cBf, 0, 1024 );
                if ( recv( sd, cBf, 1024, 0 ) )
                {
                  pBf = get( cBf, 1024 );
                  if ( pBf ) 
                    printf( "%s\n", pBf );
                  close( sd );
                  return 0;
                };
              };
            };
          };
        };
      };
    
      return 1;
    };
    
    char *get( char *pBf, int iBfLn )
    {
      if ( pBf )
      {
        iBfLn--;
        while ( iBfLn && ( !pBf[iBfLn] || pBf[iBfLn] == '\n' ) )
        {
          pBf[iBfLn] = (char)0;
          iBfLn--;
        };
    
        while ( iBfLn )
        {
          if ( pBf[iBfLn-1] == '\n' )
            return &pBf[iBfLn];
          iBfLn--;
        };
      };
    
      return 0;
    };
    


  • Hallo,

    };
              };
            };
          };
        };
      };
    

    Sieht schön aus. 🙂

    Du solltest evtl. mal etwas besser kommentieren, denn so ohne Weiteres ist der Code nicht zu verstehen.



  • 🙂 Ja weiß ich. Ist halt alter Code den ich irgendwann mal auf die schnelle zusammengetippt habe. Ursprünglich habe ich damit meine aktuelle IP-Adresse ausgelesen (siehe getip.dyndns.org). Aber Recht hast du auf jeden Fall.
    PS: Daher habe ich auch vor dem Code eine kleine Beschreibung geschrieben.



  • Bevor man hier mit C weitermacht obwohl man C++ verwenden will sollte man

    eine eigene Socketklasse schreiben
    eine Socketklasse im INET suchen und sich damit auseinandersetzen.

    ein Klasse schreiben welche bestimmte Strings über diese Socketklasse sendet.

    Wenn du das machst kannst du ohne Probleme einen Connect zu einem Webserver aufbauen (verbinden zu www.something.com und PORT 80) und dann z.B. folgedes senden.

    GET /blablabla/test.html HTTP/1.0\n\n

    oder

    POST /blablabla/test.html HTTP/1.0\n\n

    Dann solltest du die Antwortseite auf denm Socket zurüchbekommen
    So macht es übrigens auch ein Browser und alle anderen Programme.
    Das erste ist jedoch sich eine Socketklasse zuzulegen oder selbst zu schreiben.

    http://science.slc.edu/~msiff/courses/soft/examples/sockets/tougher/



  • @Unix-Tom,
    oh...ifstream hab ich vollkommen überlesen.



  • Ich mach das nun folgendermassen:

    void download_file(string url,string file){
      remove(file.c_str());
      system(("wget --quiet --tries=3 --retry-connrefused --output-document=\""+file+"\" \""+url+"\"").c_str());
      ifstream in(file.c_str());
      if(in.get()==EOF)
        throw no_download("Could not download \""+url+"\" to \""+file+"\"");
    }
    

    Danke für eure Hilfe.



  • geht aber nur wenn wget installiert ist.

    Ein Softwareentwickler nimmt normalerweise eine saubere Lösung.



  • Unix-Tom schrieb:

    Ein Softwareentwickler nimmt normalerweise eine saubere Lösung.

    Dein Wort in Gottes Ohr... 🤡

    Nein, aber mal ernsthaft, was spricht denn gegen libcurl?


Anmelden zum Antworten