Il protocollo applicativo. Esempio di protocollo applicativo

Documenti analoghi
La Programmazione di Rete e di Sistema (iii) La programmazione di sistema. Il sistema operativo. La programmazione di sistema

Applicazioni distribuite. La programmazione di rete. Interfacce e protocolli. Protocollo applicativo

ESERCITAZIONE 2 RIPASSO. EX. 1 Un processo padre (parent) crea due processi figli (children) e attende la loro terminazione. Se, e solo se,...

La programmazione di rete

La programmazione di rete

La Programmazione di Rete e di Sistema (ii) La programmazione di rete. La tecnologia di rete. Tipologia di reti. Architettura delle reti

eseguire comandi dati dall'utente, utilizzando una macchina reale, di livello inferiore,

La Programmazione di Rete e di Sistema (ii) La programmazione di rete. Tipologia di reti. La tecnologia di rete. Architettura delle reti

Addendum alle chiamate di sistema per la gestione processi. E Mumolo

Sistemi Operativi Teledidattico

Pag. 1. modello di esecuzione parallela

System call per la gestione di processi

System call per la gestione di processi

Università di Roma Tor Vergata Corso di Laurea triennale in Informatica Sistemi operativi e reti A.A Pietro Frasca.

Esempio 1: stampa locale di file remoto

System Call EXEC EXEC P P. fork exec(new_prog) fork. sono_il_padre = fork(); if (!sono_il_padre) {

Il processo figlio : utilizza lo stesso codice che sta eseguendo il padre ;

La creazione di un nuovo processo in UNIX

Controllo dei Processi 1

Seconda Esercitazione. Gestione di processi in Unix Primitive Fork, Wait, Exec

COMUNICAZIONE TRA PROCESSI REMOTI IN UNIX

Corso di Sistemi Operativi Esercitazioni

Università di Roma Tor Vergata Corso di Laurea triennale in Informatica Sistemi operativi e reti A.A Pietro Frasca.

1. PARALLELISMO E PROCESSI. 1.1 La necessità del parallelismo

CORSO DI SISTEMI OPERATIVI A - ESERCITAZIONE 4

Le reti basate su TCP/IP

il tipo di parallelismo dipende dal grado di cooperazione

Esercitazione [7] Server multi-process/multi-thread

SISTEMI OPERATIVI. Processi in Linux. Giorgio Giacinto Sistemi Operativi

LABORATORIO DI SISTEMI OPERATIVI

Esercitazione [08] Server multi-process/multi-thread

Sistemi Operativi (M. Cesati)

Lezione 21. #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <sys/wait.

" &$ () " ) ) $ ' () *) " ) $

I.I.S. G.B. PENTASUGLIA MATERA ISTITUTO TECNICO SETTORE TECNOLOGICO LICEO SCIENTIFICO SCIENZE APPLICATE. Classe: 5Ci

Laboratorio di. Reti Informatiche. Corso di Laurea Triennale in Ingegneria Informatica A.A. 2016/2017. Ing. Niccolò Iardella

Sistemi Operativi 1. Lezione III: Concetti fondamentali. Mattia Monga. 7 marzo 2008

Sistemi Operativi 1. Mattia Monga. 7 marzo Dip. di Informatica e Comunicazione Università degli Studi di Milano, Italia

Terza Esercitazione. Gestione di segnali in Unix Primitive signal e kill!

AXO. Operativo. Architetture dei Calcolatori e Sistema. programmazione di sistema

Esercizio sulla gestione di processi in Unix!

SmallShell Piccolo processore comandi

Programmazione di sistema e gestione dei processi in C

IPC Inter Process Communication

Sistemi di Calcolo - Secondo modulo (SC2) Programmazione dei Sistemi di Calcolo Multi-Nodo

Fondamenti di Informatica T-1 modulo 2

Simulazione esame Laboratorio di Sistemi Operativi Cognome Nome Mat.

Lab. di Sistemi Operativi - Esercitazione n 9- -Thread-

