Esercizio 1, 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_FAILURE);}
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 rappresenta: Cioe’
Conversione
Conversione (2) La rappresentazione little endian darebbe il valore: rappresenta: Quindi il risultato sarebbe
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],&socks); 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_FAILURE);} if (readsocks == 0) {/* Niente di pronto */printf(".");fflush(stdout);} else read_socks();} /* while(1) */} /* main */
Esercizio 2 18/7/2007 Get e Post Username:
HTTP Get =damiani
HTTP Post POST / html_form_submit.asp HTTP/1.0 User-Agent: Mozilla Content-Type: application/x-www-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, PORT command successful. ---> LIST 150 Opening ASCII mode data connection for file list.
Commenti Il comando PORT specifica una porta sul client ( ) (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) 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 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 Opening ASCII mode data connection for file list drwx 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) 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: 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/ OK Date: Mon, 12 Mar :12:16 GMT Server: Apache/ (Unix) Debian/GNU mod_perl/1.24 Last-Modified: Fri, 22 Sep :16:18 ETag: "dd7b6e-d29-39cb69b2” Accept-Ranges: bytes Content-Length: 3369 Connection: close Content-Type: text/html [File content goes here]
HTTP _Headers.htmlhttp:// _Headers.html psamples