X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=elemtcp.tex;h=111b0f2b1ccd921039faea854401365e804ce404;hp=3e2b0c7ca8f9dc2b45a73dcc8edce7f86e819910;hb=df52b4351217a5ca93506df97a34f6fba69474f0;hpb=e2a1ad24365266ea8846b688addd4e7694428969 diff --git a/elemtcp.tex b/elemtcp.tex index 3e2b0c7..111b0f2 100644 --- a/elemtcp.tex +++ b/elemtcp.tex @@ -489,7 +489,7 @@ relative tabelle. \begin{figure}[!htb] \centering - \includegraphics[width=10cm]{img/port_alloc} + \includegraphics[width=15cm]{img/port_alloc} \caption{Allocazione dei numeri di porta} \label{fig:TCPel_port_alloc} \end{figure} @@ -649,10 +649,7 @@ ci si porr \begin{prototype}{sys/socket.h} {int bind(int sockfd, const struct sockaddr *serv\_addr, socklen\_t addrlen)} - Il primo argomento è un file descriptor ottenuto da una precedente chiamata - a \func{socket}, mentre il secondo e terzo argomento sono rispettivamente - l'indirizzo (locale) del socket e la dimensione della struttura che lo - contiene, secondo quanto già trattato in \secref{sec:sock_sockaddr}. + Assegna un indirizzo ad un socket. \bodydesc{La funzione restituisce zero in caso di successo e -1 per un errore; in caso di errore la variabile \var{errno} viene impostata secondo @@ -666,6 +663,11 @@ ci si porr \end{errlist}} \end{prototype} +Il primo argomento è un file descriptor ottenuto da una precedente chiamata a +\func{socket}, mentre il secondo e terzo argomento sono rispettivamente +l'indirizzo (locale) del socket e la dimensione della struttura che lo +contiene, secondo quanto già trattato in \secref{sec:sock_sockaddr}. + Con il TCP la chiamata \func{bind} permette di specificare l'indirizzo, la porta, entrambi o nessuno dei due. In genere i server utilizzano una porta nota che assegnano all'avvio, se questo non viene fatto è il kernel a @@ -676,7 +678,8 @@ per il server\footnote{un'eccezione a tutto ci viene registrata presso il \textit{portmapper}; quest'ultimo è un altro demone che deve essere contattato dai client per ottenere la porta effimera su cui si trova il server.} che in genere viene identificato dalla porta su -cui risponde. +cui risponde (l'elenco di queste porte, e dei relativi servizi, è in +\file{/etc/services}). Con \func{bind} si può assegnare un IP specifico ad un socket, purché questo appartenga ad una interfaccia della macchina. Per un client TCP questo @@ -697,34 +700,50 @@ Per specificare un indirizzo generico con IPv4 si usa il valore è pari a zero, nell'esempio \figref{fig:net_serv_code} si è usata un'assegnazione immediata del tipo: -\footnotesize \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} - serv_add.sin_addr.s_addr = htonl(INADDR_ANY); /* connect from anywhere */ +serv_add.sin_addr.s_addr = htonl(INADDR_ANY); /* connect from anywhere */ \end{lstlisting} -\normalsize Si noti che si è usato \func{htonl} per assegnare il valore -\const{INADDR\_ANY}; benché essendo questo pari a zero il riordinamento sia -inutile; ma dato che tutte le costanti \val{INADDR\_} sono definite -secondo l'ordinamento della macchina è buona norma usare sempre la funzione -\func{htonl}. - -L'esempio precedete funziona con IPv4 dato che l'indirizzo è rappresentabile -anche con un intero a 32 bit; non si può usare lo stesso metodo con IPv6, -in cui l'indirizzo è specificato come struttura, perché il linguaggio C non -consente l'uso di una struttura costante come operando a destra in una -assegnazione. - -Per questo nell'header \file{netinet/in.h} è definita una variabile +\const{INADDR\_ANY}, benché essendo questo pari a zero il riordinamento sia +inutile. Si tenga presente comunque che tutte le costanti \val{INADDR\_} +(riportate in ) sono definite secondo l'ordinamento della macchina, ed anche +se esse possono essere invarianti rispetto all'ordinamento, è comunque buona +norma usare sempre la funzione \func{htonl}. + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|l|} + \hline + \textbf{Costante} & \textbf{Significato} \\ + \hline + \hline + \const{INADDR\_ANY} & Indirizzo generico (\texttt{0.0.0.0})\\ + \const{INADDR\_BROADCAST}& Indirizzo di \textit{broadcast}.\\ + \const{INADDR\_LOOPBACK} & Indirizzo di \textit{loopback} + (\texttt{127.0.0.1}).\\ + \const{INADDR\_NONE} & Indirizzo errato.\\ + \hline + \end{tabular} + \caption{Costanti di definizione di alcuni indirizzi generici per IPv4.} + \label{tab:TCPel_ipv4_addr} +\end{table} + +L'esempio precedente funziona correttamente con IPv4 poiché che l'indirizzo è +rappresentabile anche con un intero a 32 bit; non si può usare lo stesso +metodo con IPv6, in cui l'indirizzo deve necessariamente essere specificato +con una struttura, perché il linguaggio C non consente l'uso di una struttura +costante come operando a destra in una assegnazione. + +Per questo motivo nell'header \file{netinet/in.h} è definita una variabile \type{in6addr\_any} (dichiarata come \ctyp{extern}, ed inizializzata dal sistema al valore \const{IN6ADRR\_ANY\_INIT}) che permette di effettuare una -assegnazione del tipo: +assegnazione del tipo: -\footnotesize \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} - serv_add.sin6_addr = in6addr_any; /* connect from anywhere */ +serv_add.sin6_addr = in6addr_any; /* connect from anywhere */ \end{lstlisting} -\normalsize \subsection{La funzione \func{connect}} @@ -735,14 +754,10 @@ connessione con un server TCP, il prototipo della funzione \begin{prototype}{sys/socket.h} {int connect(int sockfd, const struct sockaddr *servaddr, socklen\_t addrlen)} - Il primo argomento è un file descriptor ottenuto da una precedente chiamata - a \func{socket}, mentre il secondo e terzo argomento sono rispettivamente - l'indirizzo e la dimensione della struttura che contiene l'indirizzo del - socket, già descritta in \secref{sec:sock_sockaddr}. + Stabilisce una connessione fra due socket. \bodydesc{La funzione restituisce zero in caso di successo e -1 per un - errore, in caso di errore la variabile \var{errno} viene impostata secondo - i seguenti codici di errore: + errore, in caso di errore \var{errno} assumerà i valori: \begin{errlist} \item[\errcode{ECONNREFUSED}] non c'è nessuno in ascolto sull'indirizzo remoto. @@ -766,6 +781,12 @@ connessione con un server TCP, il prototipo della funzione \errval{ENOTSOCK}, \errval{EISCONN} e \errval{EADDRINUSE}.} \end{prototype} +Il primo argomento è un file descriptor ottenuto da una precedente chiamata a +\func{socket}, mentre il secondo e terzo argomento sono rispettivamente +l'indirizzo e la dimensione della struttura che contiene l'indirizzo del +socket, già descritta in \secref{sec:sock_sockaddr}. + + La struttura dell'indirizzo deve essere inizializzata con l'indirizzo IP e il numero di porta del server a cui ci si vuole connettere, come mostrato nell'esempio \secref{sec:net_cli_sample} usando le funzioni illustrate in