*HVWLRQHDYDQ]DWDGHOOH6RFNHWLQ& ODSULPLWLYDVHOHFW

Creare un'elementare backdoor in C in ambiente UNIX

Fondamenti di Informatica T-1 modulo 2

Università di Roma Tor Vergata Corso di Laurea triennale in Informatica Sistemi operativi e reti A.A Pietro Frasca.

Corso di Reti di Calcolatori L-A

Esercitazione [7] Client/Server con Socket

Principles of Concurrent Programming

(VHUFLWD]LRQLGLEDVHVXOOH6RFNHWLQ&

Sistemi Operativi (M. Cesati)

SISTEMI&OPERATIVI& AA&2013&0&2014& Processi( in(linux( Giorgio&Giacinto&2013& Sistemi&Opera?vi&

Terza Esercitazione. Gestione di segnali in Unix Primitive signal e kill

Socket. Nei sistemi operativi moderni i servizi disponibili in rete si basano principalmente sul modello client/server.

System Calls per la Gestione dei Processi

Architetture dei Calcolatori e Sistemi Operativi

Università degli Studi di Cagliari Corso di Laurea Specialistica in Ingegneria Elettronica. SISTEMI OPERATIVI A.A. 2004/2005 Docente: Giorgio Giacinto

Reti (già Reti di Calcolatori )

LABORATORIO di Reti di Calcolatori

Introduzione ai socket

La funzione main() La funzione main(), presente in tutti i programmi C, è una funzione come tutte le altre

ACSO Programmazione di Sistema e Concorrente

Università di Roma Tor Vergata Corso di Laurea triennale in Informatica Sistemi operativi e reti A.A Pietro Frasca.

In generale può essere utile che i due processi eseguano del codice diverso

Sistemi Operativi T. Esercizi

Laboratorio di. Reti Informatiche. Corso di Laurea Triennale in Ingegneria Informatica A.A. 2017/2018. Ing. Carlo Vallati

Esempio 1: stampa locale di file remoto

Laboratorio di. Reti Informatiche. Corso di Laurea Triennale in Ingegneria Informatica A.A. 2016/2017. Ing. Niccolò Iardella

L uso di Socket UDP. TCP vs. UDP UDP

Lab. di Sistemi Operativi - Esercitazione n 7- -Gestione dei processi Unix-

Politecnico di Milano FACOLTÀ DI INGEGNERIA DELL INFORMAZIONE. Prof. William FORNACIARI

I Processi nel SO UNIX

C UDP in Windows p53 - variante 1

Esercitazione: Utilizzo delle Pipe

Interazione (TCP) Client-Server con le socket

Complementi. - Ridefinizione di tipo - - Costrutto switch - - Programmazione su più file - - Parametri della funzione main - Funzione system -

Programmazione di sistema

Sistemi Operativi (M. Cesati)

I Processi nel SO UNIX

Complementi. - Ridefinizione di tipo - - Costrutto switch - - Programmazione su più file - - Parametri della funzione main - Funzione system -

I Processi nel Sistema Operativo Unix. Gerarchie di processi Unix. Stati di un processo Unix. Stati di un processo Unix.

ESERCITAZIONE 2 fork e exec

Corso di Reti di Calcolatori L-A

Comunicazioni fra processi remoti: i socket nello UNIX di Berkeley

Sistemi Operativi Anno Accademico 2011/2012. Segnali: Interrupt software per la gestione di eventi asincroni

Un server di posta (che usa il protocollo SMTP) è identificato dal numero di porta 25.

Manualistica 3 Le strutture di controllo

Programmazione I. De Marco - Zizza. De Prisco - Senatore. Ritirato. Appello di Luglio (prima prova) 18 luglio Cognome: Nome: Matricola:

Sistemi Operativi (M. Cesati)

Processi in Linux. Stru/ura file eseguibili

Riepilogo sulla Concorrenza

Transcript:

Il protocollo applicativo TCP/IP fornisce gli strumenti per realizzare un protocollo applicativo (gestisce un byte stream). TCP/IP non definisce il protocollo applicativo. Una volta definito, il protocollo applicativo gode di vita propria indipendente dalle singole implementazioni. Esempio di protocollo applicativo Trasmettere stringhe di caratteri a lunghezza variabile (esempio molto comune). Il mittente ed il destinatario concordano che la fine della stringa è sancita dal carattere \0. Il funzionamento è del tutto analogo al meccanismo di cin e cout del C++ (!!). 1

Un esempio di client/server Interprete comandi distribuito. Viene utilizzato il seguente protocollo: il client si connette al server e gli invia un comando (di un solo carattere): a è il comando senza parametri; b è il comando seguito da alcuni parametri, in formato stringa; il server esegue il comando specificato ed invia come risposta una stringa terminata da *\n. Interprete comandi distribuito Il client riconosce, nella risposta inviata dal server, la stringa *\n. Deve quindi essere in grado di distinguere: *a\n ; *x\n ; x*a\n ; a***********\n. 2

La macchina a stati finiti Consente di descrivere il funzionamento di un sistema individuando: uno stato iniziale (a t=0); gli stati nei quali il sistema può trovarsi; le transizioni di stato (da uno stato corrente ad uno stato successivo); gli ingressi che causano una transizione di stato; uno o piu stati finali. E anche detta fsm (finite state machine). Funzionamento del client Invia comando E-/E Chiudi conn. A-/A B-/B arg Attendi risposta -(!= \n )/- -(!= * )/- - * /- - \n /- Attendi \n - * /- Notazione: xy/z: x = input da terminale y = input dal server z = output verso il server - indica informazione irrilevante 3

Funzionamento del server Dialogo di connessione Attesa conness. \0 /- E/- Notazione: x/z : x = input dal client z = output verso il client - indica uscita irrilevante Esegui A Leggi param. 2!= \0 /-!= \0 /- A/- B/- Attesa comando Leggi param. 1 \0 /- -/ risposta -/ *\n Termina risposta -/ risposta Esegui B Listato di UClient3 (i) #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define PORT 4000 void addr_initialize(); /* programma UCLIENT3 */ void main(int argc, char* argv[]) int sd; struct sockaddr_in server_addr; int error,fine; char command, combuf[2],result; char param1[]="alfa"; char param2[]="beta"; addr_initialize(&server_addr, PORT, inet_addr(argv[1])); sd=socket(af_inet,sock_stream,0); error=connect(sd,(struct sockaddr*) &server_addr,sizeof(server_addr)); 4

Listato di UClient3 (ii) if (error==0) printf("ho eseguito la connessione\n"); while(1) printf("\ninserire il comando seguito da CR:"); read(0,combuf,2); command=combuf[0]; send(sd,&command,1,0); if (command=='e') break; if (command=='b') send(sd,param1,5,0); send(sd,param2,5,0); } fine=0; Listato di UClient3 (iii) } while(fine!=1) recv(sd,&result,1,0); while (result=='*') recv(sd,&result,1,0); if (result=='\n') fine=1; else printf("*");} printf("%c",result); } } printf("\nchiudo la connessione \n"); close(sd); } else printf("%s","\nerrore di connect\n\n"); 5

