+La funzione \texttt{accept} è chiamata da un server TCP per gestire la
+connessione una volta che sia stato completato il three way handshake, la
+funzione restituisce un nuovo socket descriptor su cui si potrà operare per
+effettuare la comunicazione. Se non ci sono connessioni completate il processo
+viene messo in attesa. Il prototipo della funzione è il seguente:
+
+\begin{prototype}{sys/socket.h}
+{int listen(int sockfd, struct sockaddr *addr, socklen\_t *addrlen)}
+ La funzione estrae la prima connessione relativa al socket \texttt{sockfd}
+ in attesa sulla coda delle connessioni complete, che associa ad nuovo socket
+ con le stesse caratteristiche di \texttt{sockfd} (restituito dalla funzione
+ stessa). Il socket originale non viene toccato. Nella struttura
+ \texttt{addr} e nella variabile \texttt{addrlen} vengono restituiti
+ indirizzo e relativa lunghezza del client che si è connesso.
+
+ La funzione restituisce un numero di socket descriptor positivo in caso di
+ successo e -1 in caso di errore, nel qual caso la variabile \texttt{errno}
+ viene settata ai seguenti valori:
+
+ \begin{errlist}
+ \item \texttt{EBADF} l'argomento \texttt{sockfd} non è un file descriptor
+ valido.
+ \item \texttt{ENOTSOCK} l'argomento \texttt{sockfd} non è un socket.
+ \item \texttt{EOPNOTSUPP} il socket è di un tipo che non supporta questa
+ operazione.
+ \item \texttt{EAGAIN} o \item \texttt{EWOULDBLOCK} il socket è stato
+ settato come non bloccante, e non ci sono connessioni in attesa di essere
+ accettate.
+ \item \texttt{EFAULT} l'argomento \texttt{addr} .
+ \item \texttt{EPERM} Firewall rules forbid connection.
+
+ \item \texttt{ENOBUFS, ENOMEM} Not enough free memory. This often means
+ that the memory allocation is limited by the socket buffer limits, not by
+ the system memory.
+
+ Inoltre possono essere restituiti gli errori di rete relativi al nuovo
+ socket come: \texttt{EMFILE}, \texttt{EINVAL}, \texttt{ENOSR},
+ \texttt{ENOBUFS}, \texttt{EPERM}, \texttt{ECONNABORTED},
+ \texttt{ESOCKTNOSUPPORT}, \texttt{EPROTONOSUPPORT}, \texttt{ETIMEDOUT},
+ \texttt{ERESTARTSYS}.
+
+ \end{errlist}
+\end{prototype}
+
+La funzione può essere usata solo con socket che supportino la connessione
+(cioè di tipo \texttt{SOCK\_STREAM}, \texttt{SOCK\_SEQPACKET} o
+\texttt{SOCK\_RDM}). Per alcuni protocolli che richiedono una conferma
+esplicita della connessione, (attualmente in Linux solo DECnet ha questo
+comportamento), la funzione opera solo l'estrazione dalla coda delle
+connessioni, la conferma della connessione viene fatta implicitamente dalla
+prima chiamata ad una \texttt{read} o una \texttt{write} mentre il rifiuto
+della connessione viene fatto con la funzione \texttt{close}.
+
+È da chiarire che Linux presenta un comportamento diverso nella gestione degli
+errori rispetto ad altre implementazioni dei socket BSD, infatti la funzione
+\texttt{accept} passa gli errori di rete pendenti sul nuovo socket come codici
+di errore per \texttt{accept}. Inoltre la funzione non fa ereditare ai nuovi
+socket flag come \texttt{O\_NONBLOCK}, che devono essere rispecificati volta
+volta, questo è un comportamento diverso rispetto a quanto accade con BSD e
+deve essere tenuto in conto per scrivere programmi portabili.
+
+I due argomenti \texttt{cliaddr} e \texttt{addrlen} (si noti che quest'ultimo
+è passato per indirizzo per avere indietro il valore) sono usati per ottenere
+l'indirizzo del client da cui proviene la connessione. Prima della chiamata
+\texttt{addrlen} deve essere inizializzato alle dimensioni della struttura il
+cui indirizzo è passato come argomento in \texttt{cliaddr}, al ritorno della
+funzione \texttt{addrlen} conterrà il numero di bytes scritti dentro
+\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:file_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}