+\texttt{cliaddr}. Se questa informazione non interessa basterà inizializzare a
+\texttt{NULL} detti puntatori.
+
+Se la funzione ha successo restituisce il descrittore di un nuovo socket
+creato dal kernel (detto \textit{connected socket}) a cui viene associata la
+prima connessione completa (estratta dalla relativa coda, vedi
+\secref{sec:TCPel_func_listen}) che il client TCP ha effettuato verso il
+socket \texttt{sockfd}. Quest'ultimo (detto \textit{listening socket}) è
+quello creato all'inizio e messo in ascolto con \texttt{listen}, e non viene
+toccato dalla funzione.
+Se non ci sono connessioni pendenti da accettare la funzione mette in attesa
+il processo\footnote{a meno che non si sia settato il socket per essere
+ non-bloccante, nel qual caso ritorna con l'errore \texttt{EAGAIN},
+ torneremo su questa modalità di operazione in \secref{sec:xxx_sock_noblock}}
+fintanto che non ne arriva una.
+
+Il meccanismo di funzionamento di \texttt{accept} è essenziale per capire il
+funzionamento di un server: in generale infatti c'è sempre un solo socket in
+ascolto, che resta per tutto il tempo nello stato \texttt{LISTEN}, mentre le
+connessioni vengono gestite dai nuovi socket ritornati da \texttt{accept} che
+si trovano automaticamente nello stato \texttt{ESTABLISHED} e utilizzati fino
+alla chiusura della connessione che avviene su di essi. Si può riconoscere
+questo schema anche nell'esempio elementare in \figref{fig:net_serv_code} dove
+per ogni connessione il socket creato da \texttt{accept} viene chiuso dopo
+l'invio dei dati.
+
+
+\subsection{La funzione \texttt{close}}
+\label{sec:TCPel_func_close}
+
+La funzione standard unix \texttt{close} (vedi \secref{sec:fileunix_close})
+che si usa sui file può essere usata con lo stesso effetto anche sui socket
+descriptor.
+
+L'azione standard di questa funzione quando applicata a socket è di marcarlo
+come chiuso e ritornare immediatamente al processo. Una volta chiamata il
+socket descriptor non è più utilizzabile dal processo e non può essere usato
+come argomento per una \texttt{write} o una \texttt{read} (anche se l'altro
+capo della connessione non avesse chiuso la sua parte). Il kernel invierà
+comunque tutti i dati che ha in coda prima di iniziare la sequenza di chiusura.
+
+Vedremo più avanti in \secref{sec:TCPadv_so_linger} come è possibile cambiare
+questo comportamento, e cosa deve essere fatto perché il processo possa
+assicurarsi che l'altro capo abbia ricevuto tutti i dati.
+
+Come per i file anche per i socket descriptor viene mantenuto un numero di
+riferimenti, per cui se più di un processo ha lo stesso socket aperto
+l'emissione del FIN e la sequenza di chiusura di TCP non viene innescata
+fintanto che il numero di riferimenti non si annulla. Questo è il
+comportamento normale che ci si aspetta in un'applicazione client/server quale
+quella che illustreremo in \secref{sec:TCPel_cunc_serv}.
+
+Per attivare immediatamente l'emissione del FIN e la sequenza di chiusura si
+può usare la funzione \texttt{shutdown} su cui torneremo in seguito.
+
+
+\section{I server concorrenti su TCP}
+\label{sec:TCPel_cunc_serv}
+
+Il server \texttt{daytime} dell'esempio in \secref{sec:net_cli_sample} è un
+tipico esempio di server iterativo, in cui viene servita una richiesta alla
+volta; in generale però, specie se il servizio è più complesso e comporta uno
+scambio di dati più sostanzioso di quello in questione, non è opportuno
+bloccare un server nel servizio di un client per volta; per questo si ricorre
+alle capacità di multitasking del sistema.
+
+Il modo più immediato per creare un server concorrente è allora quello di
+usare la funzione \texttt{fork} per far creare al server per ogni richiesta da
+parte di un client un processo figlio che si incarichi della gestione della
+comunicazione.
+
+
+\subsection{Un esempio di server \textit{daytime} concorrente}
+\label{sec:TCPel_cunc_daytime}
+
+Per illustrare il meccanismo usato in generale per creare un server
+concorrente abbiamo riscritto il server \texttt{daytime} dell'esempio
+precedente in forma concorrente, inserendo anche una opzione per la stampa
+degli indirizzi delle connessioni ricevute.
+
+In \nfig\ è mostrato un estratto del codice, in cui si sono tralasciati il
+trattamento delle opzioni e le parti rimaste invariate rispetto al precedente
+esempio. Al solito il sorgente completo del server
+\texttt{ElemDaytimeTCPCuncServ.c} è allegato nella directory dei sorgenti.
+
+\begin{figure}[!htb]
+ \footnotesize
+ \begin{lstlisting}{}
+#include <sys/types.h> /* predefined types */
+#include <unistd.h> /* include unix standard library */
+#include <arpa/inet.h> /* IP addresses conversion utiliites */
+#include <sys/socket.h> /* socket library */
+#include <stdio.h> /* include standard I/O library */
+#include <time.h>
+
+int main(int argc, char *argv[])
+{
+ int list_fd, conn_fd;
+ int i;
+ struct sockaddr_in serv_add, client;
+ char buffer[MAXLINE];
+ socklen_t len;
+ time_t timeval;
+ pid_t pid;
+ int logging=0;
+ ...
+ /* write daytime to client */
+ while (1) {
+ if ( (conn_fd = accept(list_fd, (struct sockaddr *)&client, &len))
+ <0 ) {
+ perror("accept error");
+ exit(-1);
+ }
+ /* fork to handle connection */
+ if ( (pid = fork()) < 0 ){
+ perror("fork error");
+ exit(-1);
+ }
+ if (pid == 0) { /* child */
+ close(list_fd);
+ timeval = time(NULL);
+ snprintf(buffer, sizeof(buffer), "%.24s\r\n", ctime(&timeval));
+ if ( (write(conn_fd, buffer, strlen(buffer))) < 0 ) {
+ perror("write error");
+ exit(-1);
+ }
+ if (logging) {
+ inet_ntop(AF_INET, &client.sin_addr, buffer, sizeof(buffer));
+ printf("Request from host %s, port %d\n", buffer,
+ ntohs(client.sin_port));
+ }
+ close(conn_fd);
+ exit(0);
+ } else { /* parent */
+ close(conn_fd);
+ }
+ }
+ /* normal exit, never reached */
+ exit(0);
+}
+ \end{lstlisting}
+ \caption{Esempio di codice di un server concorrente elementare per il
+ servizio daytime.}
+ \label{fig:TCPel_serv_code}
+\end{figure}