Merge branch 'master' of ssh://gapil.gnulinux.it/srv/git/gapil
[gapil.git] / othersock.tex
index 2474abeda4ce0d219bf06d5988949703363eb06f..325fb0d02745c2c674e6c05fbb35ca8d840c2ced 100644 (file)
@@ -1,6 +1,6 @@
 %% othersock.tex
 %%
-%% Copyright (C) 2004-2015 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2004-2019 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Un preambolo",
@@ -55,11 +55,10 @@ utilizzando per il tipo di socket il valore \const{SOCK\_DGRAM}.
 Questa differenza comporta ovviamente che anche le modalità con cui si usano i
 socket UDP sono completamente diverse rispetto ai socket TCP, ed in
 particolare non esistendo il concetto di connessione non esiste il meccanismo
-del \itindex{three~way~handshake} \textit{three way handshake} né quello degli
-stati del protocollo. In realtà tutto quello che avviene nella comunicazione
-attraverso dei socket UDP è la trasmissione di un pacchetto da un client ad un
-server o viceversa, secondo lo schema illustrato in
-fig.~\ref{fig:UDP_packet-exchange}.
+del \textit{three way handshake} né quello degli stati del protocollo. In
+realtà tutto quello che avviene nella comunicazione attraverso dei socket UDP
+è la trasmissione di un pacchetto da un client ad un server o viceversa,
+secondo lo schema illustrato in fig.~\ref{fig:UDP_packet-exchange}.
 
 \begin{figure}[!htb]
   \centering \includegraphics[width=10cm]{img/udp_connection}  
@@ -115,13 +114,23 @@ destinati, oppure a scartarli inviando un messaggio \textit{ICMP port
 \label{sec:UDP_sendto_recvfrom}
 
 Come accennato in sez.~\ref{sec:UDP_characteristics} le due funzioni
-principali usate per la trasmissione di dati attraverso i socket UDP sono
-\func{sendto} e \func{recvfrom}. La necessità di usare queste funzioni è
-dovuta al fatto che non esistendo con UDP il concetto di connessione, non si
-ha neanche a disposizione un \textsl{socket connesso} su cui sia possibile
-usare direttamente \func{read} e \func{write} avendo già stabilito (grazie
-alla chiamata ad \func{accept} che lo associa ad una connessione) quali sono
-sorgente e destinazione dei dati.
+principali usate per la trasmissione di dati attraverso i socket UDP (ed in
+generale per i socket di tipo \textit{datagram}) sono \func{sendto} e
+\func{recvfrom}. La necessità di usare queste funzioni è dovuta al fatto che
+non esistendo con UDP il concetto di connessione, non si può stabilire (come
+avviene con i socket TCP grazie alla chiamata ad \func{accept} che li associa
+ad una connessione) quali sono la sorgente e la destinazione dei dati che
+passano sul socket.\footnote{anche se in alcuni casi, come quello di un client
+  che contatta un server, è possibile connettere il socket (vedi
+  sez.~\ref{sec:UDP_connect}), la necessità di \func{sendto} e \func{recvfrom}
+  resta, dato che questo è possibile solo sul lato del client.}
+
+Per questo anche se in generale si possono comunque leggere i dati con
+\func{read}, usando questa funzione non si sarà in grado di determinare da
+quale fra i possibili corrispondenti (se ve ne sono più di uno, come avviene
+sul lato del server) questi arrivino. E non sarà comunque possibile usare
+\func{write} (che fallisce un errore di \errval{EDESTADDRREQ}) in quanto non
+è determinato la destinazione che i dati avrebbero.
 
 Per questo motivo nel caso di UDP diventa essenziale utilizzare queste due
 funzioni, che sono comunque utilizzabili in generale per la trasmissione di
@@ -129,13 +138,13 @@ dati attraverso qualunque tipo di socket. Esse hanno la caratteristica di
 prevedere tre argomenti aggiuntivi attraverso i quali è possibile specificare
 la destinazione dei dati trasmessi o ottenere l'origine dei dati ricevuti. La
 prima di queste funzioni è \funcd{sendto} ed il suo prototipo\footnote{il
-  prototipo illustrato è quello utilizzato dalle \acr{glibc}, che seguono le
+  prototipo illustrato è quello utilizzato dalla \acr{glibc}, che segue le
   \textit{Single Unix Specification}, l'argomento \param{flags} era di tipo
-  \texttt{int} nei vari BSD4.*, mentre nelle \acr{libc4} e \acr{libc5} veniva
-  usato un \texttt{unsigned int}; l'argomento \param{len} era \texttt{int} nei
-  vari BSD4.* e nelle \acr{libc4}, ma \type{size\_t} nelle \acr{libc5}; infine
-  l'argomento \param{tolen} era \texttt{int} nei vari BSD4.* nelle \acr{libc4}
-  e nelle \acr{libc5}.} è:
+  \ctyp{int} nei vari BSD4.*, mentre nelle \acr{libc4} e \acr{libc5} veniva
+  usato un \texttt{unsigned int}; l'argomento \param{len} era \ctyp{int} nei
+  vari BSD4.* e nella \acr{libc4}, ma \type{size\_t} nella \acr{libc5}; infine
+  l'argomento \param{tolen} era \ctyp{int} nei vari BSD4.*, nella \acr{libc4} e
+  nella \acr{libc5}.} è:
 \begin{functions}
   \headdecl{sys/types.h}
   \headdecl{sys/socket.h}
