Sťahovanie súborov z internetu pomocou C/C++
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Sťahovanie súborov z internetu pomocou C/C++Sťahovanie súborov z internetu pomocou C/C++

 
Hledat
Moderní platforma pro vytvoření vašeho nového webu – Wix.com.
Nyní už můžete mít web zdarma.
Vybavení pro Laser Game
Spuštěn Filmový magazín
Laser Game Brno

Sťahovanie súborov z internetu pomocou C/C++

Google       Google       7. 3. 2010       26 647×

Jednoduché riešenie pre vaše programy, ktoré potrebujú sťahovať súbory z Internetu. Ak ste uvažovali o rozšírení svojej aplikácie alebo minimálne vašich vedomostí o možnosť sťahovať dáta z Internetu pomocou C++, tak po prečítaní tohto článku by vám to nemalo robiť problém.

Reklama
Reklama

K dosiahnutiu tohto cieľa existuje viacero ciest, no pre programátorov v prostredí Windows je najefektívnejšie využiť WinInet. Dôvody, prečo je tomu tak, v krátkosti objasním.

K súborom, ktoré sa nachádzajú v sieti Internet, sa najčastejšie pristupuje pomocou protokolu HTTP. HTTP teda slúži na výmenu dát medzi klientom a serverom. Nachádza sa na 4.  (aplikačnej) vrstve TCP/IP modelu. Pod ním sa nachádza vrstva transportná, sieťová a fyzická. HTTP je závislé na TCP (Transmission Control Protocol), ktoré je svojim protokolom náročné na aplikovanie. WinInet sa však stará o tieto problémy za nás, a nám sa tak ponúka komfortné implementovanie HTTP služieb.

Samotný postup sťahovania dát z Internetu pomocou WinInet sa skladá z niekoľkých krokov. Prvým z nich je nadviazanie spojenia, resp. vytvorenie inštancie, ktorá sa použije pri otváraní internetových súborov, alebo ešte inak povedané, inicializovanie WinInet pre použitie v aplikácii. Druhým krokom je otvorenie internetového súboru a tretím samotné prečítanie tohto súboru. Tieto tri základné kroky sú však v tomto článku rozšírené, aby sme si ukázali postupy, ktoré je vhodné dodržať. Napríklad zistenie statusu práve otvoreného internetového súboru nie je nutné, no môže nám povedať, či sa daný súbor otvoril, zistiť jeho veľkosť a iné, i keď menej dôležité informácie.

