Socket, introduzione
Per capire cosa sono i socket e come funzionano,
prendiamo in considerazione una banale telefonata.
Per chiamare un amico, ne selezioniamo il numero
sul telefono ed attendiamo che risponda (il suo telefono sara' in attesa
di qualche chiamata). Se non c'e', dopo qualche squillo, arrivera' il segnale
di occupato.
Se invece l'amico c'e', e risponde, possiamo
parlargli finche' vogliamo, cioe' finche' non riattacchiamo.
Quel che accade e' che viene stabilita una connessione, tramite la linea
telefonica, fra il nostro apparecchio e quello dell'altra persona.
Proviamo a sostituire noi e l'amico, adesso,
con due processi di cui uno vuole comunicare con l'altro.
La situazione e' identica a quella della volonta'
di chiamare l'amico via telefono. Il socket,
puo' essere visto come il telefono del processo.
Le funzioni principali che solitamente sono messe
a disposizione per utilizzare i socket, riguardano la creazione, il collegamento
(con una macchina remota), l'attesa su una determinata porta
(una porta, in pratica, puo' essere vista come un'interfaccia fra il computer
ed il mondo esterno), lo scambio di dati e la chiusura del socket.
Vediamo come funziona un tipico scambio dati con
socket. Supponiamo di avere due processi
A che deve spedire un messaggio ad un
altro processo B.
B, a sua volta, deve rispondere opportunamente. Si puo' vedere la cosa
come un invito a cena da parte di un amico (anche se in questo caso la
risposta sara' sempre si').
| Processo A |
|
Processo B |
| |
1 |
Creazione e configurazione
socket.
(contratto telefonico) |
Creazione e configurazione socket.
(contratto telefonico) |
2 |
Attesa di una connessione.
(il telefono puo' ricevere chiamate) |
Tentativo di connessione.
(comporre il numero di telefono) |
3 |
|
| |
4 |
Accettazione della connessione.
(alzare la cornetta) |
| |
5 |
Attesa di un messaggio.
(aspettare che l'altra persona si pronunci) |
Invio del messaggio.
(Invito a cena) |
6 |
|
Attesa di una risposta.
(verra' o non verra'?) |
7 |
Lettura del messaggio ed invio della risposta.
(ma certo che vengo...) |
Lettura risposta.
(Ci vediamo stasera...) |
8 |
Chiusura connessione.
(attaccare la cornetta) |
Chiusura connessione.
(attaccare la cornetta) |
9 |
Attesa di una connessione.
(il telefono puo' ricevere chiamate) |
| Chiusura socket. |
|
|
| ... |
... |
... |
| |
n |
Chiusura socket. |
La tabella mostra lo svolgersi della comunicazione
passo per passo. L'analogia con la comunicazione telefonica e' forte. Per
questo, ogni cella, contiene sia il passo della comunicazione fra i processi
che l'analogo della comunicazione fra amici.
Il tutto puo' essere formalizzato come segue:
| Processo A |
Processo B |
socketA=CreaSocket();
InizializzaSocket(socketA,porta);
Connetti(socketA,Indirizzo di B);
Manda(socketA,messaggio);
risposta=Ricevi(socketA);
ChiudiSocket(socketA);
|
socketB=CreaSocket();
InizializzaSocket(socketB,porta);
socketTemporanea=AttendiConnessione(socketB);
messaggio=Ricevi(socketTemporaneo);
Manda(socketTemporaneo,risposta);
ChiudiSocket(socketTemporaneo);
ChiudiSocket(socketB);
|
Commentiamo quanto scritto.
Innanzitutto vi sono delle supposizioni da fare.
Le funzioni "Ricevi"
ed "AttendiConnessione"
bloccano il flusso del programma finche' non viene ricevuto rispettivamente
un messaggio o una richiesta di connessione. Inoltre, si suppone che: esistano
il tipo socket e le funzioni utilizzate; ogni chiamata alle funzioni della
tabella sottostante non possa provocare errori.
Le funzioni usate hanno il seguente compito:
| CreaSocket |
Crea un socket e lo restituisce come risultato. |
| InizializzaSocket |
Riceve come parametro un socket e dei dati. Inizializza
il socket con i dati ricevuti. |
| AttendiConnessione |
Riceve come parametro un socket e lo pone in
ascolto per eventuali richieste di connessione.
Restituisce un nuovo socket inizializzato alla
comunicazione con quello che ha effettuato la richiesta. |
| Connetti |
Riceve come parametro un socket ed un indirizzo.
Connette il socket con quello che e' in ascolto all'indirizzo indicato
ed alla porta indicata nella configurazione. |
| Manda |
Riceve come parametro un socket (1) ed un messaggio
da spedire. Manda il messaggio al socket (2) con cui l'(1) e' connesso. |
| Ricevi |
Come Manda, ma riceve un messaggio e lo restituisce
come risultato. |
| ChiudiSocket |
Riceve come parametro un socket e lo chiude definitivamente. |
I socket dei due processi, per essere usati devono
essere configurati. Nel caso del processo A, sara' necessario indicare
la porta (valore numerico) dove il socket con cui si vuole comunicare e'
in ascolto. Per quanto riguarda il processo B, l'inizializzazione prevede
l'assegnazione di una porta su cui attendere una richiesta di connessione.
Per poter comunicare con B, A dovra' prima connettersi
(Connetti).
La connessione avverra' all'indirizzo indicato. Una volta connesso, A puo'
mandare il messaggio ed attendere la risposta.
Notare che il mezzo tramite il quale avviene
la comunicazione e' il socket stesso. Ecco perche' viene passata la variabile
socketA
sia a "Manda"
che a "Ricevi".
Il significato e' "manda/ricevi il messaggio per mezzo del socket socketA".
Nel processo B, dopo che il socket e' stato inizializzato,
bisognera' attendere una connessione (AttendiConnessione).
Il socketB
rimarra' in attesa di una connessione dall'esterno. Una volta che una richiesta
di connessione e' arrivata, un nuovo socket viene creato automaticamente
e connesso con quello che ha effettuato la richiesta. Per ogni scambio
di dati verra' utilizzato questo nuovo socket. Alla fine delle operazioni,
"socketTemporaneo"
puo' essere chiuso e socketB puo' essere usato per ulteriori connessioni
oppure puo essere chiuso (cio' avviene nel programma di esempio).
|