From: Simone Piccardi Date: Mon, 2 Apr 2001 23:24:42 +0000 (+0000) Subject: Inserito il package listings ... e adesso ho la syntax highlight dei X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=a8d6fb4cf9036d69f2884d9ba9d9350f649ed401 Inserito il package listings ... e adesso ho la syntax highlight dei sorgenti automatizzata (e totalmente customizzabile) semplicemente copiandoli dentro il latex !!! E c'e` pure qualcuno che continua a insistere col docbook ... puah Fatto pure un programma di esempio (client daytime) e inserite le prime spiegazioni. --- diff --git a/main.tex b/main.tex index dfdfb15..da2fd97 100644 --- a/main.tex +++ b/main.tex @@ -9,6 +9,9 @@ \usepackage{amsmath} \usepackage{amsfonts} \usepackage[hang,bf,footnotesize,it]{caption2} +\usepackage{listings} +\lstloadlanguages{C++} +\usepackage{color} % % Setting page layout % @@ -65,6 +68,26 @@ \pagenumbering{arabic} + +\lstset{language=C++} + +\lstset{basicstyle=\small, + labelstyle=\tiny, + labelstep=1, + labelsep=2pt, + frame=TB, + frametextsep=5pt, + basicstyle=\ttfamily, + keywordstyle=\color{blue}\ttfamily, + ndkeywordstyle=\color{yellow}\ttfamily, +% rdkeywordstyle=\ttfamily, + identifierstyle=\ttfamily, + commentstyle=\color{red}\ttfamily, + stringstyle=\color{green}\ttfamily, +% texcsststyle=\ttfamily, + directivestyle=\color{magenta}\ttfamily +} + \include{intro} \include{files} \include{process} diff --git a/network.tex b/network.tex index 531d731..3a72f11 100644 --- a/network.tex +++ b/network.tex @@ -6,9 +6,9 @@ come prerequisiti per capire la programmazione di rete ed esamineremo a grandi linee i protocolli di rete e come questi sono organizzati e interagiscono. In particolare, avendo assunto l'ottica di un'introduzione mirata alla -programmazione di rete, ci concentreremo sul protocollo più diffuso che è -quello che sta alla base di internet, ed in particolare sulle parti più -importanti ai fini della programmazione. +programmazione, ci concentreremo sul protocollo più diffuso che è quello che +sta alla base di internet, ed in particolare sulle parti più importanti ai +fini della programmazione. \section{Il modello client-server} @@ -30,7 +30,8 @@ definito insieme di servizi. Esempi di questo modello sono il WEB, ftp, telnet, ssh e praticamente ogni servizio che viene fornito tramite la rete, ma il modello è utilizzato in -generale anche per programmi di uso locale. +generale anche per programmi che non fanno necessariamente uso della rete, +come il sistema a finestre. Normalmente si dividono i server in due categorie principali, \textit{concorrenti} e \textit{iterativi}, sulla base del loro comportamento. @@ -47,6 +48,124 @@ contemporaneamente, una volta che il processo figlio ha concluso il suo lavoro viene terminato, mentre il server originale resta sempre attivo. +\subsection{Un primo esempio di client} +\label{sec:net_cli_sample} + +Per evitare di rendere l'esposizione dei concetti generali puramente teorica +iniziamo con il mostrare un semplice esempio di client TCP. In \nfig è +riportata la sezione principale del codice del nostro client elementare per il +servizio \textit{daytime}, un servizio standard che restituisce l'ora locale +della macchina a cui si effettua la richesta. + +\begin{figure}[htbp] + \footnotesize + \begin{lstlisting}{} +#include /* predefined types */ +#include /* include unix standard library */ +#include /* IP addresses conversion utiliites */ +#include /* socket library */ +#include /* include standard I/O library */ + +int main(int argc, char *argv[]) +{ + int sock_fd; + int i, nread; + struct sockaddr_in serv_add; + char buffer[MAXLINE]; + ... + /* create socket */ + if ( (sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("Socket creation error"); + return -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 post is 13 */ + /* build address using inet_pton */ + if ( (inet_pton(AF_INET, argv[optind], &serv_add.sin_addr)) <= 0) { + perror("Address creation error"); + return -1; + } + /* extablish connection */ + if (connect(sock_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) { + perror("Connection error"); + return -1; + } + /* read daytime from server */ + while ( (nread = read(sock_fd, buffer, MAXLINE)) > 0) { + buffer[nread]=0; + if (fputs(buffer, stdout) == EOF) { /* write daytime */ + perror("fputs error"); + return -1; + } + } + /* error on read */ + if (nread < 0) { + perror("Read error"); + return -1; + } + /* normal exit */ + return 0; +} + \end{lstlisting} + \caption{Esempio di codice di un semplice client per il servizio daytime.} + \label{fig:net_cli_code} +\end{figure} + + +Scopo di questo esempio è fornire un primo approccio alla programmazione di +rete, per questo motivo non ci dilungheremo nel trattare il significato dei +termini o il funzionamento delle varie funzioni utilizzate. Tutto questo sarà +esaminato in dettaglio nel seguito, per cui qui ci limiteremo a citarli senza +ulteriori spiegazioni. + +Il listato completo del programma (che comprende il trattamento delle opzioni +e una funzione per stampare un messaggio di aiuto) è allegato alla guida nella +sezione dei codici sorgente e può essere compilato su una qualunque macchina +linux. + +Il programma anzitutto include gli header necessari (\texttt{\small 1--5}); +dopo la dichiarazione delle variabili (\texttt{\small 9--12}), si è omessa +tutta la parte relativa al trattamento degli argomenti passati dalla linea di +comando effettuata con le apposite routines illustrate in +\ref{cha:parameter_options}. + +Il primo passo (\texttt{\small 14--18}è creare un \textit{socket} internet +(\texttt{AF\_INET}), di tipo TCP \texttt{SOCK\_STREAM}), la funzione ritorna +un descrittore, analogo a quello dei file, che viene usato per identificare il +socket in tutte le chiamate successive. Nel caso la chiamata fallisca si +stampa un errore con la relativa routine e si esce. + +Il passo seguente (\texttt{\small 19--27}) è quello di costruire una apposita +struttura \texttt{sockaddr\_in} in cui sarà inserito l'indirizzo del server ed +il numero della porta del servizio. Il primo passo è inizializzare tutto a +zero, poi si setta il tipo di protocollo e la porta (usando la funzione +\texttt{htons} per convertire il formato dell'intero a quello usato nella +rete), infine si utilizza la funzione \texttt{inet\_pton} per convertire +l'indirizzo numerico passato dalla linea di comando. + +Usando la funzione \texttt{connect} (\texttt{\small 28--32}) si provvede poi a +stabilire la connessione con il server. Un valore negativo + +\subsection{Un primo esempio di server} +\label{sec:net_serv_sample} + +Dopo aver visto il client facciamo vedere adesso anche il corrispettivo +server, in questo modo sarà possibile fare delle prove + +\begin{figure}[htbp] + \begin{center} + \begin{verbatim} + + + \end{verbatim} + \caption{Esempio di codice di un semplice server per il servizio daytime.} + \label{fig:net_serv_code} + \end{center} +\end{figure} + + \section{I protocolli di rete} \label{sec:net_protocols} @@ -456,6 +575,8 @@ stesso tempo, il che poi comporta che quanto dicevamo a proposito del controllo di flusso e della gestione della sequenzialità dei dati viene effettuato per entrambe le direzioni di comunicazione. + + \subsection{Creazione e terminazione della connessione TCP} Per capire il funzionamento delle funzioni della interfaccia dei socket che diff --git a/option.tex b/option.tex index 52dab01..05da09e 100644 --- a/option.tex +++ b/option.tex @@ -1,4 +1,5 @@ \chapter{Gestione di parametri e opzioni} +\label{cha:parameter_options} Il passaggio dei parametri e delle variabili di ambiente dalla riga di comando al singolo programma quando viene lanciato è effettuato attraverso le @@ -10,7 +11,7 @@ come argomenti della funzione principale: \end{verbatim} \section{Il formato dei parametri} - +\label{sec:par_format} Il passaggio dei parametri al programma viene effettuato dalla shell, che si incarica di leggere la linea di comando e di effettuarne la scansione (il cosiddetto \textit{parsing}) per individuare le parole che la compongono, @@ -24,6 +25,7 @@ variabile \texttt{argc} viene inizializzata al numero di parametri trovati, in questo modo il primo parametro è sempre il nome del programma (vedi \nfig). \section{La gestione delle opzioni} +\label{sec:opt_handling} In generale un programma unix riceve da linea di comando sia i parametri che le opzioni, queste ultime sono standardizzate per essere riconosciute come @@ -79,9 +81,10 @@ case; la funzione inizializza inoltre alcune varibili globali: In \nfig è mostrato un programma di esempio, + \begin{figure}[htbp] - \begin{center} - \begin{verbatim} + \footnotesize + \begin{lstlisting}{} opterr = 0; /* don't want writing to stderr */ while ( (i = getopt(argc, argv, "o:a:i:hve")) != -1) { switch (i) { @@ -119,13 +122,13 @@ In \nfig } } debug("Optind %d, argc %d\n",optind,argc); - \end{verbatim} - \caption{Esempio di codice per la gestione delle opzioni.} - \label{fig:options_code} - \end{center} + \end{lstlisting} + \caption{Esempio di codice per la gestione delle opzioni.} + \label{fig:options_code} \end{figure} \subsection{Opzioni in formato esteso} +\label{sec:opt_extended} Un'estensione di questo schema è costituito dalle cosiddette \textit{long-options} espresse nella forma \texttt{--option=parameter}, anche @@ -134,6 +137,8 @@ versione estesa di \texttt{getopt}. \section{Le variabili di ambiente} +\label{sec:par_env_var} + Questo va fatto. diff --git a/sources/SimpleDaytimeTCPClient.c b/sources/SimpleDaytimeTCPClient.c new file mode 100644 index 0000000..7704c8a --- /dev/null +++ b/sources/SimpleDaytimeTCPClient.c @@ -0,0 +1,109 @@ +/**************************************************************** + * + * Program daytime_tcp_client.c: + * Simple TCP client for daytime service (port 13) + * + * Author: Simone Piccardi + * Apr. 2001 + * + * Usage: daytime -h give all info's + * + * $Id: SimpleDaytimeTCPClient.c,v 1.1 2001/04/02 23:24:42 piccardi Exp $ + * + ****************************************************************/ +/* + * Include needed headers + */ +#include /* predefined types */ +#include /* include unix standard library */ +#include /* IP addresses conversion utiliites */ +#include /* socket library */ +#include /* include standard I/O library */ + +#define MAXLINE 80 +/* Program begin */ +void usage(void); +int main(int argc, char *argv[]) +{ +/* + * Variables definition + */ + int sock_fd; + int i, nread; + struct sockaddr_in serv_add; + char buffer[MAXLINE]; + /* + * Input section: decode parameters passed in the calling + * Use getopt function + */ + opterr = 0; /* don't want writing to stderr */ + while ( (i = getopt(argc, argv, "h")) != -1) { + switch (i) { + /* + * Handling options + */ + case 'h': + printf("Wrong -h option use\n"); + usage(); + return(0); + break; + case '?': /* unrecognized options */ + printf("Unrecognized options -%c\n",optopt); + usage(); + default: /* should not reached */ + usage(); + } + } + /* *********************************************************** + * + * Options processing completed + * + * Main code beginning + * + * ***********************************************************/ + /* create socket */ + if ( (sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("Socket creation error"); + return -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 post is 13 */ + /* build address using inet_pton */ + if ( (inet_pton(AF_INET, argv[optind], &serv_add.sin_addr)) <= 0) { + perror("Address creation error"); + return -1; + } + /* extablish connection */ + if (connect(sock_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) { + perror("Connection error"); + return -1; + } + /* read daytime from server */ + while ( (nread = read(sock_fd, buffer, MAXLINE)) > 0) { + buffer[nread]=0; + if (fputs(buffer, stdout) == EOF) { /* write daytime */ + perror("fputs error"); + return -1; + } + } + /* error on read */ + if (nread < 0) { + perror("Read error"); + return -1; + } + /* normal exit */ + return 0; +} +/* + * routine to print usage info and exit + */ +void usage(void) { + printf("Take daytime from a remote host \n"); + printf("Usage:\n"); + printf(" daytime [-h] [-v] [host in dotted decimal form] \n"); + printf(" -v set verbosity on\n"); + printf(" -h print this help\n"); + exit(1); +}