\func{socket} ritorna il descrittore che viene usato per identificare il
socket in tutte le chiamate successive. Nel caso la chiamata fallisca si
stampa un errore (\texttt{\small 16}) con la funzione \func{perror} e si esce
-(\texttt{\small 16}) con un codice di errore.
+(\texttt{\small 17}) con un codice di errore.
Il passo seguente (\texttt{\small 19--27}) è quello di costruire un'apposita
struttura \struct{sockaddr\_in} in cui sarà inserito l'indirizzo del server ed
gestire tutta una serie di situazioni critiche che non esistono per i processi
locali.
-Come accennato in \secref{sec:TCP_func_accept} la funzione \func{accept}
-riporta tutti gli eventuali errori di rete pendenti su una connessione sul
-\textit{connected socket}; questo significa che, oltre al caso di interruzione
-da parte di un segnale, esistono altri errori non fatali che necessitano
-semplicemente la ripetizione della chiamata senza che si debba uscire dal
-programma. Un esempio possibile è quello mostrato in
-\figref{fig:TCP_early_abort}, in cui la connessione viene abortita dal client
-con l'invio di un segmento RST prima che sia stata chiamata la funzione
-\func{accept}.
-
+La prima situazione critica è quella della terminazione precoce, per via di un
+qualche errore di rete, della connessione effettuata da un client. Come
+accennato in \secref{sec:TCP_func_accept} la funzione \func{accept} riporta
+tutti gli eventuali errori di rete pendenti su una connessione sul
+\textit{connected socket}.
+
+Questo significa che, oltre alla interruzione da parte di un segnale, che
+abbiamo trattato in \secref{sec:TCP_child_hand} nel caso particolare di
+\const{SIGCHLD}, si possono avere altri errori non fatali all'uscita di
+\func{accept}, che necessitano semplicemente la ripetizione della chiamata
+senza che si debba uscire dal programma. Uno scenario tipo è quello mostrato
+in \figref{fig:TCP_early_abort}, in cui la connessione viene abortita sul lato
+client con l'invio di un segmento RST, prima che nel server sia stata chiamata
+la funzione \func{accept}.
\begin{figure}[htb]
\centering
\label{fig:TCP_early_abort}
\end{figure}
+Benché questo non sia un fatto comune un evento simile può essere osservato
+con dei server molto occupati. In tal caso, in una struttura del server simile
+a quella del nostro esempio, in cui la gestione delle singole connessioni è
+demandata a processi figli, può accadere che il three way handshake venga
+completato e la relativa connessione abortita subito dopo, prima che il padre,
+per via del carico della macchina abbia fatto in tempo a rieseguire la
+chiamata \func{accept}. In questo caso si ha una situazione analoga a quella
+illustrata in \figref{fig:TCP_early_abort}, la connessione viene stabilita, ma
+subito dopo si ha una condizione
+
+
+che, come nell'esempio in figura, ritornerebbe
+immediatamente con un errore relativo alla connessione abortita.
+
+
+Si tenga presente che questo tipo di terminazione non è riproducibile
+terminando il client prima della chiamata ad \func{accept}; in tal caso
+infatti il socket associato alla connessione viene semplicemente chiuso,
+attraverso la sequenza vista in \secref{sec:TCP_conn_term}, per cui la
+\func{accept} ritornerà senza errori, e si avrà semplicemente un end-of-file
+al primo accesso al socket.
+
+In questo caso
+
%%% Local Variables:
attenzione particolare alle GNU libc, che sono la versione più
usata delle librerie del C, senza dimenticare, ove note, di
citare le differenze con possibili alternative come le libc5 o
- le ulibc.
+ le uclibc.
</p>
<p>
L'obiettivo resta comunque quello di riuscire a produrre una
all'opera di Mirko Maischberger abbiamo anche una bellissima
versione HTML, accessibile nella sezione <A
href="http://www.lilik.it/~mirko/gapil/gapil.html"> <font
- face="sans-serif"> <b>On Line</b> </font></A>, finalemente
+ face="sans-serif"> <b>online</b> </font></A>, finalmente
all'altezza della versione stampabile.
</p>
</td>
\label{sec:sock_addr_func}
In questa sezione tratteremo delle varie funzioni usate per manipolare gli
-indirizzi, limitandoci però agli indirizzi internet.
-
-Come accennato gli indirizzi e i numeri di porta usati nella rete devono
-essere forniti in formato opportuno (il \textit{network order}). Per capire
-cosa significa tutto ciò occorre introdurre un concetto generale che tornerà
-utile anche in seguito.
+indirizzi, limitandoci però agli indirizzi internet. Come accennato gli
+indirizzi e i numeri di porta usati nella rete devono essere forniti in
+formato opportuno (il \textit{network order}). Per capire cosa significa tutto
+ciò occorre introdurre un concetto generale che tornerà utile anche in
+seguito.
\subsection{La \textit{endianess}\index{endianess}}
\begin{figure}[htb]
\centering
- \includegraphics[height=5cm]{img/endianess}
+ \includegraphics[height=3cm]{img/endianess}
\caption{Schema della disposizione dei dati in memoria a seconda della
\textit{endianess}\index{endianess}.}
\label{fig:sock_endianess}
Il problema connesso all'endianess\index{endianess} è che quando si passano
dei dati da un tipo di architettura all'altra i dati vengono interpretati in
maniera diversa, e ad esempio nel caso dell'intero a 16 bit ci si ritroverà
-con i due byte in cui è suddiviso scambiati di posto, e ne sarà quindi
-invertito l'ordine di lettura per cui, per riavere il valore originale,
-dovranno essere rovesciati.
-
-Per questo motivo si usano delle funzioni di conversione che servono a tener
-conto automaticamente della possibile differenza fra l'ordinamento usato sul
-computer e quello che viene usato nelle trasmissione sulla rete; queste
-funzioni sono \funcd{htonl}, \funcd{htons}, \funcd{ntohl} e \funcd{ntohs} ed i
-rispettivi prototipi sono:
+con i due byte in cui è suddiviso scambiati di posto. Per questo motivo si
+usano delle funzioni di conversione che servono a tener conto automaticamente
+della possibile differenza fra l'ordinamento usato sul computer e quello che
+viene usato nelle trasmissione sulla rete; queste funzioni sono \funcd{htonl},
+\funcd{htons}, \funcd{ntohl} e \funcd{ntohs} ed i rispettivi prototipi sono:
\begin{functions}
\headdecl{netinet/in.h}
\funcdecl{unsigned long int htonl(unsigned long int hostlong)}
*
* Usage: echod -h give all info
*
- * $Id: TCP_echod.c,v 1.4 2003/06/18 21:19:24 piccardi Exp $
+ * $Id: TCP_echod.c,v 1.5 2003/06/19 11:43:13 piccardi Exp $
*
****************************************************************/
/*
int list_fd, conn_fd;
int waiting;
pid_t pid;
- struct sockaddr_in serv_add;
+ struct sockaddr_in serv_add, cli_add;
+ socklen_t len;
+ char debug[MAXLINE], ipaddr[20];
/*
* Input section: decode parameters passed in the calling
* Use getopt function
/* handle echo to client */
while (1) {
/* accept connection */
- while (((conn_fd = accept(list_fd, NULL, NULL)) < 0)
- && (errno == EINTR));
+ while (((conn_fd = accept(list_fd, (struct sockaddr *)&cli_add, &len))
+ < 0) && (errno == EINTR));
if ( conn_fd < 0) {
PrintErr("accept error");
exit(1);
}
+ if (debugging) {
+ inet_ntop(AF_INET, &cli_add.sin_addr, ipaddr, sizeof(ipaddr));
+ snprintf(debug, MAXLINE, "Accepted connection form %s\n", ipaddr);
+ if (demonize) {
+ syslog(LOG_DEBUG, debug);
+ } else {
+ printf("%s", debug);
+ }
+ }
/* fork to handle connection */
if ( (pid = fork()) < 0 ){
PrintErr("fork error");
if (debugging) {
buffer[nread] = 0;
snprintf(debug, MAXLINE+20, "Letti %d byte, %s", nread, buffer);
- if (demonize) { /* go daemon */
+ if (demonize) { /* daemon mode */
syslog(LOG_DEBUG, debug);
} else {
printf("%s", debug);
* routine to print error on stout or syslog
*/
void PrintErr(char * error) {
- if (demonize) { /* go daemon */
+ if (demonize) { /* daemon mode */
syslog(LOG_ERR, error);
} else {
perror(error);