cerca
Socket Library
modifica cronologia stampa login logout

Wiki

UniCrema


Materie per semestre

Materie per anno

Materie per laurea


Help

Return to Socket Library  (Edit)

Uni.SocketLibrary History

Hide minor edits - Show changes to output

Changed line 3 from:
[[Torna alla pagina di Sistemi Anticoncezionali delle Reti e dei Damiani->Sistemi]]
to:
[[Torna alla pagina di Sistemi per l'elaborazione delle informazioni->Sistemi]]
Changed line 296 from:
[[Torna alla pagina di Sistemi Anticoncezionali delle Reti e dei Damiani->Sistemi]]
to:
[[Torna alla pagina di Sistemi per l'elaborazione delle informazioni->Sistemi]]
Deleted lines 29-30:

%rframe%http://images.askmen.com/galleries/celeb-profiles-actress/donna-feldman/pictures/donna-feldman-picture-2.jpg
Added line 31:
%rframe%http://images.askmen.com/galleries/celeb-profiles-actress/donna-feldman/pictures/donna-feldman-picture-2.jpg
Changed line 162 from:
%lframe%http://www.yandy.com/Images/Products/4507Full585381127.jpg
to:
%rframe%http://www.yandy.com/Images/Products/4507Full585381127.jpg
Added line 72:
%rframe%http://dr.buzzenstein.com/wp-content/uploads/2007/07/lingeriebowl.jpg
Deleted line 80:
%rframe%http://dr.buzzenstein.com/wp-content/uploads/2007/07/lingeriebowl.jpg
Changed line 31 from:
%lframe width=300%http://images.askmen.com/galleries/celeb-profiles-actress/donna-feldman/pictures/donna-feldman-picture-2.jpg
to:
%rframe%http://images.askmen.com/galleries/celeb-profiles-actress/donna-feldman/pictures/donna-feldman-picture-2.jpg
Added lines 30-31:

%lframe width=300%http://images.askmen.com/galleries/celeb-profiles-actress/donna-feldman/pictures/donna-feldman-picture-2.jpg
Deleted line 55:
%lframe width=300%http://images.askmen.com/galleries/celeb-profiles-actress/donna-feldman/pictures/donna-feldman-picture-2.jpg
Added line 80:
%rframe%http://dr.buzzenstein.com/wp-content/uploads/2007/07/lingeriebowl.jpg
Deleted line 113:
%rframe%http://dr.buzzenstein.com/wp-content/uploads/2007/07/lingeriebowl.jpg
Added line 163:
%lframe%http://www.yandy.com/Images/Products/4507Full585381127.jpg
Deleted line 216:
%lframe%http://www.yandy.com/Images/Products/4507Full585381127.jpg
Added lines 8-9:
Data la noiosità della materia trattata, l'esposizione dei contenuti sarà intervallata ad immagini di donne in pose discinte (uomini solo a richiesta).
Added line 54:
%lframe width=300%http://images.askmen.com/galleries/celeb-profiles-actress/donna-feldman/pictures/donna-feldman-picture-2.jpg
Added line 112:
%rframe%http://dr.buzzenstein.com/wp-content/uploads/2007/07/lingeriebowl.jpg
Added line 215:
%lframe%http://www.yandy.com/Images/Products/4507Full585381127.jpg
Added lines 103-104:
Un'altra cosa da ricordare è che se specifico ''sin_port'' = 0, il sistema mi troverà la prima porta disponibile in automatico.
Changed line 8 from:
>>left bgcolor=#f5f9fc width=260px border='2px solid #cccccc' padding=5px<<
to:
>>left bgcolor=#f5f9fc width=270px border='2px solid #cccccc' padding=5px<<
Changed line 8 from:
>>left bgcolor=#f5f9fc width=250px border='2px solid #cccccc' padding=5px<<
to:
>>left bgcolor=#f5f9fc width=260px border='2px solid #cccccc' padding=5px<<
Changed line 8 from:
>>left bgcolor=#f5f9fc width=280px border='2px solid #cccccc' padding=5px<<
to:
>>left bgcolor=#f5f9fc width=250px border='2px solid #cccccc' padding=5px<<
Changed line 8 from:
>>left bgcolor=#f5f9fc width=300px border='2px solid #cccccc' padding=5px<<
to:
>>left bgcolor=#f5f9fc width=280px border='2px solid #cccccc' padding=5px<<
Added line 2:
[[#su]]
Added lines 23-24:
# [[#s13|Funzione send]]
# [[#s14|Funzione recv]]
Added lines 35-37:
[[#su|[-'''Torna su'''-]]]
Added lines 48-50:
[[#su|[-'''Torna su'''-]]]
Changed lines 55-56 from:
%soluzione%''int'' socket (''int'' pf, ''int'' type, protocol)
to:
%soluzione%sockid = socket (pf, type, protocol)
Added lines 72-74:
[[#su|[-'''Torna su'''-]]]
Added lines 103-105:
[[#su|[-'''Torna su'''-]]]
Changed lines 110-111 from:
%soluzione%''int'' bind (''int'' sockid, ''const struct sockaddr'' *localaddr, ''socklen_t'' addrlen)
to:
%soluzione%status = bind (sockid, &localaddr, addrlen)
Added lines 119-121:
[[#su|[-'''Torna su'''-]]]
Added lines 134-136:
[[#su|[-'''Torna su'''-]]]
Changed lines 141-142 from:
%soluzione%''int'' connect (''int'' sockid, ''const struct sockaddr'' *destaddr, ''socklen_t'' addrlen)
to:
%soluzione%status = connect (sockid, &destaddr, addrlen)
Added lines 152-154:
[[#su|[-'''Torna su'''-]]]
Changed lines 159-160 from:
%soluzione%''int'' listen (''int'' sockid, ''int'' queuelen)
to:
%soluzione%status = listen (sockid, queuelen)
Added lines 169-171:
[[#su|[-'''Torna su'''-]]]
Changed lines 176-177 from:
%soluzione%''int'' accept (''int'' sockid, ''struct sockaddr'' *addr, ''socklen_t'' *addrlen)
to:
%soluzione%s = accept (sockid, &addr, &addrlen)
Added lines 195-197:
[[#su|[-'''Torna su'''-]]]
Added lines 205-207:
[[#su|[-'''Torna su'''-]]]
Changed lines 212-213 from:
%soluzione%''int'' close (''int'' sockid)
to:
%soluzione%status = close (sockid)
Added lines 224-226:
[[#su|[-'''Torna su'''-]]]
Changed lines 233-234 from:
%soluzione%''int'' select (''int'' nfds, ''fd_set'' *readfds, ''fd_set'' *writefds, ''fd_set'' *exceptfds, ''struct timeval'' *timeout)
to:
%soluzione%status = select (nfds, &readfds, &writefds, &exceptfds, &timeout)
Changed lines 242-243 from:
La funzione ''select'' restituisce i descrittori dell'insieme dei descrittori dei socket che sono pronti, ''-1'' in caso di errore.
to:
La funzione ''select'' restituisce i descrittori dell'insieme dei descrittori dei socket che sono pronti, o ''-1'' in caso di errore.
Added lines 246-287:
[[#su|[-'''Torna su'''-]]]


[[#s13]]
!!!Funzione send
Ora che sappiamo come creare e gestire le connessioni, vogliamo anche farci qualcosa. Per inviare dati posso utilizzare la funzione ''send''.

%soluzione%count = send (sockid, &buf, len, flags)

, dove:
* '''sockid''' è il descrittore del socket da utilizzare;
* '''buf''', sta per buffer, è la stringa dei caratteri che devono essere inviati;
* '''len''' è un intero che indica la dimensione di ''buf'' in byte;
* '''flags''' è un intero che consente al mittente di specificare alcune opzioni speciali di invio. Viene generalmente lasciato a 0.

La funzione ''send'' restituisce il numero dei byte trasmessi, o ''-1'' in caso di errore.

La ''send'' è ''bloccante'', ovvero non ritorna finché non vengono immessi dei dati nel buffer.

[[#su|[-'''Torna su'''-]]]


[[#s14]]
!!!Funzione recv
A che serve mandare dati con la ''send'' se poi non abbiamo modo di riceverli? Ecco a cosa serve la ''recv''.

%soluzione%count = recv (sockid, &buf, len, flags)

, dove:
* '''sockid''' è il descrittore del socket da utilizzare;
* '''buf''' specifica l'indirizzo di memoria in cui va memorizzato il messaggio;
* '''len''' è un intero che indica la dimensione di ''buf'' in byte;
* '''flags''' è un intero che consente al chiamante di controllare la ricezione. Anche in questo caso viene generalmente lasciato a 0.

La funzione ''recv'' restituisce il numero dei byte ricevuti, o ''-1'' in caso di errore.

La ''recv'' è ''bloccante'', ovvero non ritorna finché non vengono ricevuti dei dati.

Da notare infine che sia la ''send'' che la ''recv'' sono pensate per socket che supportano le connessioni. I SOCK_DGRAM, ad esempio, utilizzeranno altre funzioni come ad esempio la ''sendto'' e la ''recvto'' in cui verranno specificati anche gli indirizzi di destinazione/partenza.

[[#su|[-'''Torna su'''-]]]
Changed lines 195-198 from:
Un sistema per risolvere il problema l'abbiamo già visto con la ''fork()'' e quindi con la gestione simultanea delle richieste.

%soluzione%''int'' accept (''int'' sockid, ''struct sockaddr'' *addr, ''socklen_t''
*addrlen)
to:
Un sistema per risolvere il problema l'abbiamo già visto con la ''fork()'' e quindi con la gestione simultanea delle richieste. Un altro è fare in modo che uno stesso processo possa attendere delle connessioni su più di un socket. Questo sistema avviene utilizzando la funzione ''select''.

%soluzione%''int'' select (''int'' nfds, ''fd_set''
*readfds, ''fd_set'' *writefds, ''fd_set'' *exceptfds, ''struct timeval'' *timeout)
Changed lines 200-207 from:
* '''sockid''' è il descrittore intero del socket su cui il server ascolta le richieste di connessione;
*
'''addr''' è l'indirizzo del client che ha richiesto la connessione (tale campo viene dunque riempito solo a richiesta avvenuta);
* '''addrlen''' è un intero che indica la dimensione di
''addr'' in byte.

La funzione ''accept'' restituisce un intero positivo in caso di successo (il descrittore del nuovo socket) in caso di successo e ''-1'' in caso di errore
.

[...segue...]
to:
* '''nfds''' è il numero dei descrittori da esaminare (che vanno da 2 a ''nfds-1'');
*
'''readfds''' è l'elenco dei descrittori da controllare perchè pronti alla lettura;
* '''writefds''' è l'elenco dei descrittori da controllare perchè pronti alla scrittura;
*
'''exceptfds''' è l'elenco dei descrittori da controllare perchè si è verificata un’eccezione;
* '''timeout''' specifica un tempo massimo di attesa prima che la funzione ritorni. Se è impostato a NULL (tempo infinito), la funzione attende indefinitamente; se è 0, significa che la chiamata blocca l'esecuzione finché un descrittore non è pronto
.

La funzione ''select'' restituisce i descrittori dell'insieme dei descrittori dei socket che sono pronti, ''-1'' in caso di errore.

Generalmente viene usata quando il numero dei socket da gestire è basso
.
Added lines 20-21:
# [[#s11|Chiusura del socket]]
# [[#s12|Funzione select]]
Added lines 175-205:
[[#s11]]
!!!Chiusura del socket
Abbiamo parlato più di una volta di ''chiusura'' del socket senza spiegare come si fa. E' presto detto:

%soluzione%''int'' close (''int'' sockid)

, dove:
* '''sockid''' è il descrittore intero del socket da chiudere.

La funzione ''close'' restituisce 0 in caso di successo e ''-1'' in caso di errore.

Tre precisazioni:
# se più di un processo ha lo stesso socket aperto, questo non verrà chiuso finché non sarà invocata una ''close'' su ognuno di essi;
# se un processo termina per una qualsiasi ragione, tutti i socket che utilizzava saranno chiusi automaticamente dal sistema;
# una volta chiuso il socket, la porta che utilizzava diventa di nuovo disponibile.

[[#s12]]
!!!Funzione select
Se per programmi semplici il fatto di avere funzioni bloccanti (come la connect o la accept) può essere utili, per quelli più complessi aumentano i problemi. Ad esempio, come saranno gestite le connessioni multiple? E cosa succederà nel caso di connessioni simultanee? Si finirà irrimediabilmente per saturare la coda dei client in attesa, continuando a scartare nuove richieste.

Un sistema per risolvere il problema l'abbiamo già visto con la ''fork()'' e quindi con la gestione simultanea delle richieste.

%soluzione%''int'' accept (''int'' sockid, ''struct sockaddr'' *addr, ''socklen_t'' *addrlen)

, dove:
* '''sockid''' è il descrittore intero del socket su cui il server ascolta le richieste di connessione;
* '''addr''' è l'indirizzo del client che ha richiesto la connessione (tale campo viene dunque riempito solo a richiesta avvenuta);
* '''addrlen''' è un intero che indica la dimensione di ''addr'' in byte.

La funzione ''accept'' restituisce un intero positivo in caso di successo (il descrittore del nuovo socket) in caso di successo e ''-1'' in caso di errore.
Changed lines 168-172 from:
to:
Una volta accettata una connessione, il server ha due approcci diversi per gestire le richieste:
* '''interattivamente'''. Il server gestisce direttamente la richiesta, chiude il nuovo socket e richiama quindi la ''accept'' per passare alla richiesta di connessione successiva;
* '''simultaneamente'''. Il server crea un processo secondario che eredita una copia del nuovo socket, e gli delega la gestione della richiesta. Una volta evasa, il modulo secondario chiude il socket e termina. Nel frattempo il processo server principale chiude la sua copia del socket dopo aver attivato quello secondario, e chiama ''accept'' per passare alla richiesta di connessione successiva.\\
La chiamata di sistema ''fork()'' consente di creare processi secondari, anche detti ''processi figli'' per distinguerli dai ''processi padri'' di cui sono una copia. L'unica differenza tra i due è il valore di ritorno della stessa ''fork'', che vale 0 nel processo figlio ed un numero positivo nel processo padre (che sarebbe poi l'identificativo del figlio) se l'operazione è andata a buon fine.
Added lines 17-19:
# [[#s8|Funzione listen]]
# [[#s9|Funzione accept]]
# [[#s10|Gestione delle richieste]]
Added lines 112-113:
Da notare che tutto ciò accade solo su quei socket che supportano la connessione, come ad esempio SOCK_STREAM. Per il SOCK_DGRAM (tipico delle UDP), ad esempio, non accade nulla di tutto questo.
Added lines 129-168:
[[#s8]]
!!!Funzione listen
Una volta che il socket è stato creato e assegnato a una porta locale, al server per completare la procedura di ''apertura passiva'' non rimane altro che eseguire la funzione ''listen'', che mette il socket in modalità passiva e specifica una lunghezza della coda per le richieste di connessione.

%soluzione%''int'' listen (''int'' sockid, ''int'' queuelen)

, dove:
* '''sockid''' è il descrittore intero del socket pronto per essere usato dal server;
* '''queuelen''' è il numero massimo di partecipanti attivi che possono attendere una connessione. Quando il limite viene raggiunto, le richieste di connessione successive vengono ignorate e scartate.

La funzione ''listen'' restituisce 0 in caso di successo e ''-1'' in caso di errore.

La ''listen'' è ''non-bloccante'', ovvero ritorna subito, e può essere usata solo per socket che supportano le connessioni.

[[#s9]]
!!!Funzione accept
Completata l'apertura passiva, grazie alla funzione ''accept'' il server blocca tutto e si mette in attesa di richieste di connessione.

%soluzione%''int'' accept (''int'' sockid, ''struct sockaddr'' *addr, ''socklen_t'' *addrlen)

, dove:
* '''sockid''' è il descrittore intero del socket su cui il server ascolta le richieste di connessione;
* '''addr''' è l'indirizzo del client che ha richiesto la connessione (tale campo viene dunque riempito solo a richiesta avvenuta);
* '''addrlen''' è un intero che indica la dimensione di ''addr'' in byte.

La funzione ''accept'' restituisce un intero positivo in caso di successo (il descrittore del nuovo socket) in caso di successo e ''-1'' in caso di errore.

Vediamo passo passo cosa succede:
# la ''accept'' estrae da ''sockid'' la prima richiesta di connessione che attende in coda. Se non sono presenti, si blocca finché non ne arriva una;
# la chiamata della funzione viene completata riempendo l'argomento ''addr'' con l'indirizzo del client richiedente e l'argomento ''addrlen'' calcolato di conseguenza;
# viene creato un nuovo socket con le stesse caratteristiche di ''sockid'', la cui destinazione è connessa al client chiamante. Il descrittore del nuovo socket è quello restituito dalla ''accept'';
# viene ritornato il descrittore del nuovo socket al client richiedente.

Mentre vengono eseguiti i punti 3 e 4, il socket ''sockid'' originale non viene toccato e resta nello stato di ''listen''.

La funzione ''accept'', lo abbiamo visto, è decisamente ''bloccante''.

[[#s10]]
!!!Gestione delle richieste
Added lines 15-16:
# [[#s6|Creazione della connessione]]
# [[#s7|Funzione connect]]
Changed lines 54-55 from:
La funzione ''socket'' ritorna un intero positivo in caso di successo e ''-1'' in caso contrario.
to:
La funzione ''socket'' ritorna un intero positivo in caso di successo (che diventerà il descrittore del socket) e ''-1'' in caso di errore.
Changed lines 97-100 from:
La funzione ''bind'' restituisce 0 in caso di successo e ''-1'' in caso contrario.

[... segue ...]
to:
La funzione ''bind'' restituisce 0 in caso di successo e ''-1'' in caso di errore.

[[#s6]]
!!!Creazione della connessione
Introduciamo le prossime funzioni di gestione del socket descrivendo le varie fasi di connessione che caratterizzano il protocollo TCP. Le due figure che entrano in gioco sono il ''partecipante passivo'' (un server), in fiduciosa attesa che qualcuno gli richieda la connessione, e un ''partecipante attivo'' (il client) che effettua tale richiesta.

Ecco in pratica cosa succede:
# (''lato passivo'') Il server esegue l'apertura passiva del socket, attraverso le funzioni ''socket'', ''bind'' e ''listen'';
# (''lato attivo'') Il client richiede l'inizio della connessione (apertura attiva) usando la funzione ''connect'';
# (''lato passivo'') Il server accetta la connessione tramite la funzione ''accept'' e la sposta su un nuovo socket;
# (''lato passivo e attivo'') Invio e ricezione dei dati.

[[#s7]]
!!!Funzione connect
Se la ''bind'' permetteva a un server di assegnare una porta ad un socket, la ''connect'' è la funzione che consente ad un client di collegarsi a quella porta specifica, ponendo un socket nello ''stato connesso''.

%soluzione%''int'' connect (''int'' sockid, ''const struct sockaddr'' *destaddr, ''socklen_t'' addrlen)

, dove:
* '''sockid''' è il descrittore intero del socket da connettere;
* '''destaddr''' è la struttura che contiene l'indirizzo di destinazione cui il socket si dovrà collegare (indirizzo IP più porta);
* '''addrlen''' è un intero che indica la dimensione dell'indirizzo in byte.

La funzione ''connect'' restituisce 0 in caso di successo e ''-1'' in caso di errore.

La ''connect'' è inoltre ''bloccante'', ovvero ritorna solo quando la connessione è stabilita o quando si è verificato un errore. Se ciò non avviene, il codice non va avanti.

[...segue
...]
Added lines 13-14:
# [[#s4|Codifica degli indirizzi]]
# [[#s5|Funzione bind]]
Changed lines 23-24 from:
I socket sono i due punti finali di tale canale, che forniscono l'interfaccia tra i programmi applicativi e il livello di trasporto (TCP, UDP, ...).
to:
I socket sono i due capi di tale canale, che forniscono l'interfaccia tra i programmi applicativi e il livello di trasporto (TCP, UDP, ...).
Changed lines 31-34 from:
# se è tutto ok, il server accetta la connessione e crea un nuovo socket "s2" su una porta diversa
# il servizio chiamato dal client viene gestito
dal server sul socket "s2" (che viene chiuso una volta soddisfatte le richieste del client)
# mentre viene eseguito il punto 4,
il server è tornato ad ascoltare su "s1" eventuali chiamate da parte di altri client.
to:
# quando questa arriva, se è tutto ok il server accetta la connessione e crea un nuovo socket "s2" su una nuova porta
# il servizio chiamato
dal client viene gestito dal server sul socket "s2" (che verrà poi chiuso una volta soddisfatta la richiesta)
# mentre viene eseguito
il punto 4, il server è tornato ad ascoltare su "s1" eventuali chiamate da altri client.
Changed lines 39-42 from:
'''int socket (int pf, int type, protocol)'''

,dove:
to:
%soluzione%''int'' socket (''int'' pf, ''int'' type, protocol)

, dove:
Changed lines 43-48 from:
* '''type''' che consente la scelta del tipo di comunicazione, e che dipende dal protocollo utilizzato tra quelli disponibili nella famiglia scelta sopra. Ogni tipo ha un valore intero, anche in questo caso rappresentato da costanti. Ad esempio:
** SOCK_STREAM: fornisce un canale di trasmissione bidirezionale, sequenziale e affidabile. Il nome ''stream'' deriva dal fatto che i dati vengono trattati come un flusso continuo di byte. Il SOCK_STREAM della PF_INET è TCP;
** SOCK_DGRAM: usato per trasmettere pacchetti di dati (''datagram'') senza connessione e con trasmissione non affidabile. Il SOCK_DGRAM della PF_INET è UDP;
** SOCK_RAW: dà accesso di basso livello ai protocolli di rete e alle varie interfacce. Riservato all'uso di sistema. Il SOCK_RAW della PF_INET è IPv4.
to:
* '''type''' consente la scelta del tipo di comunicazione, che dipende dal protocollo utilizzato tra quelli disponibili nella famiglia scelta sopra. Ogni tipo ha un valore intero, anche in questo caso rappresentato da costanti. Ad esempio:
** ''SOCK_STREAM'': fornisce un canale di trasmissione bidirezionale, sequenziale e affidabile. Il nome ''stream'' deriva dal fatto che i dati vengono trattati come un flusso continuo di byte. Il SOCK_STREAM della PF_INET è TCP;
** ''SOCK_DGRAM'': usato per trasmettere pacchetti di dati (''datagram'') senza connessione e con trasmissione non affidabile. Il SOCK_DGRAM della PF_INET è UDP;
** ''SOCK_RAW'': dà accesso di basso livello ai protocolli di rete e alle varie interfacce. Riservato all'uso di sistema. Il SOCK_RAW della PF_INET è IPv4.
Changed lines 56-57 from:
[segue]
to:
[[#s4]]
!!!Codifica degli indirizzi
Avrete notato che la funzione ''socket'' si disinteressa completamente degli indirizzi che identificano i due punti finali della comunicazione, occupandosi solo di specificare il tipo di famiglia dei protocolli da utilizzare. E' solo attraverso le altre funzioni di gestione del socket (bind, listen, ...) che vengono manipolati gli indirizzi, sotto forma di strutture (passate sempre per riferimento, tramite puntatori).

La struttura generica è la seguente:

[@
struct sockaddr {
u_short sa_family; // Address Family
char sa_data[14]; // Indirizzo (la cui forma dipende dall'AF scelta)
};
@]

Va da sé che ogni famiglia di protocolli implementerà in modo diverso questa struttura generica, dal momento che ognuna di esse ha forme di indirizzamento specifiche e distinte. I nomi di tutte queste strutture iniziano per ''sockaddr_'' più un suffisso finale che indica la famiglia di appartenenza.

Vediamo ad esempio la ''sockaddr_in'', ovvero la sockaddr specifica per IP.

[@
struct sockaddr_in {
short sin_family; // Valore: AF_INET
u_short sin_port; // Numero di porta. Valore: 0 - 65535
struct in_addr sin_addr; // sin_addr è l'indirizzo IP
char sin_zero[8]; // inutilizzato
};
@]

Importante sottolineare come i bit degli indirizzi e dei numeri di porta possano essere ordinati in modo diverso a seconda dell'hardware degli host. Si parla di ordinamento ''big-endian'' quando si parte dai bit più significativi (adottato ad esempio da IBM, Sun, Motorola), ''little-endian'' quando parte da quelli meno significativi (es. Intel). Questo comporta la necessità di eseguire delle apposite routine di verifica dell'ordinamento ed eventuale riconversione per garantire la portabilità del codice.

[[#s5]]
!!!Funzione bind
Abbiamo visto che nel momento della loro creazione i socket non sono associati a nessun indirizzo (IP o di porta). Se lato client non è sempre necessario conoscere l'indirizzo locale, lato server è spesso importante specificare la porta in ascolto di connessione. Ecco dunque lo scopo della funzione ''bind'': assegnare un indirizzo locale ad un socket.

%soluzione%''int'' bind (''int'' sockid, ''const struct sockaddr'' *localaddr, ''socklen_t'' addrlen)

, dove:
* '''sockid''' è il descrittore intero del socket da collegare all'indirizzo, quello ottenuto come valore di ritorno dalla funzione ''socket'';
* '''localaddr''' è la struttura che contiene l'indirizzo locale del socket (indirizzo IP più porta). Per specificare un indirizzo generico si usa il valore INADDR_ANY, che ha valore 0;
* '''addrlen''' è un intero che indica la dimensione dell'indirizzo in byte.

La funzione ''bind'' restituisce 0 in caso di successo e ''-1'' in caso contrario.

[... segue ...
]
Changed lines 46-49 from:
** SOCK_RAW: dà accesso di basso livello ai protocolli di rete e alle varie interfacce. Riservato all'uso di
sistema. Il SOCK_RAW della PF_INET è IPv4.
Da notare che non tutte le combinazioni "famiglia di protocolli"-"tipo di socket" sono valide (ad esempio la PF_UNIX non ha SOCK_RAW).
to:
** SOCK_RAW: dà accesso di basso livello ai protocolli di rete e alle varie interfacce. Riservato all'uso di sistema. Il SOCK_RAW della PF_INET è IPv4.

->[-'''Nota''': da
notare che non tutte le combinazioni "famiglia di protocolli"-"tipo di socket" sono valide (ad esempio la PF_UNIX non ha SOCK_RAW).-]
Added lines 1-59:
(:title Socket Library:)
[[Torna alla pagina di Sistemi Anticoncezionali delle Reti e dei Damiani->Sistemi]]
----

%titolo%''':: Socket Library ::'''

>>left bgcolor=#f5f9fc width=300px border='2px solid #cccccc' padding=5px<<
%center%'''Indice'''

# [[#s1|Introduzione]]
# [[#s2|Come avviene la comunicazione]]
# [[#s3|Creare un socket]]
>><<

[[#s1]]
!!!Introduzione
In soldoni, perché due processi residenti su macchine diverse possano comunicare tra loro, è necessario:
# verificare che le macchine siano in rete
# creare un canale di comunicazione

I socket sono i due punti finali di tale canale, che forniscono l'interfaccia tra i programmi applicativi e il livello di trasporto (TCP, UDP, ...).

[[#s2]]
!!!Come avviene la comunicazione
Cosa siano client e server lo sappiamo tutti (no? Leggi [[qua->Ceravolo#s2]]), come comunichino (in generale) tramite socket è presto detto:

# ho un programma X che gira su un server, ed è associato a una certa porta tramite il socket "s1"
# il server continua ad ascoltare su "s1", aspettando che qualche client richieda la connessione
# se è tutto ok, il server accetta la connessione e crea un nuovo socket "s2" su una porta diversa
# il servizio chiamato dal client viene gestito dal server sul socket "s2" (che viene chiuso una volta soddisfatte le richieste del client)
# mentre viene eseguito il punto 4, il server è tornato ad ascoltare su "s1" eventuali chiamate da parte di altri client.

[[#s3]]
!!!Creare un socket
La funzione necessaria per creare un socket è, manco a dirlo, ''socket''.

'''int socket (int pf, int type, protocol)'''

,dove:

* '''pf''' specifica la famiglia di protocolli da usare con il socket, che si rifletterà sul modo in cui verranno interpretati gli indirizzi forniti. Ogni famiglia è rappresentata da una costante intera, alla quale è associato un nome simbolico per facilitare la memorizzazione e aumentare la chiarezza. Per convenzione questi nomi iniziano per ''PF_'' (Protocol Family) o ''AF_'' (Address Family), la cui scelta ''nella pratica'' è del tutto equivalente. Ad esempio: PF_INET (per il TCP/IP) o PF_UNIX (per il file system UNIX).

* '''type''' che consente la scelta del tipo di comunicazione, e che dipende dal protocollo utilizzato tra quelli disponibili nella famiglia scelta sopra. Ogni tipo ha un valore intero, anche in questo caso rappresentato da costanti. Ad esempio:
** SOCK_STREAM: fornisce un canale di trasmissione bidirezionale, sequenziale e affidabile. Il nome ''stream'' deriva dal fatto che i dati vengono trattati come un flusso continuo di byte. Il SOCK_STREAM della PF_INET è TCP;
** SOCK_DGRAM: usato per trasmettere pacchetti di dati (''datagram'') senza connessione e con trasmissione non affidabile. Il SOCK_DGRAM della PF_INET è UDP;
** SOCK_RAW: dà accesso di basso livello ai protocolli di rete e alle varie interfacce. Riservato all'uso di
sistema. Il SOCK_RAW della PF_INET è IPv4.
Da notare che non tutte le combinazioni "famiglia di protocolli"-"tipo di socket" sono valide (ad esempio la PF_UNIX non ha SOCK_RAW).

* '''protocol''', il protocollo. Essendo in genere indicato implicitamente nel parametro ''type'', ha quasi sempre valore 0.

La funzione ''socket'' ritorna un intero positivo in caso di successo e ''-1'' in caso contrario.

Esempio: '''sd = socket (AF_INET, SOCK_STREAM, 0);'''

[segue]

----
[[Torna alla pagina di Sistemi Anticoncezionali delle Reti e dei Damiani->Sistemi]]