Listato di UServer3 (i) /* programma USERVER3 */ #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define PORT 4000 #define MAXCONN 5 void addr_initialize(); void main(int argc, char * argv[]) int sd,new_sd; struct sockaddr_in server_addr; struct sockaddr_in client_addr; int client_len=sizeof(client_addr); char inbuf; char rispostaa[]="**il Server ha eseguito il comando A**"; char rispostab[]="**il Server ha eseguito il comando B**"; char errmessage[]="**comando errato**"; char terminatore[2]='*','\n'}; Listato di UServer3 (ii) addr_initialize(&server_addr, PORT, INADDR_ANY); sd=socket(af_inet,sock_stream,0); bind(sd,(struct sockaddr*) &server_addr,sizeof(server_addr)); listen(sd,maxconn); while (1) printf("\nmi pongo in attesa di richieste di connessione\n"); new_sd=accept(sd,(struct sockaddr*) &client_addr, &client_len); printf("ho accettato una connessione\n"); do recv(new_sd,&inbuf,1,0); printf("\nho ricevuto il comando %c",inbuf); switch (inbuf) case 'e':break; case 'a':send(new_sd,rispostaa,sizeof(rispostaa),0); send(new_sd,terminatore,2,0);break;} 6

Listato di UServer3 (iii) } case 'b':printf("\ni parametri sono:"); do recv(new_sd,&inbuf,1,0); printf("%c",inbuf); } while (inbuf!='\0'); printf(" "); do recv(new_sd,&inbuf,1,0); printf("%c",inbuf); } while (inbuf!='\0'); send(new_sd,rispostab,sizeof(rispostab),0); send(new_sd,terminatore,2,0);break;} default:send(new_sd,errmessage,sizeof(errmessage),0); send(new_sd,terminatore,2,0);break;} } } while (inbuf!='e'); close(new_sd); printf("\nchiudo la connessione\n"); } close(sd); 7

