Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.
Obě strany předchozí revizePředchozí verze | |||
pitel:ipk:projekt1 [18. 02. 2013, 10.14:32] – zmena struktury, stazitelne snippety pitel | pitel:ipk:projekt1 [30. 12. 2022, 13.43:01] (aktuální) – upraveno mimo DokuWiki 127.0.0.1 | ||
---|---|---|---|
Řádek 1: | Řádek 1: | ||
+ | ====== Webclient ====== | ||
+ | {{xkalab00.tar.gz}} | ||
+ | Vytvoření klientské síťové aplikace v prostředí UNIXu s využitím komunikačního rozhraní BSD sockets. | ||
+ | |||
+ | Vytvořte program (klient) s využitím rozhraní schránek (BSD sockets), který implementuje stahování zadaného objektu a případných vnořených objektů pomocí URL z WWW serveru s využitím HTTP protokolu do souboru uloženého v lokálním souborovém systému. | ||
+ | |||
+ | Vytvořte program v jazyce C/C++, který je přeložitelný na studentském unixovém serveru eva včetně funkčního Makefile souboru (program přeložitelný po zadání příkazu make). Program využívá spojovanou službu (protokol TCP). Jméno přeloženého programu klienta bude webclient. Program předpokládá jeden povinný parametr a to URL identifikující objekt, který bude uložen do lokáního souborového systému do aktuálního adresáře. Pokud v dotazu URL není uvedeno jméno souboru, obsah bude uložen do souboru index.html. Program musí podporovat stavové kódy HTTP protokolu pro přesměrování požadavku 3xx. Oznámení o chybách, které mohou nastat, bude vytištěno na standardní chybový výstup (stderr). Za vnořený objekt považujte obrázek (nestahujte definici CSS, Javascript, Flash objekty atd.). Obrázky uložte do adresáře podle cesty, jaká je uvedena v HTML dokumentu. | ||
+ | |||
+ | <file c webclient.c> | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | int webclient(char* url, unsigned short jumps) { | ||
+ | if (jumps > 5) { | ||
+ | fprintf(stderr, | ||
+ | return 1; | ||
+ | } | ||
+ | |||
+ | if (strstr(url, | ||
+ | url = strstr(url, "://" | ||
+ | } | ||
+ | |||
+ | char* parsedhost = url; | ||
+ | char* parsedport = " | ||
+ | char* parsedurl = ""; | ||
+ | char* parsedfile = " | ||
+ | unsigned int i = 0; | ||
+ | while (url[i] != ' | ||
+ | if (url[i] == ':' | ||
+ | url[i] = ' | ||
+ | parsedport = url + i + 1; | ||
+ | } | ||
+ | if (url[i] == '/' | ||
+ | url[i] = ' | ||
+ | parsedurl = url + i + 1; | ||
+ | i++; | ||
+ | while (url[i] != ' | ||
+ | if (url[i] == '/' | ||
+ | parsedfile = url + i + 1; | ||
+ | } | ||
+ | i++; | ||
+ | } | ||
+ | break; | ||
+ | } | ||
+ | i++; | ||
+ | } | ||
+ | |||
+ | if (strlen(parsedurl) < 1) { | ||
+ | parsedurl = ""; | ||
+ | } | ||
+ | |||
+ | // | ||
+ | |||
+ | int s = socket(PF_INET, | ||
+ | if (s < 0) { | ||
+ | fprintf(stderr, | ||
+ | return 1; | ||
+ | } | ||
+ | |||
+ | struct sockaddr_in sadr; | ||
+ | bzero(& | ||
+ | sadr.sin_family = AF_INET; //rodina | ||
+ | struct hostent *host; | ||
+ | if ((host = gethostbyname(parsedhost)) == NULL) { | ||
+ | fprintf(stderr, | ||
+ | return 1; | ||
+ | } | ||
+ | memcpy(& | ||
+ | sadr.sin_port = htons(atoi(parsedport)); | ||
+ | |||
+ | if (connect(s, (struct sockaddr*) &sadr, sizeof(sadr)) < 0) { | ||
+ | fprintf(stderr, | ||
+ | return 1; | ||
+ | } | ||
+ | printf(" | ||
+ | |||
+ | printf(" | ||
+ | char* get = NULL; | ||
+ | if (parsedurl == NULL) { | ||
+ | parsedurl = ""; | ||
+ | } | ||
+ | // | ||
+ | get = malloc((strlen(" | ||
+ | if (get == NULL) { | ||
+ | fprintf(stderr, | ||
+ | return 1; | ||
+ | } | ||
+ | get[0] = ' | ||
+ | strcat(get, | ||
+ | strcat(get, | ||
+ | strcat(get, | ||
+ | strcat(get, | ||
+ | strcat(get, | ||
+ | // | ||
+ | if ((write(s, get, strlen(get))) <= 0) { | ||
+ | fprintf(stderr, | ||
+ | if (parsedurl != NULL) { | ||
+ | free(get); | ||
+ | } | ||
+ | return 1; | ||
+ | } | ||
+ | if (parsedurl != NULL) { | ||
+ | free(get); | ||
+ | } | ||
+ | |||
+ | printf(" | ||
+ | char* header; | ||
+ | unsigned int allocated = 1; | ||
+ | unsigned int dumped = 0; | ||
+ | header = malloc(allocated * sizeof(char)); | ||
+ | if (header == NULL) { | ||
+ | fprintf(stderr, | ||
+ | return 1; | ||
+ | } | ||
+ | while (strstr(header, | ||
+ | read(s, header + dumped, 1); | ||
+ | dumped++; | ||
+ | if (dumped >= allocated) { | ||
+ | allocated *= 2; | ||
+ | header = realloc(header, | ||
+ | if (header == NULL) { | ||
+ | fprintf(stderr, | ||
+ | return 1; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | // | ||
+ | |||
+ | unsigned int response = atoi(header + 9); | ||
+ | printf(" | ||
+ | |||
+ | char* location = NULL; | ||
+ | if (response >= 300 && response < 400) { | ||
+ | location = strstr(header, | ||
+ | i = 0; | ||
+ | while (location[i] != ' | ||
+ | i++; | ||
+ | } | ||
+ | location[i] = ' | ||
+ | // | ||
+ | } | ||
+ | |||
+ | if (response == 200) { | ||
+ | // | ||
+ | printf(" | ||
+ | FILE* fp = fopen(parsedfile, | ||
+ | if (fp == NULL) { | ||
+ | fprintf(stderr, | ||
+ | free(header); | ||
+ | return 1; | ||
+ | } | ||
+ | char socketchar[1]; | ||
+ | while (read(s, socketchar, 1) > 0) { | ||
+ | fwrite(socketchar, | ||
+ | } | ||
+ | fclose(fp); | ||
+ | } | ||
+ | if (response >= 300 && response < 400) { | ||
+ | printf(" | ||
+ | webclient(location, | ||
+ | } | ||
+ | |||
+ | free(header); | ||
+ | shutdown(s, | ||
+ | close(s); | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | int main(int argc, char* argv[]) { | ||
+ | if (argc > 2) { | ||
+ | fprintf(stderr, | ||
+ | return 1; | ||
+ | } | ||
+ | |||
+ | if (argc == 1) { | ||
+ | printf(" | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | return webclient(argv[1], | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <file Make Makefile> | ||
+ | CC = gcc | ||
+ | CFLAGS = -O2 -std=c99 -pedantic -Wall -W -pipe | ||
+ | PROG = webclient | ||
+ | |||
+ | all: $(PROG) | ||
+ | |||
+ | webclient: webclient.c | ||
+ | |||
+ | clean: | ||
+ | -rm -f $(PROG) *.htm *.html *.png *.gif *.jpg *.jpeg *.bmp | ||
+ | </ | ||
+ | |||
+ | <file bash test.sh> | ||
+ | #!/bin/bash | ||
+ | |||
+ | echo " | ||
+ | make clean | ||
+ | echo | ||
+ | echo " | ||
+ | make | ||
+ | echo | ||
+ | echo " | ||
+ | ./webclient http:// | ||
+ | echo | ||
+ | echo " | ||
+ | ./webclient http:// | ||
+ | </ |