From 8bfe80f7fe2470bf0a26d656b281ea44c69d8fe5 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Sun, 6 Jun 2004 13:27:10 +0000 Subject: [PATCH] Aggiunto file dimenticato per strada e piccole modifiche al materiale sui socket UDP. --- listati/herrno.c | 1 + othersock.tex | 45 +++++++++++++++++++++++++++++++++++---------- sockctrl.tex | 4 ++-- 3 files changed, 38 insertions(+), 12 deletions(-) create mode 100644 listati/herrno.c diff --git a/listati/herrno.c b/listati/herrno.c new file mode 100644 index 0000000..52997e2 --- /dev/null +++ b/listati/herrno.c @@ -0,0 +1 @@ +extern int h_errno; diff --git a/othersock.tex b/othersock.tex index 9af54ba..3944e5d 100644 --- a/othersock.tex +++ b/othersock.tex @@ -14,7 +14,7 @@ Dopo aver trattato in cap.~\ref{cha:TCP_socket} i socket TCP, che costituiscono l'esempio più comune dell'interfaccia dei socket, esamineremo in questo capitolo gli altri tipi di socket, a partire dai socket UDP, e i socket -\textit{Unix domain} già incontrati in \secref{sec:ipc_socketpair}. +\textit{Unix domain} già incontrati in sez.~\ref{sec:ipc_socketpair}. \section{I socket UDP} @@ -656,8 +656,8 @@ asincroni. Quando si chiama \func{connect} su di un socket UDP tutto quello che succede è che l'indirizzo passato alla funzione viene registrato come indirizzo di -destinazione del socket, a differenza di quanto avviene con TCP non viene -scambiato nessun pacchetto; tutto quello che succede è che da quel momento in +destinazione del socket. A differenza di quanto avviene con TCP non viene +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 @@ -666,12 +666,12 @@ le normali funzioni \func{read} e \func{write}.\footnote{in realt l'argomento \param{to} deve essere inizializzato a \const{NULL}, e \param{tolen} deve essere inizializzato a zero, pena un errore.} -Una volta che il socket è connesso però cambia anche il comportamento in +Una volta che il socket è connesso cambia però anche il comportamento in ricezione; prima infatti il kernel avrebbe restituito al socket qualunque pacchetto ricevuto con un indirizzo di destinazione corrispondente a quello del socket, senza nessun controllo sulla sorgente; una volta che il socket viene connesso saranno riportati su di esso solo i pacchetti con un indirizzo -sorgente corrispondente a quello a cui ci si è connessi. +sorgente corrispondente a quello a cui ci si è connessi. Infine quando si usa un socket connesso, venendo meno l'ambiguità segnalata alla fine di sez.~\ref{sec:UDP_problems}, tutti gli eventuali errori asincroni @@ -708,23 +708,48 @@ fig.~\ref{fig:UDP_echo_conn_echo_client}. \label{fig:UDP_echo_conn_echo_client} \end{figure} +Utilizzando questa nuova versione del client si può verificare che quando ci +si rivolge verso un indirizzo inesistente o su cui non è in ascolto un server +si è in grado rilevare l'errore, se infatti eseguiamo il nuovo programma +otterremo un qualcosa del tipo: +\begin{verbatim} +[piccardi@gont sources]$ ./echo 192.168.1.1 +prova +Errore in lettura: Connection refused +\end{verbatim}%$ + +Ma si noti che a differenza di quanto avveniva con il client TCP qui l'errore +viene rilevato soltanto dopo che si è tentato di inviare qualcosa, ed in +corrispondenza al tentativo di lettura della risposta. Questo avviene perché +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. +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 +questo resterà bloccato permanentemente in attesa di una risposta. Per +risolvere questo problema l'unico modo sarebbe quello di impostare un +\textit{timeout} o riscrivere il client in modo da usare l'I/O non bloccante. \section{I socket \textit{Unix domain}} \label{sec:unix_socket} -Benché i socket Unix domain non siano strettamente attinenti alla rete, in -quanto definiscono una interfaccia di comunicazione locale alla singola -macchina, li tratteremo comunque in questa sezione in quanto la loro -interfaccia è comunque basata sulla più generale interfaccia dei socket. +Benché i socket Unix domain, come meccanismo di comunicazione fra processi che +girano sulla stessa macchina, non siano strettamente attinenti alla rete, li +tratteremo comunque in questa sezione. Nonstante le loro peculiarità infatti, +l'interfaccia di programmazione che serve ad utilizzarli resta sempre quella +dei socket. + \section{Altri socket} \label{sec:socket_other} - Tratteremo in questa sezione gli altri tipi particolari di socket supportati da Linux, come i \textit{raw socket}, con i quali si possono \textsl{forgiare} direttamente i pacchetti a tutti i livelli dello stack dei protocolli, o i diff --git a/sockctrl.tex b/sockctrl.tex index 82f1c66..24c752f 100644 --- a/sockctrl.tex +++ b/sockctrl.tex @@ -136,8 +136,8 @@ vengono memorizzati in una opportuna struttura \struct{hostent} la cui definizione è riportata in fig.~\ref{fig:sock_hostent_struct}. In caso di insuccesso l'errore viene segnalato da un valore nullo del puntatore, ma in questo caso, a differenza delle funzioni viste finora, non viene utilizzata la -variabile \var{errno} per riportare un codice di errore, in quanto questo è -dipende solo dalle sottostanti chiamate al sistema e non avere nessun +variabile \var{errno} per riportare un codice di errore, in quanto questo +dipende solo dalle sottostanti chiamate al sistema e può non avere nessun significato nell'indicare quale parte del procedimento di risoluzione è fallita. -- 2.30.2