Začal by som popisom jednotlivých funkcií, ktoré v tomto programe použijeme. WinInet obsahuje množstvo užitočných funkcií, no rád by som vám poskytol len základy, na ktorých sa môžete realizovať a rozvíjať. Pre viac informácií môžete navštíviť referencie na MSDN.

  • Prvou takou funkciou, ktorú v našom programe použijeme je:
    DWORD InternetAttemptConnect(DWORD rezervovane);
    Ako už z názvu vyplýva, táto funkcia sa pokúsi o spojenie s Internetom. Lepšie túto funkciu popísať neviem, no na MSDN je trochu presnejší popis, i keď jej úloha nie je až také podstatné, program by fungoval aj bez nej, ale vždy je lepšia prevencia než liečba . Funkcia vracia ERROR_SUCCESS pri úspešnom spojení.
  • HINTERNET InternetOpen(LPCTSTR agent,DWORD typPristupu,LPCTSTR nazovProxy,LPCTSTR proxyBypass,DWORD priznaky);
    Touto funkciou inicializujeme našu aplikáciu na používanie WinInet funkcií. Pri úspešnom inicializovaní obdržíme handler, ktorý sa bude ďalej používať napr. otváraní internetových súborov. agent predstavuje názov vášho agenta, typPristupu je spôsob, akým budeme pristupovať na Internet, resp. či sa bude používať proxy atď. S týmto súvisia aj ďalšie parametre, a to proxyBypass a priznaky.
  • HINTERNET InternetOpenUrl(HINTERNET hInternet,LPCTSTR url,LPCTSTR hlavicky,DWORD dlzkaHlaviciek,DWORD priznaky,DWORD_PTR kontext);
    Otvoríme požadovaný súbor pomocou URL, či už HTTP alebo FTP. My však v tomto programe budeme používať HTTP. Ako hInternet použijeme hodnotu vrátenú funkciou InternetOpen. Parametrom hlavicky špecifikujeme vlastné hlavičky, ktoré sa odošlú spolu s požiadavkou. Funkcia nám vracia handle na otvorený internetový súbor (skôr sa stretnete s pojmom resource).
  • BOOL InternetReadFile(HINTERNET internetovySubor,LPVOID zasobnik,DWORD pocetBajtovNaPrecitanie,LPDWORD pocetPrecitanychBajtov);
    Touto funkciou prečítame určitú časť nášho internetového súboru, resp. v tomto prípade už odpoveď servera. internetovySubor nám určuje, ktorú resource ideme čítať. Tento parameter sme dostali funkciou InternetOpenUrl. Ostatné parametre sú známe. Výsledok funkcie je buď true alebo false. Výsledok true dostaneme aj vtedy, keď sme súbor už prečítali, čiže musíme kontrolovať počet bajtov, ktoré táto funkcia z resource prečítala, a ak sa táto hodnota rovná nule, ukončiť čítanie.
  • BOOL HttpQueryInfo(HINTERNET request,DWORD typInformacie,LPVOID zasobnik,LPDWORD velkostZasobnika,LPDWORD index);
    Túto funkciu môžeme použiť, ak chceme z odpovede servera získať informáciu napr. o statuse odpovede, veľkosti obsahu a pod. Za request v našom prípade dosadíme handle vrátený funkciou InternetOpenUrl. typInformacie nám určuje, ktorú informáciu chceme z hlavičky prečítať. Kompletný zoznam je na MSDN. Do premennej na adrese zasobnik sa uloží výsledok.
//---------------------------------------------------------------------------------
// Sťahovanie súborov z internetu pomocou WinInet
//---------------------------------------------------------------------------------
#include 
#include 
#include 
#include 
#include    // hlavičkový súbor knižnice WinInet
//---------------------------------------------------------------------------------
#define VELKOST_VYROVNAVACEJ_PAMATE   256   // veľkosť vyrovnávacej pamäte použitej
                              // pri čítaní internetového súboru
//---------------------------------------------------------------------------------
#pragma comment(lib,"WinInet.lib")   // prilinkovanie knižnice WinInet
//---------------------------------------------------------------------------------
using namespace std;
//---------------------------------------------------------------------------------

