X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=othersock.tex;h=bffd4aeb1eb1b685c97bdac60eca1f6b29033282;hp=6d73bee8d3e3b1d4ac4bc89e159f3027e721d62d;hb=5a15091e17c25f37a6f53751ccde91f504006773;hpb=5afbcf1d6a84ab2a527859d8fd05b75a31e39736 diff --git a/othersock.tex b/othersock.tex index 6d73bee..bffd4ae 100644 --- a/othersock.tex +++ b/othersock.tex @@ -1,6 +1,6 @@ %% othersock.tex %% -%% Copyright (C) 2004-2015 Simone Piccardi. Permission is granted to +%% Copyright (C) 2004-2018 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 \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 nelle \acr{libc4}, ma \type{size\_t} nelle \acr{libc5}; - infine l'argomento \param{tolen} era \ctyp{int} nei vari BSD4.* nelle - \acr{libc4} e nelle \acr{libc5}.} è: + 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 +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} è \ctyp{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