HTTP klient pomocou BSD socketov
Jedná sa o prvý školský projekt v rámci predmetu počítačovej siete. Zadaním bolo vytvoriť jednoduchý HTTP klient v C / C ++ as použitím BSD socketov.
Východiskovým textom k implementácii bolo toto RFC, ktoré som však rozhodne nemal čas prečítať celé. Implementoval som len nutné minimum (redirect, chunked prenos, základné stavové kódy) pre funkčného HTTP klienta.
S implementáciou som začal v deň odovzdávania, takže sa prosím nikto neinspirujte štýlom kódu (všetko v main, divná kombinácia C a C ++). Musím sa ale pochváliť svojím prvým použitím goto (okrem assemblery) ..: D
Použitie programu je jednoduché. Pri svojom spustení očakáva jediný parameter - platnú url. Podporuje aj iné porty, ako predvolené.
$ webclient www.abcd.cz:88/cesta/test.html
Ak by chcel niekto tento program vyskúšať na Windows, tak je to možné s použitím Cygwin, ktorý implementuje sys / socket.ha alebo je možné program portovať na WinSocks. Sú tam drobné rozdiely, ale nič zásadné.
BSD Sockety
BSD (alebo tiež Berkley) sockety sú Unixové API (nájdete ich teda natívne v Linuxe alebo BSD) pre medziprocesorovej a internetovú komunikáciu. Ich zmyslom je obaliť systémové implementácie jednotlivých protokolov (tj. IPv4, IPv6, TCP, UDP, ...) rôznych úrovní a vytvoriť jednotné rozhranie. Vznikli už roku 1983 a boli natoľko úspešné, že sú de facto používané vo všetkých moderných OS. Windows je implementuje mierne odlišne (už spomínané WinSocks) a v praxi sa odporúča používať POSIX sockety, ktoré nahradzujú staršie BSD funkcie (gethostbyname, gethostbyaddr, ...) za moderné (príjemnejšie sa programujú a vie niektoré veci navyše) gettaddrinfo a getnameinfo.
Tento projekt ukazuje použitie pôvodných BSD socketov (testovaný bol na FreeBSD 10.2, ale funguje aj na modernom Linuxe) a IPv4 / TCP stacku.
Základný princíp
Využitie BSD socketov je v zásade veľmi jednoduché. Najprv vytvoríme tzv. Socket - z pohľadu programátora ide de facto o "obyčajný súbor" a môžeme s ním pracovať veľmi podobne. Keď do neho zapíšeme, systém úplne autonómne vezme dáta, vytvorí z nich pakety (v tomto prípade TCP) a odošle ich. Vďaka použitiu TCP je zaručené správne poradie doručených dát a tiež ich bezchybnosť.
Vytvorenie socketu je triviálne. Definujeme, ktoré protokoly budú využité. AF_INET značí IPv4 a SOCK_STREAM TCP:
tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
Ďalší krok je opäť jednoduchý. Je potrebné získať IP adresu servera z jeho mena (DNS záznamu). K tomu môžeme využiť gethostbyname ().
struct hostent *server; server = gethostbyname(hostname.c_str()); // očekává klasický C string
Zo štruktúry hostent potom získame všetky dôležité informácie. Tento krok je trochu neprehľadný a pri použití spomínaných POSIX socketov (tie som využil v druhom projekte) odpadá.
struct sockaddr_in server_address; memset(&server_address, 0, sizeof(server_address)); // vymazání struktury server_address.sin_family = AF_INET; // nastavení IPv4 memcpy(&server_address.sin_addr.s_addr, server->h_addr_list[0], server->h_length); // nakopírování samotné adresy server_address.sin_port = htons(port); // htons: převod do big-endian
Ďalším krokom je už pripojenie na server:
connect(tcp_socket, (const struct sockaddr *) &server_address, sizeof(server_address));
Teraz, keď máme nadviazané TCP spojenia, môžeme jednoducho odosielať a prijímať dáta ..
string http_get = "nejaky text podle HTTP standardu.."; int reply_size; char reply[BUFFER_LEN]; send(tcp_socket, http_get.c_str(), http_get.size(), 0); reply_size = recv(tcp_socket, reply, BUFFER_LEN, 0);
Ak vám vŕtala hlavou tá nula ako posledný parameter všetkých volaní, tak ide o flags - môžete modifikovať správanie (možnosti viď. Manuálové stránky). V tomto prípade napríklad bude program čakať, až bude prijaté presne chunk_size bajtov a až potom ich vráti.
reply_size = recv(tcp_socket, reply, chunk_size, MSG_WAITALL);
Na záver po sebe ako slušní programátori upraceme:
close(tcp_socket);
Záver
Program je len veľmi jednoduchá ukážka, ako vytvoriť aplikáciu komunikujúce po sieti. Nabudúce ukážem, ako vytvoriť server a vlastné jednoduchý protokol pre prenos súborov.
Galéria
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 46x (3.5 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C