-\begin{figure}[!htbp]
- \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>
-#define MAXLINE 80
-#define BACKLOG 10
-int main(int argc, char *argv[])
-{
-/*
- * Variables definition
- */
- int list_fd, conn_fd;
- int i;
- struct sockaddr_in serv_add;
- char buffer[MAXLINE];
- time_t timeval;
-
- ...
-
- /* create socket */
- if ( (list_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- perror("Socket creation error");
- exit(-1);
- }
- /* initialize address */
- memset((void *)&serv_add, 0, sizeof(serv_add)); /* clear server address */
- serv_add.sin_family = AF_INET; /* address type is INET */
- serv_add.sin_port = htons(13); /* daytime port is 13 */
- serv_add.sin_addr.s_addr = htonl(INADDR_ANY); /* connect from anywhere */
- /* bind socket */
- if (bind(list_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
- perror("bind error");
- exit(-1);
- }
- /* listen on socket */
- if (listen(list_fd, BACKLOG) < 0 ) {
- perror("listen error");
- exit(-1);
- }
- /* write daytime to client */
- while (1) {
- if ( (conn_fd = accept(list_fd, (struct sockaddr *) NULL, NULL)) <0 ) {
- perror("accept error");
- exit(-1);
- }
- 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);
- }
- close(conn_fd);
- }
- /* normal exit */
- exit(0);
-}
- \end{lstlisting}
- \caption{Esempio di codice di un semplice server per il servizio daytime.}
- \label{fig:net_serv_code}
-\end{figure}
-
-Come per il client si includono gli header necessari a cui è aggiunto quello
-per trattare i tempi, e si definiscono alcune costanti e le variabili
-necessarie in seguito (\texttt{\small 1--18}), come nel caso precedente si
-sono omesse le parti relative al trattamento delle opzioni da riga di comando.
-
-La creazione del socket (\texttt{\small 22--26}) è analoga al caso precedente,
-come pure l'inizializzazione della struttura \texttt{sockaddr\_in}, anche in
-questo caso si usa la porta standard del servizio daytime, ma come indirizzo
-IP si il valore predefinito \texttt{INET\_ANY} che corrisponde ad un indirizzo
-generico (\texttt{\small 27--31}).
-
-Si effettua poi (\texttt{\small 32--36}) la chiamata alla funzione
-\texttt{bind} che permette di associare la precedente struttura al socket, in
-modo che quest'ultimo possa essere usato per accettare connessioni su una
-qualunque delle interfacce di rete locali.
-
-Il passo successivo (\texttt{\small 37--41}) è mettere ``in ascolto'' il
-socket, questo viene effettuato con la funzione \texttt{listen} che dice al
-kernel di accettare connessioni per il socket specificato, la funzione indica
-inoltre, con il secondo parametro, il numero massimo di connessioni che il
-kernel accetterà di mettere in coda per il suddetto socket.
-
-Questa ultima chiamata completa la preparazione del socket per l'ascolto (che
-viene chiamato anche \textit{listening descriptor}) a questo punto il processo
-è mandato in sleep (\texttt{\small 44--47}) con la successiva chiamata alla
-funzione \texttt{accept}, fin quando non arriva e viene accettata una
-connessione da un client.
-
-Quando questo avviene \texttt{accept} ritorna un secondo descrittore di
-socket, che viene chiamato \textit{connected descriptor} che è quello che
-viene usato dalla successiva chiamata alla \texttt{write} per scrivere la
-risposta al client, una volta che si è opportunamente (\texttt{\small 48--49})
-costruita la stringa con la data da trasmettere. Completata la trasmissione il
-nuovo socket viene chiuso (\texttt{\small 54}).
-Il tutto è inserito in un loop infinito (\texttt{\small 42--55}) in modo da
-poter ripetere l'invio della data ad una successiva connessione.
-
-È impostante notare che questo server è estremamente elementare, infatti a
-parte il fatto di essere dipendente da IPv4, esso è in grado di servire solo
-un client alla volta, è cioè un \textsl{server iterativo}, inoltre esso è
-scritto per essere lanciato da linea di comando, se lo si volesse utilizzare
-come demone di sistema (che è in esecuzione anche quando non c'è nessuna shell
-attiva), occorrerebbero delle opportune modifiche.