8

La programmazione di rete in ambiente multiprocesso Il parallelismo nei server 9

Necessità di parallelismo nei server Server sequenziali: accettano una sola connessione alla volta; non sono pertanto particolarmente utili. E solo una comunicazione tra due processi per volta, eventualmente accodando altri processi che vogliano connettersi allo stesso server (listen); sono anche detti monoconnessione. Necessità di parallelismo nei server Server paralleli: superano i limiti dei server sequenziali sfruttando il meccanismo di parallelismo; utilizzeremo il parallelismo di Unix, trascurando quello di Windows; il client non ha modo di distinguere se si è connesso ad un server sequenziale o ad un server parallelo: può solo accorgersi di una connessione rifiutata. 10

Funzionamento di un server parallelo Il server si pone in attesa di richieste di connessioni (accept) su un port srvport; alla ricezione di una richiesta di connessione (connect del client su srvport), il server crea tramite la fork un nuovo processo detto figlio, identico a se stesso (processo padre, impropriamente detto anche server principale). All interno del server parallelo Dopo la creazione del processo figlio, il padre chiude la connessione col client e rimane in attesa di nuove richieste di connect, che utilizzeranno sempre lo stesso srvport; Il figlio utilizza il socket aperto dal padre alla connect. Al termine, il figlio chiude la connessione (close) e termina (exit). 11

Funzionamento di base di un server parallelo while (1) /* il server è in un ciclo perenne */ new_sd = accept(sd,...) pid = fork(); if (pid==0) /*sono nel figlio */ /*esegui le richieste del client utilizzando il socket connesso new_sd; alla fine chiudi new_sd ed esegui exit */ } else /* sono nel padre */ /*chiudi new_sd e riprendi ad eseguire la accept su sd */ } } Realizzazione di un server parallelo Modificare UServer3 così da renderlo un server parallelo (UServer4). n.b. sui calcolatori Unix, il tipo pid_t coincide con il tipo int. Verrà quindi utilizzata la dichiarazione del tipo: int p_id; 12

Listato di UServer4 (i) #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define PORT 4000 #define MAXCONN 5 /* programma USERVER4 */ void addr_initialize(); void main(int argc, char * argv[]) int sd,new_sd; int pid; char inbuf; struct sockaddr_in server_addr; struct sockaddr_in client_addr; int client_len=sizeof(client_addr); char rispostaa[]="**il Server ha eseguito il comando A**"; char rispostab[]="**il Server ha eseguito il comando B**"; char errmessage[]="**comando errato**"; char terminatore[2]='*','\n'}; Listato di UServer4 (ii) addr_initialize(&server_addr, PORT, INADDR_ANY); sd=socket(af_inet,sock_stream,0); bind(sd,(struct sockaddr*) &server_addr,sizeof(server_addr)); listen(sd,maxconn); while (1) printf("\nmi pongo in attesa di richieste di connessione\n"); new_sd=accept(sd,(struct sockaddr*) &client_addr, &client_len); printf("ho accettato una connessione da: %d\n", ntohs(client_addr.sin_port)); pid=fork(); 13

