Proszę zrobić kilka zadań z (*) ! - zwłaszcza osoby które chcą mieć lepszą ocenę z ćwiczeń ...
Ćwiczenie X1
Pojęcia dotyczące sieci komputerowych :
Pojęcia/ idee dotyczące Tcl/Tk:
Zadanie 79
Zadanie 80 (*)
Protokół HTTP jest protokołem typu żądanie/odpowiedź (ang. request/response);
przeglądarka stron WWW wykonuje następujące kroki:
1. podłącza się do serwera WWW na porcie nr 80
2. wysyła do serwera żądanie
3. odczytuje odpowiedź
4. połączenie jest przerywane.
Protokół HTTPjest protokołem bezstanowym, co oznacza że nie pamięta niczego między jednym a drugim żądaniem.
Strony WWW możesz łatwo wygenerować przy pomocy programu mozilla/ opcja "Edit page" (?); warto żeby strona na której będziemy eksperymentować miała linki i miała kilka obrazków - ale z tym ostatnim może być pewien problem ....
Szczegóły protokołu HTTP ... są bardzo proste:
Przeglądarka wysyła do serwera następujący komunikat:
GET /index.html HTTP/1.0 [CRLF] Accept: image/gif, image/jpeg [CRLF] User-Agent: Mozilla/4.0 [CRLF] Host: www.cs.huji.ac.il:80 [CRLF] Connection: Keep-Alive [CRLF] [CRLF] ???????????
Uwaga: Napis [CRLF] oznacza dwa znaki o kodach 13 i 10 które oznaczają
koniec linii (pod DOS-em).
Tak naprawdę wystarczy że serwer przeczyta pierwszą linie żądania ...
A serwer odpowiada tak
HTTP/1.0 200 OK [CRLF] Date: Fri, 31 Dec 1999 23:59:59 GMT [CRLF] Content-Type: text/html[CRLF] Content-Length: 1354[CRLF] [CRLF] <html>[CRLF] <body>[CRLF] <h1>Hello World</h1> [CRLF] ...................................
Uwaga: Jeśli na stronie WWW którą przeglądarka ściąga są obrazki to
przeglądarka zażąda tych obrazków osobno ...; obrazki są przesyłane "w trybie
binarnym" (są umieszczane zaraz za pustą linią).
Trzeba odpowiednio ustawić nagłówek "Content-Type"; reszta
nagłówków jest raczej niekonieczna !.
Patrz też slajdy opisujące protokół HTTP: "http1.zip" i "http2.zip".
Zadanie 81
Zadanie 82 (*)
lftp adres_serwera_FTP -u użytkownik,hasło
Następnie wydaje się polecenia przypominające trochę polecenia do operowania na plikach znane z Unix-a:
ls
# powinno nam wyświetlić listę plików w (naszym) bieżącym katalogu na serwerze FTP
pwd
# wyświetla bieżący katalog
cd katalog
# pozwala zmienić katalog bieżący
bin
# włącza tryb binarny przesyłania plików (bez zmiany oznaczeń końców linii 13+10 <=> 10)
get plik
# ściąga plik z serwera FTP
put plik
# wysyła plik do serwera FTP
mput maska
# wysyła wszystkie pliki zgodne z maską
# itd ...
Wskazówki do zadania 82:
To zadanie trzeba koniecznie zrobić na Unix-ie (a nie pod Windows-ami) !.
Nasz interfejs graficzny ("ftp.tcl") powinien wykorzystywać klienta tekstowego "lftp" i sterować nim w zależności od operacji wykonywanych przez użytkownika. Na samym początku powinien ściągnąć listę plików i pokazać ją w widgecie typu listbox. Program "lftp" powinien być uruchomiony JEDNOKROTNIE, zaraz po uruchomieniu skryptu "ftp.tcl"; dalej sterujemy nim poprzez dwa łącza nazwane - przez jedno wysyłamy komendy do lftp, przez drugie odbieramy wyniki ich działania.
Do uruchamiania zewnętrznych programów służy
polecenia Tcl-u "exec", w którym można stosować przeadresowywanie i
inne konstrukcje, jak w powłokach Unix-owych:
exec lftp $serwerFTP -u $uzytkownik,$haslo <ftp1 >ftp0 2>ftp0
&
Trzeba koniecznie użyć programu "lftp" (a nie "ftp" !), gdyż "ftp" bardzo źle
pracuje gdy jego stdin i stdout NIE są prawdziwym terminalem ...; można to
zauważyć uruchamiając taki potok:
cat | ftp serwer_FTP | cat
# zarówno stdin (desk 0) jak i stdout
(desk 1) programu ftp są tutaj końcówkami łączy
Przeanalizuj skrypty ftp_gui.tcl i
ftp_gui2.tcl ! - skrypty
te pozwalają wysyłać komendy do programu "lftp" i obserwować wyniki ich
działania; pojawiające się w tych skryptach rozwiązania i "triki" (zwłaszcza
trik z nieistniejącym poleceniem "qqq") są wystarczające aby wykonać poprawnie
to zadanie ...; drugi ze skryptów pozwala wysłać do lftp kilka poleceń za jednym
zamachem. Aby skrypty przykładowe działały trzeba ustawić odpowiednio zmienne w
pierwszych liniach skryptu:
# -------------------------------
set serwerFTP "localhost"
set uzytkownik "mhanckow"
set haslo "?"
# -------------------------------
W zadaniu tym można stosować tryb blokujący zarówno przy zapisie do łączy jak i przy odczycie z łączy ! (nie ma niebezpieczeństwa pojawienia się zakleszczenia, gdyż komendy które wysyłamy są "krótkie", jedynie odpowiedzi mogą być długie - proszę przemyśleć tę sprawę !).
(Koniec wskazówek do zadania 82).
Nowe wbudowane komendy dodaje się przy pomocy języka C/C++;
można to zrobić zarówno pod Linux-em jak i pod Windows-sami (łatwiej pod
Linux-em !).
Oprócz nowych komend można także dodawać nowe widgety;
patrz dokumentacja "własne widgety".
Każda nowa komenda wygląda "z grubsza" jak funkcja main() języka C; w ten sam sposób pobiera swoje parametry jak program w języku C:
// funkcja realizująca komendę "eq" // sprawdzającą czy podane 2 argumenty (stringi) są identyczne // int EqCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { if (argc != 3) { interp->result = "wrong # args"; return TCL_ERROR; } if (strcmp(argv[1], argv[2]) == 0) { interp->result = "1"; } else { interp->result = "0"; } return TCL_OK; }// specjalna funkcja uruchamiana zaraz po włączeniu wish/tclsh ... // int Tcl_AppInit(interp) Tcl_Interp *interp; { if (Tcl_Init(interp) == TCL_ERROR) { return TCL_ERROR; } #ifdef tk if (Tk_Init(interp) == TCL_ERROR) { return TCL_ERROR; } #endif // w ten sposób tworzymy komendę "eq" ... // Tcl_CreateCommand(interp,"eq",EqCmd,NULL,NULL); return TCL_OK; }main(int argc, char** argv) { #ifdef tk Tk_Main(argc,argv,Tcl_AppInit); #else Tcl_Main(argc,argv,Tcl_AppInit); #endif }
Zadanie 83 (*)
gcc -Dtcl np01.cc tclapp01.c -ltcl8.3 -lm -o zad83
Zadanie 84 (*)
Potem uruchom przykład "square01.tcl"gcc -Dtcl -Dtk np01.cc tclapp02.c square.c -ltcl8.3 -ltk8.3 -lX11 -lm -o zad84