\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}
\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
\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
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
è 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}}
\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.
\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