Listato di UServer4 (iii) if (pid==0) do recv(new_sd,&inbuf,1,0); printf("ho ricevuto il comando %c ",inbuf); printf("da: %d \n", ntohs(client_addr.sin_port)); switch (inbuf) case 'e':break; case 'a':send(new_sd,rispostaa, sizeof(rispostaa),0); send(new_sd,terminatore,2,0);break;} case 'b':printf("i parametri sono: "); dorecv(new_sd,&inbuf,1,0); printf("%c",inbuf); }while (inbuf!='\0'); printf(" "); do recv(new_sd,&inbuf,1,0); printf("%c",inbuf); }while (inbuf!='\0'); printf(" \n"); send(new_sd,rispostab,sizeof(rispostab),0); send(new_sd,terminatore,2,0);break;} Listato di UServer4 (iv) default:send(new_sd,errmessage, sizeof(errmessage),0); send(new_sd,terminatore,2,0);break;} } } while (inbuf!='e'); printf("\nchiudo la connessione con: %d\n\n", ntohs(client_addr.sin_port)); close(new_sd); exit(); } /* chiude if (pid == 0) */ close(new_sd); /* il padre chiude il socket che */ /* viene utilizzato dal figlio */ } /* chiude while (1) */ } /* chiude main */ 14

Esecuzione di UServer4 Consideriamo ora un esempio di esecuzione di UServer4 che accetta connessioni da 3 distinti processi, rispettivamente C1, C2 e C3. C1, C2 e C3 sono esecuzioni del programma UClient3 (o WClient3). UClient3 non ha modo di riconoscere se il server cui si collega è sequenziale o parallelo. Esecuzione di UServer4 I processi figli di UServer4 utilizzano la stessa sessione di terminale del processo padre. I messaggi del padre e dei figli saranno alternati su una unica finestra. 15

Avvio di UServer4 C1 esegue il comando a 16

Avvio di C2 C2 esegue i comandi a e b 17

C1 esegue il comando x C2 esegue il comando y 18

Avvio di C3 C3 esegue il comando a 19

C2 chiude la connessione C1 esegue il comando b 20

C3 esegue il comando 3 C3 chiude la connessione 21

C1 chiude la connessione Invocazione di programmi di servizio Un server presenta un interfaccia attraverso cui differenti client richiedono a quel server l esecuzione di programmi già esistenti. Il server parallelo (fork e generazione di figlio per ogni connessione ricevuta) deve: eseguire il programma, specificato dal client, tramite una exec passandogli il descrittore del socket; attendere il termine del programma (wait). 22

UServer5 Rispetto a Userver4: è sempre multiprocesso, quindi per ogni connessione esegue una fork; ad ogni richiesta dal client, genera un ulteriore processo (tramite una fork) che esegue il comando indicato dal client (tramite la execve); passa al programma invocato (MainA o MainB) il descrittore del socket per comunicare col client. Listato di UServer5 (i) #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define PORT 4000 #define MAXCONN 5 /* programma USERVER5 */ void addr_initialize(); void main(int argc, char * argv[]) int sd,new_sd; char inbuf; struct sockaddr_in server_addr; struct sockaddr_in client_addr; int client_len=sizeof(client_addr); char errmessage[]="**comando errato**"; /* rispetto a UServer4 mancano */ char terminatore[2]='*','\n'}; /* rispostaa e rispostab */ char sdstring[7]; /* nuovo rispetto a UServer4 */ char *envp[3] = NULL, NULL, NULL}; int pid,my_pid,status; 23

