Upload
ravenna-pepe
View
222
Download
3
Embed Size (px)
Citation preview
C.Brandolese Politecnico di Milano
SocketSocket
Calcolatori Elettronici
Calcolatori Elettronici 2C.Brandolese
SommarioSommario
• Introduzione• Interfaccie e protocolli• Il modello Client/Server• Indirizzamento• Connessione• Strutture dati e costanti• Funzioni di utilità• Gestione dei socket• Esempi
Calcolatori Elettronici 3C.Brandolese
IntroduzioneIntroduzione
• Una applicazione è un insieme di programmi coordinati in modo da svolgere una determinata funzione: la funzione applicativa
• In un ambiente di programmazione usuale una applicazione coincide generalmente con un singolo programma.
• In un ambiente distribuito si parla di applicazioni distribuite• Applicazione distribuita:
• E’ costituita da un insieme di programmi che vengono generalmente eseguiti su macchine diverse
• I vari programmi cooperano attraverso una rete di calcolatori
• Le applicazioni distribuite richiedono la capacità di comunicare attraverso una rete.
Calcolatori Elettronici 4C.Brandolese
IntroduzioneIntroduzione
• I vari programmi che costituiscono una applicazione distribuita devono seguire alcune regole per comunicare in modo corretro
• L’insieme delle regole per la comunicazione prende il nome di protocollo applicativo
• Si noti che, come è ovvio, due programmi comunicano tra di loro solo quando sono in esecuzione: a rigore quindi sono i processi a comunicare sulla base delle istruzioni constenute nei programmi
• Nel seguito si parlerà indifferentemente di processi o di programmi, intendendo quanto appena chiarito
Calcolatori Elettronici 5C.Brandolese
Interfaccie e protocolliInterfaccie e protocolli
• Per la comunicazione i programmi di una applicazione distribuita si appoggiano a un insieme di servizi tipici forniti:• Dal sistema operativo• Dal software di rete
• Il programmatore utilizzare in pratica delle funzioni di libreria• L’insieme delle funzioni di base prende il nome di Application
Program Interface o API• E’ bene notare la differenza tra protocollo applicativo e API:
• Il protocollo applicativo rappresenta le regole per la comunicazione, ma non è un canale diretto di comunicazione
• Le API sono le funzioni che realizzano sul canale fisico le regole di comunicazione definite nel protocollo.
Calcolatori Elettronici 6C.Brandolese
Interfaccie e protocolliInterfaccie e protocolli
• Esempio di applicazione distribuita:
APPLICAZIONE DISTRIBUTA
PROGRAMMAAPPLICATIVO
PROGRAMMAAPPLICATIVO
Sistema Operativoe
Software di Rete
Sistema Operativoe
Software di Rete
Protocollo Applicativo
API API
RETE
Calcolatori Elettronici 7C.Brandolese
Interfaccie e protocolliInterfaccie e protocolli
• Nel seguito faremo riferimento ai sistemi operativi:• UNIX • WindowsNT
• Supporremo inoltre che il software di rete disponibile sia TCP/IP• TCP/IP definisce in maniera astratta alcuni servizi che i vari
sistemi operativi realizzano e rendono disponibili tramite le API• Uno dei servizi forniti dal protocollo TCP/IP è l’interfaccia:
• SOCKET (UNIX)• WINSOKET (WindowsNT)
Calcolatori Elettronici 8C.Brandolese
Interfaccie e protocolliInterfaccie e protocolli
• La configurazione di riferimento di una applicazione distribuita basata su TCP/IP e soket è il seguente:
PROGRAMMA C PROGRAMMA C
UNIX API + SOKET NT API + WINSOKET
UNIX + TCP/IP WindowsNT + TCP/IP
Protocollo Applicativo
Canale
Calcolatori Elettronici 9C.Brandolese
Il modello Client/ServerIl modello Client/Server
• Il protocollo TCP/IP fornisce un meccanismo di comunicazione tra processi residenti su macchine diverse
• Il tipo di comunicazione è detto peer-to-peer (da pari a pari)• Sta al programmatore definire le regole di comunicazione cioè il
protocollo applicativo• Molte applicazioni sono basate sul modello Client/Server• In questo modello una delle applicazioni agisce da Server mentre
le altre agiscono da Client• In generale un processo può assumere il ruolo di Client o di
Server dinamicamente nel tempo
Calcolatori Elettronici 10C.Brandolese
Il modello Client/ServerIl modello Client/Server
• Il processo Server:• Fornisce servizi• Accetta richieste provenienti dai client• Esegue i servizi richiesti• Eventualmente ritorna un risultato al richiedente
• Il processo Client:• Richiede servizi ad un server• Attende una risposta da parte del server
• Ad esempio:• Server: WEBServer• Client: Browser
Calcolatori Elettronici 11C.Brandolese
IndirizzamentoIndirizzamento
• Quando un processo P intende comunicare con un processo Q, in esecuzione su un’altra macchina deve:• Identificare la macchina su cui è in esecuzione Q• Identificare il processo Q fra tutti quelli in esecuzione sulla macchina
• Una macchina è individuata dal suo indirizzo IP:• Un indirizzo IP è un numero di 32 bit univoco all’interno di una rete• Gli indirizzi IP vengono scritti esprimendo il valore decimale dei 4 gruppi di
8 bit che lo compongono, separati da un punto
• Un processo è individuato attraverso un port:• Un port è un numero usato per identificare un processo solo ai fini della
comunicazione TCP/IP• Il port di un processo non ha nessuna relazione con il suo pid
Calcolatori Elettronici 12C.Brandolese
IndirizzamentoIndirizzamento
• Port e pid identificano un processo ma:• Il pid di un processo è assegnato dal sistema operativo ed il
programmatore non ha alcun controllo sul suo valore• Il port viene assegnato dal programmatore
• Affinché il processo P possa comunicare con il processo Q, i due programmi devono stabilire un port con cui identificarsi
• I port da 0 a 1023 sono utilizzati da servizi standard e non possono essere usati dal programmatore
• Un idirizzo TCP completo è quindi costituito dalla coppia:
< IP_Address, Port >
Calcolatori Elettronici 13C.Brandolese
ConnessioneConnessione
• La comunicazione in TCP si dice orientata alla connesione• Questo significa che, prima di poter scambiare dati, due processi
devono stabilire una connessione• In un modello client/server, per stabilire una connessione tra due
processi P e Q è necessario che:• Il processo P, che agisce da server, si metta in attesa di richieste da parte
del processo Q• Il processo Q, che agisce da client, invia richieste al processo P ed
attende una risposta
• Quando il server P accetta una richiesta di un servizio da parte del processo Q si stabilisce la connessione
Calcolatori Elettronici 14C.Brandolese
ConnessioneConnessione
• Aspetti generali di una connessione:• I due processi che stabiliscono una connessione sono detti punti terminali• Ogni processo è identificato dalla coppia <IP_Address, Port>• La connessione è identificata dai suoi punti terminali cioè dalle due coppie <IP_Address, Port> relative appunto ai punti terminali
• Dopo aver stabilito la connessione, i processi dispongono di un canale:• Bidirezionale: la comunicazione può avvenire nelle due direzioni
• Affidabile: un meccanismo di acknowledge garantisce che i dati siano ricevuti
• Orientato allo stream: i dati vengono trasmessi in modo continuo
• Si noti che l’identificazione della connessione consente ad un processo di partecipare a diverse connessioni in quanto TCP le distingue in base agli indirizzi dei punti terminali
Calcolatori Elettronici 15C.Brandolese
Strutture dati e costantiStrutture dati e costanti
• Gli indirizzi di socket sono memorizzati in una struttura dati C:
• Il significato dei campi è il seguente• sin_family: famiglia degli indirizzi. Nel nostro caso AF_INET.• sin_port: numero del port. Compreso tra 0 e 64k• sin_addr: indirizzo IP. Si tratta di una union di cui useremo solo il
campo s_addr di tipo u_long, cioè intero a 32 bit
senza segno• sin_zero: non utilizzato
struct sockaddr_in { short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8];
Calcolatori Elettronici 16C.Brandolese
Strutture dati e costantiStrutture dati e costanti
• Sono definiti alcuni gruppi di costanti• Costanti per la definizione del tipo di indirizzo
• AF_UNIX: Indirizzi ARPA, locali alle macchine• AF_INET: Indirizzi Internet
• Costanti per la definizione del tipo di comunicazione:• SOCK_STREAM: Orientata allo stream• SOCK_DGRAM: Datagram• SOCK_RAW: Raw data
• Queste costanti vengono utilizzate nella creazione dei socket e nella definizione degli indirizzi
Calcolatori Elettronici 17C.Brandolese
Funzioni di utilitàFunzioni di utilità
• Conversione da stringa a indirizzo IP:
• Conversione da formato host a formato network
• Conversione da formato network a formato host
uint32_t htonl(unint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
unsigned long inet_addr(const char *cp);
Calcolatori Elettronici 18C.Brandolese
Gestione dei socketGestione dei socket
• Creazione di un socket:
• I parametri hanno il seguente significato:• domain: famiglia di protocolli, nel nostro caso AF_INET• type: tipo di connessione, nel nostro caso SOCK_STREAM• protocol: tipo di protocollo, nel nostro caso esiste solo il
protocollo IPquindi questio parametro vale generalmente 0
• Crea un socket con le caratteristiche specificate e restituisce un descrittore
• Il descrittore è simile al descrittore utilizzato per la gestione dei files
int socket(int domain, int type, int protocol);
Calcolatori Elettronici 19C.Brandolese
Gestione dei socketGestione dei socket
• Chiusura di un socket:
• I parametri hanno il seguente significato:• socket: descrittore di socket
• Chiude il socket individuato dal descrittore specificato• Dopo la chiusura, il socket non è più accessibile
int close(int socket);
Calcolatori Elettronici 20C.Brandolese
Gestione dei socketGestione dei socket
• Associazione di un socket ad un indirizzo locale:
• I parametri hanno il seguente significato:• s: descrittore di socket• locaddr: indirizzo IP local al quale il socket viene associato• locaddrlen: dimensioni della struttura dati utilizzata per
specificare l’indirizzo locale. Generalmente si ottiene tramite la funzione standard sizeof()
• Lega il socket il cui descrittore è s all’indirizzo locale specificato nella struttura dati locaddr.
• Questa funzione associa al socket uno dei due punti terminali
int bind(int s, struct sockaddr *locaddr, int locaddrlen);
Calcolatori Elettronici 21C.Brandolese
Gestione dei socketGestione dei socket
• Dimensione della coda di un socket:
• I parametri hanno il seguente significato:• s: descrittore di socket• backlog: dimensione massima della coda di richieste
• Specifica il numero massimo di richieste che possono essere messe in coda sul socket s
• Una richiesta che arrivi quando la coda è piena viene rifutata ed il processo richiedente riceve un messaggio di errore
int listen(int s, int backlog);
Calcolatori Elettronici 22C.Brandolese
Gestione dei socketGestione dei socket
• Accettazione di una richiesta di connessione:
• I parametri hanno il seguente significato:• s: descrittore di socket• destaddr: indirizzo del processo richiedente• destaddrlen: dimensione della struttura dati contenete l’indirizzo
del processo richiedente
• Accetta la prima richiesta di connessione in coda, crea un nuovo socket e ne restituisce il descrittore
• Il socket creato non può più essere utilizzato per accettare altre richieste mentre il socket originale si
int accept(int s, struct sockaddr *destaddr, int *destaddrlen);
Calcolatori Elettronici 23C.Brandolese
Gestione dei socketGestione dei socket
• Crea una connessione:
• I parametri hanno il seguente significato:• s: descrittore di socket• destaddr: indirizzo del processo remoto richiedente• destaddrlen: dimensione della struttura dati contenete l’indirizzo
del processo richiedente
• Crea una connessione, nel nostro caso TCP/IP, con il richiedente il cui indirizzo è specificato dagli ultimi due parametri
• Dopo la creazione della connessione i due processi possono iniziare lo scambio di dati
int connect(int s, struct sockaddr *destaddr, int *destaddrlen);
Calcolatori Elettronici 24C.Brandolese
Gestione dei socketGestione dei socket
• Scrive/legge dati attraverso un socket:
• I parametri hanno il seguente significato:• fd: descrittore di socket (o di file)• buf: puntatore all’area dati• nbyte: dimensione dei dati
• Legge o scrive dati attraverso un socket• Queste funzioni sono le stesse utlizzate per la lettura scrittura di
dai da/verso i files
int write(int fd, char *buf, int nbyte);
int read (int fd, char *buf, int nbyte);
Calcolatori Elettronici 25C.Brandolese
Esempio: Client/Server – Singola connessioneEsempio: Client/Server – Singola connessione
• Il server:• Legge dalla linea di comando il numero di porta• crea un socket su quella porta • Aspetta chiamate
• Ogni volta che arriva una chiamata:• Legge da socket un comando e lo esegue • Scrive il risultato sullo stesso socket• Chiude la connessione • Si rimette in attesa
• Il ciclo di attesa non termina mai• Per terminare il processo server occorre ucciderlo (kill) esplicitamente
Calcolatori Elettronici 26C.Brandolese
Esempio: Client/Server – Singola connessioneEsempio: Client/Server – Singola connessione
• Il client: • Legge dalla linea di comando l'indirizzo IP e il numero di port del server• Crea un socket• Si connette al server• Legge un comando da standard input • Invia il comando al server• Legge la risposta• Trascrive la risposta su standard output • Chiude la connessione • Termina
• Ogni volta che il client è invocato comunica un solo comando al server
Calcolatori Elettronici 27C.Brandolese
Esempio: Client/Server – Singola connessioneEsempio: Client/Server – Singola connessione
• Il server è organizzato come segue:• Creazione del socket socket()
• Inizializzazione dell’indirizzo: • contenuto nella variabile server_addr • il tipo è struct sockaddr_in
• Binding del socket bind()
• Definizione del numero massimo di connessioni listen()
• Ciclo infinito, in cui:• Accetta una connessione accept()• Legge un comando da socket read()• Scrive il risultato dell’esecuzione del comando su socket write()• Termina la connessione close()
Calcolatori Elettronici 28C.Brandolese
Esempio: Client/Server – Singola connessioneEsempio: Client/Server – Singola connessione
#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h> #define MAX_CONN 5 int main(int argc, char* argv[]){ int sock_fd; int new_sock_fd; int client_len; struct sockaddr_in server_addr; struct sockaddr_in client_addr; char command;
if( argc != 2 ){ printf(“Numero di parametri errato\n”); exit(1); }
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
...
SERVER
Calcolatori Elettronici 29C.Brandolese
Esempio: Client/Server – Singola connessioneEsempio: Client/Server – Singola connessione
...
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons((u_short) atoi(argv[1]));
bind( sock_fd,
(struct sockaddr *) &server_addr,
sizeof(server_addr)
);
listen(sock_fd, MAX_CONN);
...
SERVER
Calcolatori Elettronici 30C.Brandolese
Esempio: Client/Server – Singola connessioneEsempio: Client/Server – Singola connessione
... while(1) { new_sock_fd = accept( sock_fd, (struct sockaddr *) &client_addr,
&client_len ); read(new_sock_fd, &command, 1); switch (command) { case 'a': write(new_sock_fd, "SERVICE_A", strlen("SERVICE_A") ); break; case 'b': write(new_sock_fd, "SERVICE_B", strlen("SERVICE_B") ); break; default: write(new_sock_fd, "UNKNOWN", strlen("UNKNOWN") ); break; } close(new_sock_fd); }}
SERVER
Calcolatori Elettronici 31C.Brandolese
Esempio: Client/Server – Singola connessioneEsempio: Client/Server – Singola connessione
• Il client è organizzato come segue:• Creazione del socket socket()
• Inizializzazione dell’indirizzo: • L’indirizzo IP è in argv[1] • Il port del server è in argv[2]
• Connessione al server connect()
• Legge un comando da standard input• Scrive il comando sul soket write()
• Legge il risultato dal socket read()
• Scrive il risultato sullo standard output• Chiude il socket e termina close()
Calcolatori Elettronici 32C.Brandolese
Esempio: Client/Server – Singola connessioneEsempio: Client/Server – Singola connessione
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char* argv[]) {
int sock_fd;
int err;
struct sockaddr_in server_addr;
char command;
char result;
if (argc != 3) {
printf(“Numero di parametri errato\n”);
exit(1);
}
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
...
CLIENT
Calcolatori Elettronici 33C.Brandolese
Esempio: Client/Server – Singola connessioneEsempio: Client/Server – Singola connessione
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr( argv[1] );
server_addr.sin_port = htons( (u_short)atoi(argv[2]) );
err = connect( sock_fd,
(struct sockaddr *) &server_addr,
sizeof(server_addr)
);
if( err < 0 ) exit(1);
read(0, &command, 1);
write(sock_fd, &command, 1);
while( read( sock_fd, &result, 1 ) )
write( 1, &result, 1 );
close( sock_fd );
}
CLIENT
Calcolatori Elettronici 34C.Brandolese
Esempio: Client/Server – Più connessioniEsempio: Client/Server – Più connessioni
• Il server: • Legge dalla linea di comando il numero di porta• Crea un socket su quella • Aspetta chiamate
• Ogni volta che arriva una chiamata:• Genera un processo figlio, che gestirà la connessione• Il processo padre chiude la connessione e si rimette in attesa• Il processo figlio legge da socket un comando• Esegue il comando e scrive il risultato sullo stesso socket• Ripete la sequenza di gestione dei comandi finché non riceve il comando
di uscita• Chiude la connessione e termina
Calcolatori Elettronici 35C.Brandolese
Esempio: Client/Server – Più connessioniEsempio: Client/Server – Più connessioni
• Il server è organizzato come segue:• Creazione del socket socket()
• Inizializzazione dell’indirizzo: • contenuto nella variabile server_addr • il tipo è struct sockaddr_in
• Binding del socket bind()
• Definizione del numero massimo di connessioni listen()
• Ciclo infinito, in cui:• Accetta una connessione e crea un figlio
accept()• Il figlio legge un comando da socket read()• Il figlio scrive un risultato sul socket write()• Il figlio terminala connessione close()• Il padre terminala connessione close()
Calcolatori Elettronici 36C.Brandolese
Esempio: Client/Server – Più connessioniEsempio: Client/Server – Più connessioni
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define MAX_CONN 5
int main(int argc, char* argv[])
{
int sock_fd, new_sock_fd;
int client_len;
int pid;
char command;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
if (argc != 2) {
printf(“Numero di parametri errato\n”);
exit(1);
}
SERVER
Calcolatori Elettronici 37C.Brandolese
Esempio: Client/Server – Più connessioniEsempio: Client/Server – Più connessioni
...
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons((u_short) atoi(argv[1]));
bind( sock_fd,
(struct sockaddr *) &server_addr,
sizeof(server_addr)
);
listen(sock_fd, MAX_CONN);
...
SERVER
Calcolatori Elettronici 38C.Brandolese
Esempio: Client/Server – Più connessioniEsempio: Client/Server – Più connessioni
while( 1 ) {
new_sock_fd = accept( sock_fd,
(struct sockaddr *) &client_addr,
&client_len
);
pid = fork();
if( pid == 0 ) {
do {
read( new_sock_fd, &command, 1 );
execute_command( new_sock_fd, command );
} while( command != 'q‘ );
close( new_sock_fd );
exit( 0 );
} else {
close( new_sock_fd ); } }}
SERVER
child
Calcolatori Elettronici 39C.Brandolese
Esempio: Client/Server – Più connessioniEsempio: Client/Server – Più connessioni
• Il server si aspetta una sequenza di comandi terminata dal carattere q
• I client gestiscono una sequenza di comandi• Nel codice seguente si mostra solamente ciò che accade dopo
l’apertura della connessione• La parte di codeice del client qui omessa è molto simile al codice
visto per la connessione singola
Calcolatori Elettronici 40C.Brandolese
Esempio: Client/Server – Più connessioniEsempio: Client/Server – Più connessioni
#define MAXSTR 4096
char command;
int nbytes;
char buf[MAXSTR];
...
while( 1 ) {
read( 0, &command, 1 );
write( sock_fd, &command, 1 );
if( command == ‘q‘ )
break;
nbytes = read( sock_fd, buf, MAXSTR);
write( 1, buf, nbytes );
}
close( sock_fd );
}
CLIENT