int main(int argc, char * argv[])
{
   cout << "Stahovanie suborov z internetu" << endl;
   string url,subor;
   cout << "Zadajte URL suboru: ";
   getline(cin,url);
   cout << "Zadajte nazov suboru na ulozenie: ";
   getline(cin,subor);

   // V prvom rade si deklarujeme premenné, ktoré budeme používať
   HINTERNET spojenie,internetovySubor;
   // Ďalej sa pokúsime o spojenie
   if (InternetAttemptConnect(0) != ERROR_SUCCESS)
   {
      // Spojenie nie je možné nadviazať, resp. nie je možné pracovať v online móde
      cout << "Nebolo mozne sa pokusit o spojenie" << endl;
      cout << "Kod chyby: " << GetLastError() << endl;
      return 1;
   }
   // Teraz si vytvoríme spojenie, inicializujeme aplikáciu na používanie WinInet
   spojenie = InternetOpenA("Moj internetovy prehladavac",
                     INTERNET_OPEN_TYPE_PRECONFIG,   // Predvolené nastavenia
                     0,                        // Žiadne proxy
                     0,                        
                     0);                        // Žiadne príznaky
   if (spojenie == 0) // NULL
   {
      cout << "Nie je mozne inicializovaz WinInet" << endl;
      cout << "Kod chyby: " << GetLastError() << endl;
      return 1;
   }
   // Následne otvoríme spojenie so súborom, ktorý je definovaný pomocou URL
   internetovySubor = InternetOpenUrlA(spojenie,      // Inštancia spojenia
                              url.c_str(),   // URL adresa súboru
                              0,            // Žiadna prídavná HTTP hlavička
                              0,            // Dĺžka prídavnej hlavičky   
                              0,            // Žiadne príznaky
                              0);
   if (internetovySubor == 0) // NULL
   {
      cout << "Nie je mozne vytvorit spojenie so suborom" << endl;
      DWORD kodChyby = GetLastError();
      cout << "Kod chyby: " << kodChyby << endl;
      char chyba[256];
      DWORD chybaVelkost = 255;
      if (InternetGetLastResponseInfoA(&kodChyby,chyba,&chybaVelkost))
         cout << "Popis chyby: " << chyba << endl;
      // Nesmieme zabudnúť zatvoriť už inicializovaný handler s WinInet
      InternetCloseHandle(spojenie);
      return 1;
   }
   // V tomto kroku môžeme zistiť podrobnosti o súbore
   DWORD informacia;
   DWORD velkostInformacie = sizeof(DWORD);
   // Najskôr si zistíme HTTP status kód (napr. status kód 200 znamená OK, 404 znamená súbor nenájdený)
   if (!HttpQueryInfoA(internetovySubor,   // Inštancia nami vytvoreného spojenia so súborom
               HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,   // Požadujeme status ktorý je číselným typom
               &informacia,         // Sem bude zapísaný výsledok volania
               &velkostInformacie,      // Veľkosť dátovej jednotky informácie
               0))
   {
      cout << "Nie je mozne zistit kod statusu" << endl;
      cout << "Kod chyby: " << GetLastError() << endl;
      InternetCloseHandle(internetovySubor);
      InternetCloseHandle(spojenie);
      return 1;
   }
   cout << "Status odpovede: " << informacia << endl;
   // Ak sa status odpovede nerovná 200, nedostaneme súbor, ktorý sme požadovali
   if (informacia != HTTP_STATUS_OK)
   {
      cout << "Status spojenia NIE je OK" << endl;
      InternetCloseHandle(internetovySubor);
      InternetCloseHandle(spojenie);
      return 1;
   }
   // Teraz si zistíme veľkosť súboru
   if (!HttpQueryInfoA(internetovySubor,   // Inštancia nami vytvoreného spojenia so súborom
               HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,   // Požadujeme status ktorý je číselným typom
               &informacia,         // Sem bude zapísaný výsledok volania
               &velkostInformacie,      // Veľkosť dátovej jednotky informácie
               0))
   {
      // Síce sme nezistili veľkosť súboru, ale to nám neprekáža v jeho stiahnutí
      cout << "Velkost suboru sa neda zistit" << endl;
      informacia = 0;
   }
   // Vytvoríme si vyrovnávaciu pamäť, do ktorej budeme ukladať časti súboru
   char * vyrovnavaciaPamat = new char[VELKOST_VYROVNAVACEJ_PAMATE];
   // Vytvoríme si výstupný súbor
   fstream vystupnySubor(subor.c_str(),   // Názov výstupného súboru
                  ios_base::out | ios_base::binary);   // Budeme zapisovať v binárnom móde
   // Premenná, do ktorej sa bude ukladať koľko sme z internetového súboru prečítali
   DWORD precitane = 0;
   // Premenná, do ktorej uložíme celkový počet stiahnutých bajtov
   DWORD stiahnute = 0;

   cout << "Stahujem\t\t\t";
   while (InternetReadFile(internetovySubor,   // Spojenie na náš internetový súbor
                     vyrovnavaciaPamat,   // Vyrovnávacia pamäť
                     VELKOST_VYROVNAVACEJ_PAMATE,   // Koľko môžeme max. prečítať
                     &precitane))      // Koľko WinInet prečítal
   {
      if (precitane == 0)      // Už sme všetko prečítali, ukončiť
         break;
      stiahnute += precitane;
      if (informacia != 0)   // Ak vieme o veľkosti súboru môžeme vypočítať %
         cout << "\rStahujem " << (int)((stiahnute*100)/informacia) << "%";
      else               // Inak len vypíšeme celkový počet stiahnutých B
         cout << "\rStahujem " << stiahnute << " B";
      // Zapísať do vsýtupného súboru
      vystupnySubor.write((const char*)vyrovnavaciaPamat,precitane);
   }
   cout << endl << endl;
   // Zistíme chybu (ak nejaká nastala)
   DWORD chyba = GetLastError();
   if (chyba != 0)
   {
      cout << "Pri citani vznikla chyba" << endl;
      cout << "Kod chyby: " << chyba << endl;
      char chybaText[256];
      DWORD chybaVelkost = 255;
      if (InternetGetLastResponseInfoA(&chyba,chybaText,&chybaVelkost))
         cout << "Popis chyby: " << chyba << endl;
   }
   else
   {
      cout << "Hotovo" << endl;
   }
   // Zatvoríme spojenia
   InternetCloseHandle(internetovySubor);
   InternetCloseHandle(spojenie);
   // Zatvoríme výstupný súbor
   vystupnySubor.close();
   // Nezabudneme vyrovnávaciu pamäť uvoľniť :)
   delete [] vyrovnavaciaPamat;
   return 0;
}