Listato di UServer5 (ii) addr_initialize(&server_addr, PORT, INADDR_ANY); sd=socket(af_inet,sock_stream,0); bind(sd,(struct sockaddr*) &server_addr,sizeof(server_addr)); listen(sd,maxconn); while (1) printf("\nmi pongo in attesa di richieste di connessione\n"); new_sd=accept(sd,(struct sockaddr*) &client_addr, &client_len); printf("ho accettato una connessione da: %d\n", ntohs(client_addr.sin_port)); pid=fork(); if (pid==0) do recv(new_sd,&inbuf,1,0); printf("ho ricevuto il comando %c ",inbuf); printf("da: %d \n", ntohs(client_addr.sin_port)); Listato di UServer5 (iii) switch (inbuf) case 'e':break; case 'a':sprintf(sdstring,"%d",new_sd); argv[1]=sdstring; pid=fork(); if (pid==0) execve("maina", argv, envp);} else my_pid = wait(&status); break;}} case 'b':sprintf(sdstring,"%d",new_sd); argv[1]=sdstring; pid=fork(); if (pid==0) execve("mainb", argv, envp);} else my_pid = wait(&status); break;}} default: send(new_sd,errmessage, sizeof(errmessage),0); send(new_sd,terminatore,2,0);break;} } /* chiude switch */ } while (inbuf!='e'); /* chiude do */ 24

Listato di UServer5 (iv) printf("\nchiudo la connessione con: %d\n\n", ntohs(client_addr.sin_port)); close(new_sd); exit(); } /* chiude if (pid == 0) */ close(new_sd); /* il padre chiude il socket che */ /* viene utilizzato dal figlio */ } /* chiude while (1) */ } /* chiude main */ Listato di MainA /* programma maina */ void main(int argc, char * argv[]) int sd; char terminatore[2] = '*','\n'}; char rispostaa[] = "**MainA ha eseguito il comando A**"; } printf(" MainA\n"); sd = atoi(argv[1]); send(sd, rispostaa, sizeof(rispostaa),0); send(sd, terminatore,2,0); printf(" MainA: ho terminato\n"); 25

Comunicazione UClient3-MainB La comunicazione tra UClient3 e MainB avviene attraverso il descrittore del socket. UClient3 non si accorge di parlare con MainB: è convinto di parlare con UServer5. MainB riceve sulla linea di comando il descrittore del socket per colloquiare con UClient3. Listato di MainB /* programma mainb*/ void main(int argc, char * argv[]) int sd; char inbuf; char rispostab[] = "**MainB ha eseguito il comando B**"; char terminatore[2] = '*','\n'}; } sd = atoi(argv[1]); printf(" MainB: i parametri sono:"); do recv(sd, &inbuf, 1, 0); printf("%c", inbuf); } while (inbuf!= '\0'); prinf(" "); do recv(sd, &inbuf, 1, 0); printf("%c",inbuf); } while (inbuf!= '\0'); printf("\n" ); send(sd, rispostab, sizeof(rispostab),0); send(sd, terminatore, 2, 0); printf(" MainB: ho terminato\n"); 26

Avvio di UServer5 UClient3 richiede il comando e lo invia al server 27

UServer5 riceve il comando b UServer5 lancia il programma MainB 28

UClient3 riceve i messaggi da MainB UClient3 esegue il comando b 29

UClient3 esegue il comando x UClient3 esegue il comando a 30

UClient3 termina Considerazione conclusive sui server Molti server sono attivati quando la macchina viene accesa e devono rimanere sempre attivi (ad es. server Web). In Unix sono detti daemons. Spesso i daemons non devono disporre di una sessione di interprete comandi e di terminale associati (esecuzione in background). Non dispongono di un terminale associato al processo. 31

Considerazioni conclusive sui server I daemons utilizzano file di log, sui quali scrivono eventuali messaggi di errore. Per alcuni servizi vengono utilizzati port riservati (con numero compreso tra 0 e 1023). Per avviare un server che utilizzi un port riservato è necessario avere i privilegi di gestore del sistema. 32