Andato avanti con il server echo.
authorSimone Piccardi <piccardi@gnulinux.it>
Mon, 11 Jun 2001 22:15:57 +0000 (22:15 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Mon, 11 Jun 2001 22:15:57 +0000 (22:15 +0000)
elemtcp.tex
filedir.tex
main.tex
simpltcp.tex
sources/SimpleEchoTCPServer.c

index f8bc164e6c60eaaf500639e27ee82a882b710e95..38dcee79a9cf2a88d790e2e5a70f634dab3db2c7 100644 (file)
@@ -1068,7 +1068,7 @@ comunicazione.
 
 
 
 
 
 
-\subsection{Un esempio di server \textit{daytime}}
+\subsection{Un esempio di server \textit{daytime} concorrente}
 \label{sec:TCPel_cunc_daytime}
 
 Per illustrare il meccanismo usato in generale per creare un server
 \label{sec:TCPel_cunc_daytime}
 
 Per illustrare il meccanismo usato in generale per creare un server
@@ -1139,7 +1139,7 @@ int main(int argc, char *argv[])
   \end{lstlisting}
   \caption{Esempio di codice di un server concorrente elementare per il 
     servizio daytime.}
   \end{lstlisting}
   \caption{Esempio di codice di un server concorrente elementare per il 
     servizio daytime.}
-  \label{fig:net_cli_code}
+  \label{fig:TCPelem_serv_code}
 \end{figure}
 
 Come si può vedere (alle linee \texttt{\small 21--25}) la funzione
 \end{figure}
 
 Come si può vedere (alle linee \texttt{\small 21--25}) la funzione
index b16e2dc7b549f2f01a4d1276785025da5ed6fb07..e39d4c955a34d84bbabbd42533bfecb30751676b 100644 (file)
@@ -464,7 +464,7 @@ delle funzioni \texttt{stat}, questa 
 usa per poter stampare tutti i dati dei files; il prototipo della funzione è
 il seguente;
 \begin{prototype}{sys/stat.h}
 usa per poter stampare tutti i dati dei files; il prototipo della funzione è
 il seguente;
 \begin{prototype}{sys/stat.h}
-{int stat(const char *file_name, struct stat *buf)}
+{int stat(const char *file\_name, struct stat *buf)}
   
   La funzione restituisce zero in caso di successo e -1 per un errore, in caso
   di errore \texttt{errno} viene settato ai valori:
   
   La funzione restituisce zero in caso di successo e -1 per un errore, in caso
   di errore \texttt{errno} viene settato ai valori:
index 6f26a6d88cd700d7855886aa1f20910c17039057..6551c982346ed4ffbf5fea6a72c911887834cc9d 100644 (file)
--- a/main.tex
+++ b/main.tex
@@ -2,7 +2,7 @@
 %% GaPiL : Guida alla Programmazione in Linux
 %%
 %% S. Piccardi Feb. 2001
 %% GaPiL : Guida alla Programmazione in Linux
 %%
 %% S. Piccardi Feb. 2001
-%% 
+%%
 %% main.tex: file principale, gli altri vanno inclusi da questo.
 %%
 \documentclass[a4paper,11pt,twoside,italian]{book}
 %% main.tex: file principale, gli altri vanno inclusi da questo.
 %%
 \documentclass[a4paper,11pt,twoside,italian]{book}
@@ -94,7 +94,6 @@
 %  texcsststyle=\ttfamily,
   directivestyle=\color{magenta}\ttfamily
 }
 %  texcsststyle=\ttfamily,
   directivestyle=\color{magenta}\ttfamily
 }
-
 \include{intro}
 \include{fileintro}
 \include{filedir}
 \include{intro}
 \include{fileintro}
 \include{filedir}
index 5ee5a87a309861395ea5b76d4b224f1ec50f2eea..9f6b9498045c987158ebd4479b923c28c802507b 100644 (file)
@@ -25,7 +25,7 @@ uscita, fintanto che il chiamante non ha chiude la connessione; il servizio
 opera sulla porta 7.
 
 Nel nostro caso l'esempio sarà costituito da un client che legge una linea di
 opera sulla porta 7.
 
 Nel nostro caso l'esempio sarà costituito da un client che legge una linea di
