X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=socket.tex;h=54e7d48662850309a35c522406d298928c910023;hp=0daa53a70e7955c208202a8e6f4e5774c69b4e70;hb=e2a1ad24365266ea8846b688addd4e7694428969;hpb=d88ea986fbf6b84a802fd8a5665af4324a6c89b3 diff --git a/socket.tex b/socket.tex index 0daa53a..54e7d48 100644 --- a/socket.tex +++ b/socket.tex @@ -108,44 +108,43 @@ il tipo di comunicazione che esso deve utilizzare. \label{sec:sock_socket} La creazione di un socket avviene attraverso l'uso della funzione -\func{socket} questa restituisce un \textit{socket descriptor} (un valore -intero non negativo) che come gli analoghi file descriptor di file e alle -pipe serve come riferimento al socket; in sostanza è l'indice nella tabella -dei file che contiene i puntatori alle opportune strutture usate dal kernel ed -allocate per ogni processo, (la stessa usata per i files e le pipes [NdA -verificare!]). - -La funzione prende tre parametri, il dominio del socket (che definisce la -famiglia di protocolli, vedi \secref{sec:sock_domain}), il tipo di socket (che -definisce lo stile di comunicazione vedi \secref{sec:sock_type}) e il -protocollo; in genere quest'ultimo è indicato implicitamente dal tipo di -socket, per cui viene messo a zero (con l'eccezione dei \textit{raw socket}). - +\func{socket}; questa restituisce un \textit{file descriptor}\footnote{del + tutto analogo a quelli che si ottengono per i file di dati e le pipe, + descritti in \secref{sec:file_fd}.} che serve come riferimento al socket; il +suo protototipo è: \begin{prototype}{sys/socket.h}{int socket(int domain, int type, int protocol)} Apre un socket. - \bodydesc{La funzione restituisce un intero positivo se riesce, e -1 se - fallisce, in quest'ultimo caso la variabile \var{errno} è impostata con i - seguenti codici di errore: - + \bodydesc{La funzione restituisce un intero positivo in caso di successo, e + -1 in caso di fallimento, nel qual caso la variabile \var{errno} assumerà + i valori: \begin{errlist} - \item[\macro{EPROTONOSUPPORT}] Il tipo di socket o il protocollo scelto non + \item[\errcode{EPROTONOSUPPORT}] Il tipo di socket o il protocollo scelto non sono supportati nel dominio. - \item[\macro{ENFILE}] Il kernel non ha memoria sufficiente a creare una + \item[\errcode{ENFILE}] Il kernel non ha memoria sufficiente a creare una nuova struttura per il socket. - \item[\macro{EMFILE}] Si è ecceduta la tabella dei file. - \item[\macro{EACCES}] Non si hanno privilegi per creare un socket nel + \item[\errcode{EMFILE}] Si è ecceduta la tabella dei file. + \item[\errcode{EACCES}] Non si hanno privilegi per creare un socket nel dominio o con il protocollo specificato. - \item[\macro{EINVAL}] Protocollo sconosciuto o dominio non disponibile. - \item[\macro{ENOBUFS}] Non c'è sufficiente memoria per creare il socket (può - essere anche \macro{ENOMEM}). + \item[\errcode{EINVAL}] Protocollo sconosciuto o dominio non disponibile. + \item[\errcode{ENOBUFS}] Non c'è sufficiente memoria per creare il socket + (può essere anche \errval{ENOMEM}). \end{errlist}} \end{prototype} -Si noti che la creazione del socket non comporta nulla riguardo -all'indicazione degli indirizzi remoti o locali attraverso i quali si vuole -effettuare la comunicazione. +La funzione ha tre argomenti, \param{domain} specifica il dominio del socket +(definisce cioè la famiglia di protocolli, come vedremo in +\secref{sec:sock_domain}), \param{type} specifica il tipo di socket (definisce +cioè lo stile di comunicazione, come vedremo in \secref{sec:sock_type}) e +\param{protocol} il protocollo; in genere quest'ultimo è indicato +implicitamente dal tipo di socket, per cui viene messo a zero (con l'eccezione +dei \textit{raw socket}). + +Si noti che la creazione del socket si limita ad allocare le opportune +strutture nel kernel (sostanzialmente una voce nella \textit{file table}) e +non comporta nulla riguardo all'indicazione degli indirizzi remoti o locali +attraverso i quali si vuole effettuare la comunicazione. \subsection{Il dominio, o \textit{protocol family}} \label{sec:sock_domain} @@ -184,17 +183,17 @@ protocolli disponibili sono riportate in \tabref{tab:net_pf_names}. \textbf{Nome} & \textbf{Utilizzo} &\textbf{Man page} \\ \hline \hline - \macro{PF\_UNIX}, - \macro{PF\_LOCAL} & Local communication & unix(7) \\ - \macro{PF\_INET} & IPv4 Internet protocols & ip(7) \\ - \macro{PF\_INET6} & IPv6 Internet protocols & ipv6(7) \\ - \macro{PF\_IPX} & IPX - Novell protocols & \\ - \macro{PF\_NETLINK}& Kernel user interface device & netlink(7) \\ - \macro{PF\_X25} & ITU-T X.25 / ISO-8208 protocol & x25(7) \\ - \macro{PF\_AX25} & Amateur radio AX.25 protocol & \\ - \macro{PF\_ATMPVC} & Access to raw ATM PVCs & \\ - \macro{PF\_APPLETALK}& Appletalk & ddp(7) \\ - \macro{PF\_PACKET} & Low level packet interface & packet(7) \\ + \const{PF\_UNIX}, + \const{PF\_LOCAL} & Local communication & unix(7) \\ + \const{PF\_INET} & IPv4 Internet protocols & ip(7) \\ + \const{PF\_INET6} & IPv6 Internet protocols & ipv6(7) \\ + \const{PF\_IPX} & IPX - Novell protocols & \\ + \const{PF\_NETLINK}& Kernel user interface device & netlink(7) \\ + \const{PF\_X25} & ITU-T X.25 / ISO-8208 protocol & x25(7) \\ + \const{PF\_AX25} & Amateur radio AX.25 protocol & \\ + \const{PF\_ATMPVC} & Access to raw ATM PVCs & \\ + \const{PF\_APPLETALK}& Appletalk & ddp(7) \\ + \const{PF\_PACKET} & Low level packet interface & packet(7) \\ \hline \end{tabular} \caption{Famiglie di protocolli definiti in Linux} @@ -202,9 +201,9 @@ protocolli disponibili sono riportate in \tabref{tab:net_pf_names}. \end{table} Non tutte le famiglie di protocolli sono accessibili dall'utente generico, ad -esempio in generale tutti i socket di tipo \macro{SOCK\_RAW} possono essere +esempio in generale tutti i socket di tipo \const{SOCK\_RAW} possono essere creati solo da processi che hanno i privilegi di root (cioè con userid -effettivo uguale a zero) o con la capability \macro{CAP\_NET\_RAW}. +effettivo uguale a zero) o con la capability \texttt{CAP\_NET\_RAW}. \subsection{Il tipo, o stile} @@ -219,23 +218,23 @@ della \acr{glibc} chiama \textit{styles}) definiti come \ctyp{int} in \file{socket.h}: \begin{list}{}{} -\item \macro{SOCK\_STREAM} Provvede un canale di trasmissione dati +\item \const{SOCK\_STREAM} Provvede un canale di trasmissione dati bidirezionale, sequenziale e affidabile. Opera su una connessione con un altro socket. I dati vengono ricevuti e trasmessi come un flusso continuo di byte (da cui il nome \textit{stream}). -\item \macro{SOCK\_DGRAM} Viene usato per mandare pacchetti di lunghezza +\item \const{SOCK\_DGRAM} Viene usato per mandare pacchetti di lunghezza massima fissata (\textit{datagram}) indirizzati singolarmente, senza connessione e in maniera non affidabile. È l'opposto del precedente. -\item \macro{SOCK\_SEQPACKET} Provvede un canale di trasmissione di dati +\item \const{SOCK\_SEQPACKET} Provvede un canale di trasmissione di dati bidirezionale, sequenziale e affidabile. Opera su una connessione con un altro socket. I dati possono solo essere trasmessi e letti per pacchetti (di dimensione massima fissata). -\item \macro{SOCK\_RAW} Provvede l'accesso a basso livello ai protocolli di +\item \const{SOCK\_RAW} Provvede l'accesso a basso livello ai protocolli di rete e alle varie interfacce. I normali programmi di comunicazione non devono usarlo. -\item \macro{SOCK\_RDM} Provvede un canale di trasmissione di pacchetti +\item \const{SOCK\_RDM} Provvede un canale di trasmissione di pacchetti affidabile ma in cui non è garantito l'ordine di arrivo dei pacchetti. -\item \macro{SOCK\_PACKET} Obsoleto, non deve essere usato. +\item \const{SOCK\_PACKET} Obsoleto, non deve essere usato. \end{list} Si tenga presente che non tutte le combinazioni fra una famiglia di protocolli @@ -247,31 +246,31 @@ elencati. \footnotesize \centering \begin{tabular}{l|c|c|c|c|c|} - \multicolumn{1}{c}{} &\multicolumn{1}{c}{\macro{SOCK\_STREAM}}& - \multicolumn{1}{c}{\macro{SOCK\_DGRAM}} & - \multicolumn{1}{c}{\macro{SOCK\_RAW}} & - \multicolumn{1}{c}{\macro{SOCK\_PACKET}}& - \multicolumn{1}{c}{\macro{SOCK\_SEQPACKET}} \\ + \multicolumn{1}{c}{} &\multicolumn{1}{c}{\const{SOCK\_STREAM}}& + \multicolumn{1}{c}{\const{SOCK\_DGRAM}} & + \multicolumn{1}{c}{\const{SOCK\_RAW}} & + \multicolumn{1}{c}{\const{SOCK\_PACKET}}& + \multicolumn{1}{c}{\const{SOCK\_SEQPACKET}} \\ \cline{2-6} - \macro{PF\_UNIX} & si & si & & & \\ + \const{PF\_UNIX} & si & si & & & \\ \cline{2-6} - \macro{PF\_INET} & TCP & UDP & IPv4 & & \\ + \const{PF\_INET} & TCP & UDP & IPv4 & & \\ \cline{2-6} - \macro{PF\_INET6} & TCP & UDP & IPv6 & & \\ + \const{PF\_INET6} & TCP & UDP & IPv6 & & \\ \cline{2-6} - \macro{PF\_IPX} & & & & & \\ + \const{PF\_IPX} & & & & & \\ \cline{2-6} - \macro{PF\_NETLINK} & & si & si & & \\ + \const{PF\_NETLINK} & & si & si & & \\ \cline{2-6} - \macro{PF\_X25} & & & & & si \\ + \const{PF\_X25} & & & & & si \\ \cline{2-6} - \macro{PF\_AX25} & & & & & \\ + \const{PF\_AX25} & & & & & \\ \cline{2-6} - \macro{PF\_ATMPVC} & & & & & \\ + \const{PF\_ATMPVC} & & & & & \\ \cline{2-6} - \macro{PF\_APPLETALK} & & si & si & & \\ + \const{PF\_APPLETALK} & & si & si & & \\ \cline{2-6} - \macro{PF\_PACKET} & & si & si & & \\ + \const{PF\_PACKET} & & si & si & & \\ \cline{2-6} \end{tabular} \caption{Combinazioni valide di dominio e tipo di protocollo per la @@ -321,13 +320,15 @@ generica per gli indirizzi dei socket, \type{sockaddr}, che si \figref{fig:sock_sa_gen_struct}. \begin{figure}[!htb] - \footnotesize - \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} + \footnotesize \centering + \begin{minipage}[c]{15cm} + \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{} struct sockaddr { sa_family_t sa_family; /* address family: AF_xxx */ char sa_data[14]; /* address (protocol-specific) */ }; - \end{lstlisting} + \end{lstlisting} + \end{minipage} \caption{La struttura generica degli indirizzi dei socket \type{sockaddr}} \label{fig:sock_sa_gen_struct} \end{figure} @@ -344,6 +345,7 @@ include in cui sono definiti; la struttura \begin{table}[!htb] \centering + \footnotesize \begin{tabular}{|l|l|l|} \hline \multicolumn{1}{|c|}{\textbf{Tipo}}& @@ -391,15 +393,16 @@ l'uso di questa struttura. \subsection{La struttura degli indirizzi IPv4} \label{sec:sock_sa_ipv4} -I socket di tipo \macro{PF\_INET} vengono usati per la comunicazione +I socket di tipo \const{PF\_INET} vengono usati per la comunicazione attraverso internet; la struttura per gli indirizzi per un socket internet (IPv4) è definita come \type{sockaddr\_in} nell'header file \file{netinet/in.h} e secondo le pagine di manuale ha la forma mostrata in \figref{fig:sock_sa_ipv4_struct}, conforme allo standard POSIX.1g. \begin{figure}[!htb] - \footnotesize - \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} + \footnotesize\centering + \begin{minipage}[c]{15cm} + \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{} struct sockaddr_in { sa_family_t sin_family; /* address family: AF_INET */ u_int16_t sin_port; /* port in network byte order */ @@ -409,7 +412,8 @@ struct sockaddr_in { struct in_addr { u_int32_t s_addr; /* address in network byte order */ }; - \end{lstlisting} + \end{lstlisting} + \end{minipage} \caption{La struttura degli indirizzi dei socket internet (IPv4) \type{sockaddr\_in}.} \label{fig:sock_sa_ipv4_struct} @@ -426,7 +430,7 @@ Il membro \var{sin\_family} deve essere sempre impostato; \var{sin\_port} specifica il numero di porta (vedi \secref{sec:TCPel_port_num}; i numeri di porta sotto il 1024 sono chiamati \textsl{riservati} in quanto utilizzati da servizi standard. Soltanto processi con i privilegi di root (con userid -effettivo uguale a zero) o con la capability \macro{CAP\_NET\_BIND\_SERVICE} +effettivo uguale a zero) o con la capability \texttt{CAP\_NET\_BIND\_SERVICE} possono usare la funzione \func{bind} su queste porte. Il membro \var{sin\_addr} contiene l'indirizzo internet dell'altro capo @@ -445,14 +449,15 @@ problema e le relative soluzioni). \subsection{La struttura degli indirizzi IPv6} \label{sec:sock_sa_ipv6} -Essendo IPv6 un'estensione di IPv4 i socket di tipo \macro{PF\_INET6} sono +Essendo IPv6 un'estensione di IPv4 i socket di tipo \const{PF\_INET6} sono sostanzialmente identici ai precedenti; la parte in cui si trovano praticamente tutte le differenze è quella della struttura degli indirizzi. La struttura degli indirizzi è definita ancora in \file{netinet/in.h}. \begin{figure}[!htb] - \footnotesize - \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} + \footnotesize \centering + \begin{minipage}[c]{15cm} + \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{} struct sockaddr_in6 { u_int16_t sin6_family; /* AF_INET6 */ u_int16_t sin6_port; /* port number */ @@ -464,14 +469,15 @@ struct sockaddr_in6 { struct in6_addr { unsigned char s6_addr[16]; /* IPv6 address */ }; - \end{lstlisting} + \end{lstlisting} + \end{minipage} \caption{La struttura degli indirizzi dei socket IPv6 \type{sockaddr\_in6}.} \label{fig:sock_sa_ipv6_struct} \end{figure} Il campo \var{sin6\_family} deve essere sempre impostato ad -\macro{AF\_INET6}, il campo \var{sin6\_port} è analogo a quello di IPv4 e +\const{AF\_INET6}, il campo \var{sin6\_port} è analogo a quello di IPv4 e segue le stesse regole; il campo \var{sin6\_flowinfo} è a sua volta diviso in tre parti di cui i 24 bit inferiori indicano l'etichetta di flusso, i successivi 4 bit la priorità e gli ultimi 4 sono riservati; questi valori @@ -490,7 +496,7 @@ possibilit \subsection{La struttura degli indirizzi locali} \label{sec:sock_sa_local} -I socket di tipo \macro{PF\_UNIX} o \macro{PF\_LOCAL} vengono usati per una +I socket di tipo \const{PF\_UNIX} o \const{PF\_LOCAL} vengono usati per una comunicazione fra processi che stanno sulla stessa macchina (per vengono chiamati \textit{local domain} o anche \textit{Unix domain}); essi rispetto ai precedenti possono essere anche creati in maniera anonima attraverso la @@ -499,20 +505,22 @@ vuole fare riferimento esplicito ad uno di questi socket si deve usare la seguente struttura di indirizzi definita nel file di header \file{sys/un.h}. \begin{figure}[!htb] - \footnotesize - \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} + \footnotesize \centering + \begin{minipage}[c]{15cm} + \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{} #define UNIX_PATH_MAX 108 struct sockaddr_un { sa_family_t sun_family; /* AF_UNIX */ char sun_path[UNIX_PATH_MAX]; /* pathname */ }; - \end{lstlisting} + \end{lstlisting} + \end{minipage} \caption{La struttura degli indirizzi dei socket locali \var{sockaddr\_un}.} \label{fig:sock_sa_local_struct} \end{figure} -In questo caso il campo \var{sun\_family} deve essere \macro{AF\_UNIX}, +In questo caso il campo \var{sun\_family} deve essere \const{AF\_UNIX}, mentre il campo \var{sun\_path} deve specificare un indirizzo; questo ha due forme un file (di tipo socket) nel filesystem o una stringa univoca (tenuta in uno spazio di nomi astratto). Nel primo caso l'indirizzo viene @@ -598,26 +606,28 @@ Per questo motivo si usano le seguenti funzioni di conversione che servono a tener conto automaticamente della possibile differenza fra l'ordinamento usato sul computer e quello che viene usato nelle trasmissione sulla rete; queste funzioni sono: -\begin{prototype}{netinet/in.h} -{unsigned long int htonl(unsigned long int hostlong)} +\begin{functions} + \headdecl{netinet/in.h} + \funcdecl{unsigned long int htonl(unsigned long int hostlong)} Converte l'intero a 32 bit \var{hostlong} dal formato della macchina a quello della rete. -\end{prototype} -\begin{prototype}{netinet/in.h} -{unsigned short int htons(unsigned short int hostshort)} + + \funcdecl{unsigned short int htons(unsigned short int hostshort)} Converte l'intero a 16 bit \var{hostshort} dal formato della macchina a quello della rete. -\end{prototype} -\begin{prototype}{netinet/in.h} -{unsigned long int ntonl(unsigned long int netlong)} + + \funcdecl{unsigned long int ntonl(unsigned long int netlong)} Converte l'intero a 32 bit \var{netlong} dal formato della rete a quello della macchina. -\end{prototype} -\begin{prototype}{netinet/in.h} -{unsigned sort int ntons(unsigned short int netshort)} + + \funcdecl{unsigned sort int ntons(unsigned short int netshort)} Converte l'intero a 16 bit \var{netshort} dal formato della rete a quello della macchina. -\end{prototype} + + \bodydesc{Tutte le funzioni restituiscono il valore convertito, e non hanno + errori.} +\end{functions} + I nomi sono assegnati usando la lettera \texttt{n} come mnemonico per indicare l'ordinamento usato sulla rete (da \textit{network order}) e la lettera \texttt{h} come mnemonico per l'ordinamento usato sulla macchina locale (da @@ -652,13 +662,13 @@ mnemonico per indicare la stringa. Dette funzioni sono: memorizzare all'indirizzo puntato da \var{dest}, restituendo 0 in caso di successo e 1 in caso di fallimento (è espressa in questa forma in modo da poterla usare direttamente con il puntatore usato per passare la struttura - degli indirizzi). Se usata con \var{dest} inizializzato a \macro{NULL} + degli indirizzi). Se usata con \var{dest} inizializzato a \val{NULL} effettua la validazione dell'indirizzo. \end{prototype} \begin{prototype}{arpa/inet.h}{in\_addr\_t inet\_addr(const char *strptr)} Restituisce l'indirizzo a 32 bit in network order a partire dalla stringa passata come parametro, in caso di errore restituisce il valore - \macro{INADDR\_NONE} che tipicamente sono trentadue bit a uno; questo + \const{INADDR\_NONE} che tipicamente sono trentadue bit a uno; questo comporta che la stringa \texttt{255.255.255.255}, che pure è un indirizzo valido, non può essere usata con questa funzione; per questo motivo essa è generalmente deprecata in favore della precedente. @@ -691,32 +701,41 @@ e \textit{numeric}. % \end{figure} Entrambe le funzioni accettano l'argomento \param{af} che indica il tipo di -indirizzo e può essere \macro{AF\_INET} o \macro{AF\_INET6}. Se la famiglia -indicata non è valida entrambe le funzioni impostano la variabile \var{errno} -al valore \macro{EAFNOSUPPORT}. I prototipi delle suddette funzioni sono i -seguenti: +indirizzo e può essere soltanto \const{AF\_INET} o \const{AF\_INET6}. I +prototipi delle suddette funzioni sono i seguenti: \begin{prototype}{sys/socket.h} - {int inet\_pton(int af, const char *src, void *addr\_ptr)} Converte la - stringa puntata da \var{src} nell'indirizzo IP da memorizzare - all'indirizzo puntato da \var{addr\_ptr}, la funzione restituisce un - valore positivo in caso di successo, e zero se la stringa non rappresenta un - indirizzo valido, e negativo se \var{af} specifica una famiglia di indirizzi - non valida. +{int inet\_pton(int af, const char *src, void *addr\_ptr)} + + Converte l'indirizzo espresso tramite una stringa nel valore numerico. + + \bodydesc{La funzione restituisce un valore negativo se \var{af} specifica + una famiglia di indirizzi non valida, settando \var{errno} a + \errcode{EAFNOSUPPORT}, un valore nullo se \param{src} non rappresenta un + indirizzo valido, ed un valore positivo in caso di successo.} \end{prototype} + +La funzione converte la stringa indicata tramite \param{src} nel valore +numerico dell'indirizzo IP del tipo specificato da \param{af} che viene +memorizzato all'indirizzo puntato da \var{addr\_ptr}, la funzione restituisce +un valore positivo in caso di successo, e zero se la stringa non rappresenta +un indirizzo valido, e negativo se \var{af} specifica una famiglia di +indirizzi non valida. + + \begin{prototype}{sys/socket.h} {char *inet\_ntop(int af, const void *addr\_ptr, char *dest, size\_t len)} Converte la struttura dell'indirizzo puntata da \var{addr\_ptr} in una stringa che viene copiata nel buffer puntato dall'indirizzo \var{dest}; questo deve essere preallocato dall'utente e la lunghezza deve essere almeno - \macro{INET\_ADDRSTRLEN} in caso di indirizzi IPv4 e - \macro{INET6\_ADDRSTRLEN} per indirizzi IPv6; la lunghezza del buffer deve + \const{INET\_ADDRSTRLEN} in caso di indirizzi IPv4 e + \const{INET6\_ADDRSTRLEN} per indirizzi IPv6; la lunghezza del buffer deve comunque venire specificata attraverso il parametro \var{len}. \bodydesc{La funzione restituisce un puntatore non nullo a \var{dest} in caso di successo e un puntatore nullo in caso di fallimento, in quest'ultimo caso viene impostata la variabile \var{errno} con il valore - \macro{ENOSPC} in caso le dimensioni dell'indirizzo eccedano la lunghezza - specificata da \var{len} o \macro{ENOAFSUPPORT} in caso \var{af} non sia + \errval{ENOSPC} in caso le dimensioni dell'indirizzo eccedano la lunghezza + specificata da \var{len} o \errval{ENOAFSUPPORT} in caso \var{af} non sia una famiglia di indirizzi valida.} \end{prototype} @@ -832,7 +851,7 @@ ssize_t SockWrite(int fd, const void *buf, size_t count) Come si può notare le funzioni ripetono la lettura/scrittura in un ciclo fino all'esaurimento del numero di byte richiesti, in caso di errore viene -controllato se questo è \macro{EINTR} (cioè un'interruzione della system call +controllato se questo è \errcode{EINTR} (cioè un'interruzione della system call dovuta ad un segnale), nel qual caso l'accesso viene ripetuto, altrimenti l'errore viene ritornato interrompendo il ciclo. @@ -925,8 +944,8 @@ comando (effettuata con le apposite routine illustrate in \capref{sec:proc_opt_handling}). Il primo passo (\texttt{\small 14--18}) è creare un \textit{socket} IPv4 -(\macro{AF\_INET}), di tipo TCP \macro{SOCK\_STREAM}. La funzione -\macro{socket} ritorna il descrittore che viene usato per identificare il +(\const{AF\_INET}), di tipo TCP \const{SOCK\_STREAM}. La funzione +\const{socket} ritorna il descrittore 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. @@ -1051,7 +1070,7 @@ 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 \type{sockaddr\_in}, anche in questo caso si usa la porta standard del servizio daytime, ma come indirizzo -IP si il valore predefinito \macro{INET\_ANY} che corrisponde ad un indirizzo +IP si il valore predefinito \const{INET\_ANY} che corrisponde ad un indirizzo generico (\texttt{\small 27--31}). Si effettua poi (\texttt{\small 32--36}) la chiamata alla funzione