SOP121/ćw - temat F

TCL/TK - zastosowania systemowe.

Proszę zrobić kilka zadań z (*) ! - zwłaszcza osoby które chcą mieć lepszą ocenę z ćwiczeń ...

Ćwiczenie X1


Wypróbuj działanie debuggera Tcl-u na przykładzie jakiegokolwiek skrypty Tcl używającego procedur (ten debugger potrafi śledzić tylko procedury !).

 

 

Skrypty "sieciowe" (wykorzystujące polecenie socket).

Pojęcia dotyczące sieci komputerowych : 

Pojęcia/ idee dotyczące Tcl/Tk:

 

Zadanie 79


(Eksperymenty z komendą socket - usługa kalkulator).
Napisz serwer (kalk_ser.tcl) i klienta (kalk_kli.tcl) usługi kalkulator.
Usługa ta działa tak: użytkownik włącza klienta, wpisuje wyrażenie arytmetyczne, naciska enter, i dostaje w odpowiedzi wartość wyrażenia; klient wysyła wyrażenie do serwera poprzez gniazdko, potem czeka na odpowiedź, gdy odpowiedz nadejdzie wyświetla ją i czeka na następną linię tekstu od użytkownika; gdy użytkownik wpisze "." + enter wtedy klient wie że powinien się zakończyć ...
 

Zadanie 80 (*)


(Serwer HTTP)
Napisz serwer usługi HTTP (czyli serwer WWW), a następnie wypróbuj jego działanie przy pomocy dowolnej przeglądarki stron WWW.

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".

 

 

Skrypty systemowe.

Zadanie 81


(Interfejs graficzny "chmod")
Napisz interfejs graficzny "chmod.tcl" do oglądania i modyfikowania praw plików/katalogów pod Unix-em.
Powinna być możliwość chodzenia po drzewie katalogów, kliknięcia na wybranym pliku, i obejrzenia + modyfikacji praw do tego pliku (widgety checkbox będą tu przydatne ...).
 

Zadanie 82 (*)


(Interfejs graficzny klienta "lftp")
Napisz interfejs graficzny "ftp.tcl" dla tekstowego klienta "lftp" dostępnego w większości unikso-podobnych systemów operacyjnych. Klienta tekstowego lftp włącza się poleceniem:

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).

 

Rozszerzanie Tcl-u (o nowe "wbudowane" komendy).

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 (*)


Wykonaj własną wersje programu "tclsh" z komendą "eq"; wykorzystaj przykłady linux_tcl.zip i win_tcl.zip; jak to należy kompilować ?
gcc -Dtcl np01.cc tclapp01.c -ltcl8.3 -lm -o zad83


Zadanie 84 (*)


Wykonaj własną wersje programu "wish" z widgetem "square"; wykorzystaj przykłady linux_tcl.zip i win_tcl.zip; jak to należy kompilować ?

gcc -Dtcl -Dtk np01.cc tclapp02.c square.c -ltcl8.3 -ltk8.3 -lX11 -lm -o zad84
Potem uruchom przykład "square01.tcl"