Esercizio 1, 9-09-05 • Un server TCP a connessione multipla usa la socket library come segue: listen(sd,5); /* AL PIU’ 5 CONNESSIONI */ do { nsd = accept(sd,&(work.s),&addrlen); pid = fork(); if (pid == 0) { /* QUI IL PROCESSO FIGLIO GESTISCE IL DIALOGO; USANDO IL DESCRITTORE nsd */ close(nsd); exit(0); /* end of child process */ } else close(nsd); /* IL PADRE NON USA 'nsd' */ } while(1); • Fornire lo pseudocodice di uníimplementazione alternativa che usi la chiamata select() supponendo che il numero massimo dei possibili client sia pari a 3 e che il loro indirizzo di rete e porta siano noti a priori. Commenti • Il modo tradizionale di scrivere il server e’ farlo bloccare su una accept(), in attesa di una connessione. • All’arrivo di una connessione, il server esegue una fork(), il processo figlio gestisce la connessione e il padre rimane ad attendere altre richieste. • Con la select(), c’e’ UN SOLO processo cje "multi-plexa" tutte le richieste, servendole tutte man mano che arrivano Commenti 2 • Vantaggio: non servono processi multipli • Svantaggio: il server servendo una richiesta non puo’ trascurare le altre come succede con la fork() – Con la fork()il processo figlio serve la connessione parlando con un solo client. – Con select(), occorre tener conto di altre richieste in arrivo Soluzione all’esercizio • select() blocca il server finche’ non succede un evento su un file descriptor (ovvero un socket). • Cos’e’ un ’evento'? L’arrivo di dati o la possibilita’ di scrivere -- e’ il programmatore a dire a select() quali eventi devono sbloccare il server • Come si fa a dirlo? Si assegnano i corretti valori ai campi della struttura fd_set. Soluzione (2) • Passi dello pseudicodice del server – Creare una struttura fd_set con i socket che si vuole monitorare in lettura. – Creare una struttura fd_set con i socket che si vuole monitorare in scrittura. – Chiamare select() e bloccare il server fino al prossimo evento. – Quando select() ritorna, controllare quale socket ha causato lo sblocco – Servire, la richiesta pervenuta (ad esempio, inviare al client una pagina Web). – Ripetere i passi precedenti. Creazione di fdset • void build_select_list() • {int listnum; • /* inseriamo il socket di connessione nella fd_set del select*/ • /* FD_ZERO() cancella fd_set*/ • FD_ZERO(&socks); • /* aggiungiamo il socket "sock" a fd_set, che sara’ usato dalla select() */ • FD_SET(sock,&socks); Aggiunta connessioni alla lista • void handle_new_connection() {int listnum; • int connection; /* conterra’ il socket della connessione in arrivo, da aggiungere alla connect list */ • connection = accept(sock, NULL, NULL); • if (connection < 0) {perror("accept");exit(EXIT_FAILUR E);} Aggiunta connessioni alla lista (2) • setnonblocking(connection); /*rende il socket non bloccante */ • for (listnum = 0; (listnum < 5) && (connection != -1); listnum ++) • if (connectlist[listnum] == 0) {printf("\n Connessione in arrivo: FD=%d; Slot=%d\n",connection,listnum); • connectlist[listnum] = connection; connection = -1;} • if (connection != -1) {/* lista piena */ printf("non c’e’ spazio per nuovo client.\n"); • sock_puts(connection,"Sorry, server busy!\r\n"); • close(connection);}} Esercizio 11/11/05 • Illustrare con un esempio la conversione XDR • 0001010000101110000111000000110 • 000101000010111000011100 rappresenta: • + 1048576 + 262144 + 8192 + 2048 + 1024 + 512 + 16 + 8 + 4 • Cioe’ 1322524 Conversione Conversione (2) • La rappresentazione little endian darebbe il valore: • 001110001010000111010000 rappresenta: • + 2097152 + 1048576 + 524288 + 32768 + 8192 + 256 + 128 + 64 + 16 • Quindi il risultato sarebbe 3711440 Inizializzazione di fd_set • /* scandisci le connessioni ed aggiungile a fd_set */ • for (listnum = 0; listnum < 5; listnum++) • {if (connectlist[listnum] != 0) {FD_SET(connectlist[listnum],&sock s); • if (connectlist[listnum] >highsock) highsock = connectlist[listnum];}}} Soluzione (3) il server • • • • while (1) { /* Ciclo infinito del server*/ build_select_list(); /* costruisce la lista dei socket da monitorare /* • timeout.tv_sec = 1; • timeout.tv_usec = 0; • /* regola il timeout */ Soluzione (4) • /* Il primo argomento della select e’ il valore del socket piu’ alto piu’ uno. (basta passare FD_SETSIZE ) */ • /* Il secondo argomento della select e’ l’indirizzo del fd_set che contiene i socket su cui ci si aspettano i dati */ • /* Il terzo argomento della select e’ l’indirizzo del fd_set che contiene i socket su cui si vuol scrivere -- in questo esempio non si usano, quindi si passa NULL. */ • /* Il quarto argomento della select e’ l’indirizzo del fd_set che contiene i socket di segnalazione out of band (di solito non si usa) */ • /* L’ultimo argomento della select e’ il time-out del blocco. Per aspettare per sempre si passa NULL. */ Soluzione (3) • readsocks = select(highsock+1, &socks, (fd_set *) 0, (fd_set *) 0, &timeout); • /* select() ritorna il numero di socket su cui ci sono dati da leggere */ • /* Dopo il ritorno di select(), fd_set e’ modificata per indicare il motivo dello sblocco. If se il socket 4 era nel fd_set, e ci sono dati da leggere, the fd_set contene 4. */ Soluzione (3) • if (readsocks < 0) {perror("select");exit(EXIT_FAILUR E);} • if (readsocks == 0) {/* Niente di pronto */printf(".");fflush(stdout);} else read_socks();} • /* while(1) */} • /* main */ Esercizio 2 18/7/2007 Get e Post • <form name="input" action="html_form_submit.asp” method="get"> • Username: <input type="text" name="user"> • <input type="submit" value="Submit"></form> HTTP Get QuickTime™ and a decompressor are needed to see this picture. • http://localhost/html_form_submit.asp?user =damiani HTTP Post • POST /html_form_submit.asp HTTP/1.0 • User-Agent: Mozilla • Content-Type: application/xwww-form-urlencoded • Content-Length: 12 • user=damiani Esercizio • % ftp -d testbox2 • Connected to testbox2.slacksite.com. • 220 testbox2.slacksite.com FTP server ready. • Name: slacker • ---> USER slacker • 331 Password required for slacker. • Password: TmpPass • ---> PASS XXXX • 230 User slacker logged in. • ---> SYST215 UNIX Esercizio 3 18/7/07 active • % ftp -d testbox2 • Connected to testbox2.slacksite.com. • 220 testbox2.slacksite.com FTP server ready. • Name: slacker • ---> USER slacker331 • Password required for slacker. • Password: TmpPass • ---> PASS XXXX Esercizio 3 active • 230 User slacker logged in. • ---> SYST215 UNIX Type: L8 • Remote system type is UNIX.Using binary mode to transfer files. • ftp> ls • ---> PORT 192,168,150,80,14,178200 PORT command successful. • ---> LIST • 150 Opening ASCII mode data connection for file list. Commenti • Il comando PORT specifica una porta sul client (192.168.150.80) (opposto al caso passivo). • 6 numeri separati da virgole. Primi quattro ottetti indirizzo IP address • Altrin due la porta di commessione • Per trovare il numero di porta moltiplicare il quinto ottetto per 256 e aggiungere il sesto ottetto. • Nell’esempio ( (14*256) + 178), o 3762. 1 - FTP server port 21 da qualsiasi (Client inizia connessione) 2 - FTP server port 21 a porte > 1023 (Server risponde al client) QuickTime™ and a decompressor are needed to see this picture. 3 - FTP server port 20 a porte > 1023 (Server inizia connessione alla data port del client) 4 - FTP server port 20 da porte > 1023 (Client invia ACKs alla data port del server) Esercizio 3 active • drwx-----3 slacker users 104 Jul 27 01:45 public_html • 226 Transfer complete • ftp> quit • ---> QUIT221 • Goodbye. Esercizio 3 18/7/2007 Passive • Type: L8Remote system type is UNIX.Using binary mode to transfer files. • ftp> passive • Passive mode on. • ftp> ls • ---> PASV227 • Entering Passive Mode (192,168,150,90,195,149). • ---> LIST Commenti • Porta viene aperta sul server, non sul client Esercizio 3 • 150 Opening ASCII mode data connection for file list • drwx-----3 slacker users 104 Jul 27 01:45 public_html • 226 Transfer complete. • ftp> quit • ---> QUIT221 • Goodbye. 1 - FTP server porta 21 da qualsiasi porta client (Client inizia connessione) 2 - FTP server porta 21 a porte > 1023 del client (Server risponde al client) QuickTime™ and a decompressor are needed to see this picture. 3 - Da porta dati del FTP client a porta > 1023 sul FTP server (Client inizia connessione dati alla porta specificata server) 4 - FTP server porta > 1023 a porta client > 1023 (Server invia ACK (e dati) alla data port del client) HTTP • GET /http.html Http1.1 • Host: www.http.header.free.fr • Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, • Accept-Language: Fr • Accept-Encoding: gzip, deflate • User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 4.0) • Connection: Keep-Alive HTTP • HTTP/1.1 200 OK • Date: Mon, 12 Mar 2008 19:12:16 GMT • Server: Apache/1.3.12 (Unix) Debian/GNU mod_perl/1.24 • Last-Modified: Fri, 22 Sep 2000 14:16:18 • ETag: "dd7b6e-d29-39cb69b2” • Accept-Ranges: bytes • Content-Length: 3369 • Connection: close • Content-Type: text/html • [File content goes here] HTTP • http://www.rexswain.com/httpview.html • http://www.w3.org/Protocols/HTTP/HTRQ _Headers.html • http://www.http.header.free.fr/http.html#htt psamples