X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=tcpsock.tex;h=d92e6d882173e8008cd3553d856579df4c59cfc0;hp=695603e744b7bb9b3f4dc81aca2098b5acd431d6;hb=922de35645e21550b70e2e5fe5ced103a0d2e0b4;hpb=4cbeb0e4fa1d31da798c8e68108eb6785586ab34 diff --git a/tcpsock.tex b/tcpsock.tex index 695603e..d92e6d8 100644 --- a/tcpsock.tex +++ b/tcpsock.tex @@ -731,7 +731,7 @@ Si noti che si è usato \func{htonl} per assegnare il valore \const{INADDR\_ANY}, anche se, essendo questo nullo, il riordinamento è inutile. Si tenga presente comunque che tutte le costanti \val{INADDR\_} (riportate in tab.~\ref{tab:TCP_ipv4_addr}) sono definite secondo -\itindex{endianess} l'\textit{endianess} della macchina, ed anche se esse +\itindex{endianness} l'\textit{endianness} della macchina, ed anche se esse possono essere invarianti rispetto all'ordinamento dei bit, è comunque buona norma usare sempre la funzione \func{htonl}. @@ -1537,8 +1537,8 @@ quello in questione, non è opportuno bloccare un server nel servizio di un client per volta; per questo si ricorre alle capacità di multitasking del sistema. -Come accennato anche in sez.~\ref{sec:proc_gen} una delle modalità più comuni -di funzionamento da parte dei server è quella di usare la funzione \func{fork} +Come spiegato in sez.~\ref{sec:proc_fork} una delle modalità più comuni di +funzionamento da parte dei server è quella di usare la funzione \func{fork} per creare, ad ogni richiesta da parte di un client, un processo figlio che si incarichi della gestione della comunicazione. Si è allora riscritto il server \textit{daytime} dell'esempio precedente in forma concorrente, inserendo anche @@ -2010,7 +2010,7 @@ quando affronteremo il comportamento in caso di conclusioni anomale: restituendo un puntatore nullo che causa l'uscita dal ciclo di \code{while}, così la funzione \code{ClientEcho} ritorna. \item al ritorno di \code{ClientEcho} ritorna anche la funzione \code{main}, e - come parte del processo terminazione tutti i file descriptor vengono chiusi + come parte del processo di terminazione tutti i file descriptor vengono chiusi (si ricordi quanto detto in sez.~\ref{sec:proc_term_conclusion}); questo causa la chiusura del socket di comunicazione; il client allora invierà un FIN al server a cui questo risponderà con un ACK. A questo punto il client @@ -2038,19 +2038,19 @@ esaminato in sez.~\ref{sec:proc_termination}). In questo caso avremo l'invio del segnale \signal{SIGCHLD} al padre, ma dato che non si è installato un gestore e che l'azione predefinita per questo segnale è quella di essere ignorato, non avendo predisposto la ricezione dello stato di terminazione, -otterremo che il processo figlio entrerà nello stato di \index{zombie} zombie -(si riveda quanto illustrato in sez.~\ref{sec:sig_sigchld}), come risulterà -ripetendo il comando \cmd{ps}: +otterremo che il processo figlio entrerà nello stato di \itindex{zombie} +\textit{zombie} (si riveda quanto illustrato in sez.~\ref{sec:sig_sigchld}), +come risulterà ripetendo il comando \cmd{ps}: \begin{verbatim} 2356 pts/0 S 0:00 ./echod 2359 pts/0 Z 0:00 [echod ] \end{verbatim} -Dato che non è il caso di lasciare processi \index{zombie} zombie, occorrerà -ricevere opportunamente lo stato di terminazione del processo (si veda -sez.~\ref{sec:proc_wait}), cosa che faremo utilizzando \signal{SIGCHLD} secondo -quanto illustrato in sez.~\ref{sec:sig_sigchld}. Una prima modifica al nostro -server è pertanto quella di inserire la gestione della terminazione dei +Dato che non è il caso di lasciare processi \itindex{zombie} \textit{zombie}, +occorrerà ricevere opportunamente lo stato di terminazione del processo (si +veda sez.~\ref{sec:proc_wait}), cosa che faremo utilizzando \signal{SIGCHLD} +secondo quanto illustrato in sez.~\ref{sec:sig_sigchld}. Una prima modifica al +nostro server è pertanto quella di inserire la gestione della terminazione dei processi figli attraverso l'uso di un gestore. Per questo useremo la funzione \code{Signal} (che abbiamo illustrato in fig.~\ref{fig:sig_Signal_code}), per installare il gestore che riceve i segnali dei processi figli terminati già @@ -2069,13 +2069,13 @@ di \errcode{EINTR}. Vediamo allora cosa comporta tutto questo nel nostro caso: quando si chiude il client, il processo figlio che gestisce la connessione terminerà, ed il padre, -per evitare la creazione di zombie, riceverà il segnale \signal{SIGCHLD} -eseguendo il relativo gestore. Al ritorno del gestore però l'esecuzione nel -padre ripartirà subito con il ritorno della funzione \func{accept} (a meno di -un caso fortuito in cui il segnale arriva durante l'esecuzione del programma -in risposta ad una connessione) con un errore di \errcode{EINTR}. Non avendo -previsto questa eventualità il programma considera questo un errore fatale -terminando a sua volta con un messaggio del tipo: +per evitare la creazione di \itindex{zombie} \textit{zombie}, riceverà il +segnale \signal{SIGCHLD} eseguendo il relativo gestore. Al ritorno del gestore +però l'esecuzione nel padre ripartirà subito con il ritorno della funzione +\func{accept} (a meno di un caso fortuito in cui il segnale arriva durante +l'esecuzione del programma in risposta ad una connessione) con un errore di +\errcode{EINTR}. Non avendo previsto questa eventualità il programma considera +questo un errore fatale terminando a sua volta con un messaggio del tipo: \begin{verbatim} [root@gont sources]# ./echod -i accept error: Interrupted system call @@ -3073,23 +3073,23 @@ vuole operare e come secondo argomento un valore intero \param{how} che indica la modalità di chiusura del socket, quest'ultima può prendere soltanto tre valori: \begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}} -\item[\macro{SHUT\_RD}] chiude il lato in lettura del socket, non sarà più +\item[\const{SHUT\_RD}] chiude il lato in lettura del socket, non sarà più possibile leggere dati da esso, tutti gli eventuali dati trasmessi dall'altro capo del socket saranno automaticamente scartati dal kernel, che, in caso di socket TCP, provvederà comunque ad inviare i relativi segmenti di ACK. -\item[\macro{SHUT\_WR}] chiude il lato in scrittura del socket, non sarà più +\item[\const{SHUT\_WR}] chiude il lato in scrittura del socket, non sarà più possibile scrivere dati su di esso. Nel caso di socket TCP la chiamata causa l'emissione di un segmento FIN, secondo la procedura chiamata \itindex{half-close} \textit{half-close}. Tutti i dati presenti nel buffer di scrittura prima della chiamata saranno inviati, seguiti dalla sequenza di chiusura illustrata in sez.~\ref{sec:TCP_conn_term}. -\item[\macro{SHUT\_RDWR}] chiude sia il lato in lettura che quello in +\item[\const{SHUT\_RDWR}] chiude sia il lato in lettura che quello in scrittura del socket. È equivalente alla chiamata in sequenza con - \macro{SHUT\_RD} e \macro{SHUT\_WR}. + \const{SHUT\_RD} e \const{SHUT\_WR}. \end{basedescript} -Ci si può chiedere quale sia l'utilità di avere introdotto \macro{SHUT\_RDWR} +Ci si può chiedere quale sia l'utilità di avere introdotto \const{SHUT\_RDWR} quando questa sembra rendere \funcd{shutdown} del tutto equivalente ad una \func{close}. In realtà non è così, esiste infatti un'altra differenza con \func{close}, più sottile. Finora infatti non ci siamo presi la briga di @@ -3116,7 +3116,7 @@ dato che restano altri riferimenti attivi, uno al socket connesso nel figlio ed uno a quello in ascolto nel padre. Questo non avviene affatto se si usa \func{shutdown} con argomento -\macro{SHUT\_RDWR} al posto di \func{close}; in questo caso infatti la +\const{SHUT\_RDWR} al posto di \func{close}; in questo caso infatti la chiusura del socket viene effettuata immediatamente, indipendentemente dalla presenza di altri riferimenti attivi, e pertanto sarà efficace anche per tutti gli altri file descriptor con cui, nello stesso o in altri processi, si fa @@ -3601,7 +3601,7 @@ Da fare. % LocalWords: lsof SOCK sys int sockfd const struct sockaddr serv addr socklen % LocalWords: addrlen errno EBADF descriptor EINVAL ENOTSOCK EACCES EADDRINUSE % LocalWords: EADDRNOTAVAIL EFAULT ENOTDIR ENOENT ENOMEM ELOOP ENOSR EROFS RPC -% LocalWords: portmapper htonl tab endianess BROADCAST broadcast any extern fd +% LocalWords: portmapper htonl tab endianness BROADCAST broadcast any extern fd % LocalWords: ADRR INIT DGRAM SEQPACKET servaddr ECONNREFUSED ETIMEDOUT EAGAIN % LocalWords: ENETUNREACH EINPROGRESS EALREADY EAFNOSUPPORT EPERM EISCONN proc % LocalWords: sysctl filesystem syn retries reset ICMP backlog EOPNOTSUPP RECV