-caratteri dallo standard input e la scrive sul server, il server leggerà una
+caratteri dallo standard input e la scrive sul server, il server leggerà la
 linea dalla connessione e la riscriverà all'indietro; sarà compito del client
 leggere la risposta del server e stamparla sullo standard output.
 
 linea dalla connessione e la riscriverà all'indietro; sarà compito del client
 leggere la risposta del server e stamparla sullo standard output.
 
@@ -33,6 +33,88 @@ Si 
 il prototipo ideale di una generica applicazione di rete in cui un server
 risponde alle richieste di un client; tutto quello che cambia nel caso si una
 applicazione più complessa è la elaborazione dell'input del client da parte
 il prototipo ideale di una generica applicazione di rete in cui un server
 risponde alle richieste di un client; tutto quello che cambia nel caso si una
 applicazione più complessa è la elaborazione dell'input del client da parte
-del server nel fornire le risposte in uscita.
+del server nel fornire le risposte in uscita. 
+
+\subsection{La struttura del server}
+\label{sec:TCPsimp_server_main}
+
+Il server si compone di un corpo principale, costituito dalla funzione
+\texttt{main} che si incarica di creare il socket, metterlo in ascolto di
+connessioni in arrivo e creare un processo figlio a cui delegare la gestione
+di ciascuna connessione. Questa parte, riportata in \nfig, è sostanzialmente
+identica a quella vista nell'esempio in \figref{sec:TCPelem_serv_code}.
+
+\begin{figure}[!htb]
+  \footnotesize
+  \begin{lstlisting}{}
+/* Subroutines declaration */
+void SockEcho(int sockfd);
+/* Program beginning */
+int main(int argc, char *argv[])
+{
+    int list_fd, conn_fd;
+    pid_t pid;
+    struct sockaddr_in serv_add;
+     ....
+    /* 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);
+    }
+    /* handle echo to client */
+    while (1) {
+        /* accept connection */
+        if ( (conn_fd = accept(list_fd, NULL, NULL)) < 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);          /* close listening socket */   
+            SockEcho(conn_fd);       /* handle echo */
+            exit(0);
+        } else {             /* parent */
+            close(conn_fd);          /* close connected socket */
+        }
+    }
+    /* normal exit, never reached */
+    exit(0);
+}
+  \end{lstlisting}
+  \caption{Codice della funzione \texttt{main} del server
+    \texttt{SimpleEchoTCPServer.c} per il servizio \texttt{echo}.}
+  \label{fig:TCPsimpl_serv_code}
+\end{figure}
+
+La struttura del server è sostanzialmente a quella dell'esempio precedente, ed
+ad esso si applicano le considerazioni fatte in
+\secref{sec:TCPel_cunc_daytime}, le uniche differenze rispetto all'esempio in
+\figref{sec:TCPelem_serv_code} è che in questo caso per il socket in ascolto
+viene usata la porta 7 e tutta la gestione della comunicazione è delegata alla
+funzione \texttt{SockEcho}.
+
+
+
+\subsection{Il client}
+\label{sec:TCPsimp_server_main}
 
 
 
 
index 35a2737cc061cecaa644c1a7dc539e2e07156943..8c0dff80698b6ff5806582a81803625625015d38 100644 (file)
@@ -8,7 +8,7 @@
  *
  * Usage: echod
  *
  *
  * Usage: echod
  *
- * $Id: SimpleEchoTCPServer.c,v 1.1 2001/06/10 11:47:17 piccardi Exp $ 
+ * $Id: SimpleEchoTCPServer.c,v 1.2 2001/06/11 22:15:57 piccardi Exp $ 
  *
  ****************************************************************/
 /* 
  *
  ****************************************************************/
 /* 
 #define BACKLOG 10
 #define MAXLINE 256
 
 #define BACKLOG 10
 #define MAXLINE 256
 
-/* Subroutine declaration */
+/* Subroutines declaration */
 void usage(void);
 void SockEcho(int sockfd);
 void usage(void);
 void SockEcho(int sockfd);
-
-/* Program begining */
+/* Program beginning */
 int main(int argc, char *argv[])
 {
 /* 
 int main(int argc, char *argv[])
 {
 /* 
@@ -77,7 +76,7 @@ int main(int argc, char *argv[])
     /* initialize address */
     memset((void *)&serv_add, 0, sizeof(serv_add)); /* clear server address */
     serv_add.sin_family = AF_INET;                  /* address type is INET */
     /* 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_port = htons(7);                   /* echo port is 7 */
     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) {
     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) {