Finito server daytime su UDP
authorSimone Piccardi <piccardi@gnulinux.it>
Sun, 21 Mar 2004 23:01:01 +0000 (23:01 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sun, 21 Mar 2004 23:01:01 +0000 (23:01 +0000)
listati/UDP_daytimed.c
othersock.tex
sources/UDP_daytimed.c

index f43853d17fa5fe6a9ba338da60e112ad77c53831..d0703f251abe04c0f5f5ed33ea6d06fbc673bd69 100644 (file)
@@ -23,7 +23,6 @@ int main(int argc, char *argv[])
     }
     /* write daytime to client */
     while (1) {
-       timeval = time(NULL);
        n = recvfrom(sock, buffer, MAXLINE, 0, (struct sockaddr *)&addr, &len);
        if (n < 0) {
            perror("recvfrom error");
@@ -34,6 +33,7 @@ int main(int argc, char *argv[])
            printf("Request from host %s, port %d\n", buffer,
                   ntohs(addr.sin_port));
        }
+       timeval = time(NULL);
        snprintf(buffer, sizeof(buffer), "%.24s\r\n", ctime(&timeval));
        n = sendto(sock, buffer, strlen(buffer), 0, 
                   (struct sockaddr *)&addr, sizeof(addr));
index 00ee9c6619378a94f1b9a11561e9983840efcc51..bbd2e7660399fab4d27c2368b117685a2bd15a34 100644 (file)
@@ -384,7 +384,6 @@ interromperemo. Vedremo in \secref{sec:UDP_connect} come si pu
 a questa problematica.
 
 
-
 \subsection{Un server UDP elementare}
 \label{sec:UDP_daytime_server}
 
@@ -442,6 +441,40 @@ socket, cos
 macchina che ha inviato il pacchetto con un messaggio ICMP di tipo
 \textit{port unreachable}.
 
+Una volta completata la fase di inizializzazione inizia il corpo principale
+(\texttt{\small 24--44}) del server, mantenuto all'interno di un ciclo
+infinito in cui si trattano le richieste. Il ciclo inizia (\texttt{\small 26})
+con una chiamata a \func{recvfrom}, che si bloccherà in attesa di pacchetti
+inviati dai client. Lo scopo della funzione è quello di ritornare tutte le
+volte che un pacchetto viene inviato al server, in modo da poter ricavare da
+esso l'indirizzo del client a cui inviare la risposta in \var{addr}. Per
+questo motivo in questo caso (al contrario di quanto fatto in
+\figref{fig:UDP_daytime_client}) si è avuto cura di passare gli opportuni
+argomenti alla funzione.  Dopo aver controllato (\texttt{\small 27--30}) la
+presenza di eventuali errori (uscendo con un messaggio di errore qualora ve ne
+siano) si verifica (\texttt{\small 31}) se è stata attivata l'opzione
+\texttt{-v} (che imposta la variabile \var{verbose}) stampando nel caso
+(\texttt{\small 32--35}) l'indirizzo da cui si è appena ricevuto una richiesta
+(questa sezione è identica a quella del server TCP illustrato in
+\figref{fig:TCP_daytime_cunc_server_code}).
+
+Una volta ricevuta la richiesta resta solo da ottenere il tempo corrente
+(\texttt{\small 36}) e costruire (\texttt{\small 37}) la stringa di risposta,
+che poi verrà inviata (\texttt{\small 38}) al client usando \func{sendto},
+avendo al solito cura di controllare (\texttt{\small 40--42}) lo stato di
+uscita della funzione e trattando opportunamente la condizione di errore.
+
+Si noti come per le peculiarità del protocollo si sia utilizzato un server
+iterativo, che processa le richieste una alla volta via via che gli arrivano.
+Questa è una caratteristica comune dei server UDP, conseguenza diretta del
+fatto che non esiste il concetto di connessione, per cui non c'è la necessità
+di trattare separatamente le singole connessioni. Questo significa anche che è
+il kernel a gestire la possibilità di richieste multiple in contemporanea;
+quello che succede è semplicemente che il kernel accumula in un buffer in
+ingresso i pacchetti che arrivano e li restituisce al processo uno alla volta
+per ciascuna chiamata di \func{recvfrom}; è poi compito del server distribuire
+le risposte sulla base dell'indirizzo da cui provengono le richieste.
+
 
 
 
@@ -457,7 +490,7 @@ iniziare una comunicazione con un server.
 \section{I socket \textit{Unix domain}}
 \label{sec:unix_socket}
 
-Benché i socket Unix domain non siano strattamente attinenti alla rete, in
+Benché i socket Unix domain non siano strettamente attinenti alla rete, in
 quanto definiscono una interfaccia di comunicazione locale alla singola
 macchina, li tratteremo comunque in questa sezione in quanto la loro
 interfaccia è comunque basata sulla più generale interfaccia dei socket.
index 4a7e03490b01ed76bfbc4229bed4b3eafab45d7d..6f607944e668c574699cd23d9e046b0eaadc7401 100644 (file)
@@ -26,7 +26,7 @@
  *
  * Usage: daytimed -h give all info
  *
- * $Id: UDP_daytimed.c,v 1.1 2004/03/21 18:30:35 piccardi Exp $
+ * $Id: UDP_daytimed.c,v 1.2 2004/03/21 23:01:01 piccardi Exp $
  *
  ****************************************************************/
 /* 
@@ -101,7 +101,6 @@ int main(int argc, char *argv[])
     }
     /* write daytime to client */
     while (1) {
-       timeval = time(NULL);
        n = recvfrom(sock, buffer, MAXLINE, 0, (struct sockaddr *)&addr, &len);
        if (n < 0) {
            perror("recvfrom error");
@@ -112,6 +111,7 @@ int main(int argc, char *argv[])
            printf("Request from host %s, port %d\n", buffer,
                   ntohs(addr.sin_port));
        }
+       timeval = time(NULL);
        snprintf(buffer, sizeof(buffer), "%.24s\r\n", ctime(&timeval));
        n = sendto(sock, buffer, strlen(buffer), 0, 
                   (struct sockaddr *)&addr, sizeof(addr));