Už funkčný exe súbor spolu s kódom nájdete na: http://router.xf.cz/cppfiledownload.zip

×Odeslání článku na tvůj Kindle

Zadej svůj Kindle e-mail a my ti pošleme článek na tvůj Kindle.
Musíš mít povolený příjem obsahu do svého Kindle z naší e-mailové adresy kindle@programujte.com.

E-mailová adresa (např. novak@kindle.com):

TIP: Pokud chceš dostávat naše články každé ráno do svého Kindle, koukni do sekce Články do Kindle.

Hlasování bylo ukončeno    
0 hlasů
Google
Autor sa venuje programovaniu v jazykoch C#, C/C++, Delphi a v poslednej dobe sa taktiež zaujíma o vývoj hardvéru.
Web    

Nové články

Obrázek ke článku Virtuální zrcadla změní způsob nakupování v e-shopech

Virtuální zrcadla změní způsob nakupování v e-shopech

Díky pluginu Virtooal.com získávají zákazníci e-shopů možnost si vyzkoušet produkty ve virtuálním světě. E-shopy, které si plugin nainstalují, výrazně snižují množství vráceného zboží, dělají nákupy zábavnějšími, a tím budují lepší vztahy se svými zákazníky. V současnosti lze Virtooal.com využít zejména pro kosmetiku, brýle a šperky, do budoucna půjde také o módu.

Reklama
Reklama
Obrázek ke článku Kariérní postup & vyšší plat: Titul MBA ve sféře IT

Kariérní postup & vyšší plat: Titul MBA ve sféře IT

Působíte jako specialista v oblasti IT a aspirujete na povýšení, příp. řídící pozici? Pak se jistě potýkáte nejen s vysokými nároky (potenciálních) zaměstnavatelů, ale i se silnou konkurencí ze strany ostatních uchazečů. Pokud chcete zvýšit své šance na kariérní posun a lepší plat, měli byste vedle technických dovedností ovládat i ty manažerské. Pomoci vám v tomto ohledu může studium MBA se specializací na management IT.

Obrázek ke článku Tisková konference Hackers Congress Paralelni Polis 2018

Tisková konference Hackers Congress Paralelni Polis 2018

Již pátý ročník akce globálního významu Hackers Congress Paralelni Polis 2018 se letos odehraje 5. – 7. října, a to znovu v prostorech Paralelní Polis a přilehlého divadla La Fabrika na Praze 7. Na kongres se opět sjedou světoví odborníci, kteří svým zaměřením kopírují čtyři základní pilíře akce. Jsou jimi Svoboda a kryptoanarchie, Decentralizovaná ekonomika a kryptoměny, Politické umění a hacking a také Věda a technologie

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032018 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý