From f3bb4dd6dfe5a8d568dca64c56c870508090c168 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Sun, 21 Mar 2004 23:01:01 +0000 Subject: [PATCH] Finito server daytime su UDP --- listati/UDP_daytimed.c | 2 +- othersock.tex | 37 +++++++++++++++++++++++++++++++++++-- sources/UDP_daytimed.c | 4 ++-- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/listati/UDP_daytimed.c b/listati/UDP_daytimed.c index f43853d..d0703f2 100644 --- a/listati/UDP_daytimed.c +++ b/listati/UDP_daytimed.c @@ -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)); diff --git a/othersock.tex b/othersock.tex index 00ee9c6..bbd2e76 100644 --- a/othersock.tex +++ b/othersock.tex @@ -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. diff --git a/sources/UDP_daytimed.c b/sources/UDP_daytimed.c index 4a7e034..6f60794 100644 --- a/sources/UDP_daytimed.c +++ b/sources/UDP_daytimed.c @@ -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)); -- 2.30.2