@@ -210,20 +219,20 @@ qualora si sia specificato un indirizzo è possibile ricevere un errore di
 Finora abbiamo tralasciato l'argomento \param{flags}; questo è un intero usato
 come maschera binaria che permette di impostare una serie di modalità di
 funzionamento della comunicazione attraverso il socket (come
-\const{MSG\_NOSIGNAL} che impedisce l'invio del segnale \signal{SIGPIPE} quando
-si è già chiuso il capo locale della connessione). Torneremo con maggiori
-dettagli sul significato di questo argomento in sez.~\ref{sec:net_sendmsg},
-dove tratteremo le funzioni avanzate dei socket, per il momento ci si può
-limitare ad usare sempre un valore nullo.
+\constd{MSG\_NOSIGNAL} che impedisce l'invio del segnale \signal{SIGPIPE}
+quando si è già chiuso il capo locale della connessione). Torneremo con
+maggiori dettagli sul significato di questo argomento in
+sez.~\ref{sec:net_sendmsg}, dove tratteremo le funzioni avanzate dei socket,
+per il momento ci si può limitare ad usare sempre un valore nullo.
 
 La seconda funzione utilizzata nella comunicazione fra socket UDP è
 \funcd{recvfrom}, che serve a ricevere i dati inviati da un altro socket; il
-suo prototipo\footnote{il prototipo è quello delle \acr{glibc} che seguono le
-  \textit{Single Unix Specification}, i vari BSD4.*, le \acr{libc4} e le
-  \acr{libc5} usano un \texttt{int} come valore di ritorno; per gli argomenti
+suo prototipo\footnote{il prototipo è quello della \acr{glibc} che segue le
+  \textit{Single Unix Specification}, i vari BSD4.*, le \acr{libc4} e la
+  \acr{libc5} usano un \ctyp{int} come valore di ritorno; per gli argomenti
   \param{flags} e \param{len} vale quanto detto a proposito di \func{sendto};
-  infine l'argomento \param{fromlen} è \texttt{int} per i vari BSD4.*, le
-  \acr{libc4} e le \acr{libc5}.} è:
+  infine l'argomento \param{fromlen} è \ctyp{int} per i vari BSD4.*, la
+  \acr{libc4} e la \acr{libc5}.} è:
 \begin{functions}
   \headdecl{sys/types.h}
   \headdecl{sys/socket.h}
@@ -674,10 +683,12 @@ scambiato nessun pacchetto, tutto quello che succede è che da quel momento in
 qualunque cosa si scriva sul socket sarà inviata a quell'indirizzo; non sarà
 più necessario usare l'argomento \param{to} di \func{sendto} per specificare
 la destinazione dei pacchetti, che potranno essere inviati e ricevuti usando
-le normali funzioni \func{read} e \func{write}.\footnote{in realtà si può
-  anche continuare ad usare la funzione \func{sendto}, ma in tal caso
+le normali funzioni \func{read} e \func{write} che a questo punto non
+falliranno più con l'errore di \errval{EDESTADDRREQ}.\footnote{in realtà si
+  può anche continuare ad usare la funzione \func{sendto}, ma in tal caso
   l'argomento \param{to} deve essere inizializzato a \val{NULL}, e
-  \param{tolen} deve essere inizializzato a zero, pena un errore.}
+  \param{tolen} deve essere inizializzato a zero, pena un errore di
+  \errval{EISCONN}.}
 
 Una volta che il socket è connesso cambia però anche il comportamento in
 ricezione; prima infatti il kernel avrebbe restituito al socket qualunque
@@ -738,8 +749,8 @@ con UDP non esiste una connessione, e fintanto che non si invia un pacchetto
 non c'è traffico sulla rete. In questo caso l'errore sarà rilevato alla
 ricezione del pacchetto ICMP \textit{destination unreachable} emesso dalla
 macchina cui ci si è rivolti, e questa volta, essendo il socket UDP connesso,
-il kernel potrà riportare detto errore in user space in maniera non ambigua,
-ed esso apparirà alla successiva lettura sul socket.
+il kernel potrà riportare detto errore in \textit{user space} in maniera non
+ambigua, ed esso apparirà alla successiva lettura sul socket.
 
 Si tenga presente infine che l'uso dei socket connessi non risolve l'altro
 problema del client, e cioè il fatto che in caso di perdita di un pacchetto