From bf66d833fbcd76d007d1d748217b2cea773d4a39 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Thu, 19 Jun 2003 11:43:13 +0000 Subject: [PATCH] Altro lavoro sul server echo, e sulle condizioni particolari --- elemtcp.tex | 50 ++++++++++++++++++++++++++++++++++---------- html/index.html | 4 ++-- img/endianess.dia | Bin 1400 -> 1514 bytes socket.tex | 27 ++++++++++-------------- sources/TCP_echod.c | 23 ++++++++++++++------ 5 files changed, 69 insertions(+), 35 deletions(-) diff --git a/elemtcp.tex b/elemtcp.tex index 585f605..cfc4c85 100644 --- a/elemtcp.tex +++ b/elemtcp.tex @@ -1328,7 +1328,7 @@ Il primo passo (\texttt{\small 14--18}) \func{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 (\texttt{\small 16}) con la funzione \func{perror} e si esce -(\texttt{\small 16}) con un codice di errore. +(\texttt{\small 17}) con un codice di errore. Il passo seguente (\texttt{\small 19--27}) è quello di costruire un'apposita struttura \struct{sockaddr\_in} in cui sarà inserito l'indirizzo del server ed @@ -2114,16 +2114,20 @@ la rete gestire tutta una serie di situazioni critiche che non esistono per i processi locali. -Come accennato in \secref{sec:TCP_func_accept} la funzione \func{accept} -riporta tutti gli eventuali errori di rete pendenti su una connessione sul -\textit{connected socket}; questo significa che, oltre al caso di interruzione -da parte di un segnale, esistono altri errori non fatali che necessitano -semplicemente la ripetizione della chiamata senza che si debba uscire dal -programma. Un esempio possibile è quello mostrato in -\figref{fig:TCP_early_abort}, in cui la connessione viene abortita dal client -con l'invio di un segmento RST prima che sia stata chiamata la funzione -\func{accept}. - +La prima situazione critica è quella della terminazione precoce, per via di un +qualche errore di rete, della connessione effettuata da un client. Come +accennato in \secref{sec:TCP_func_accept} la funzione \func{accept} riporta +tutti gli eventuali errori di rete pendenti su una connessione sul +\textit{connected socket}. + +Questo significa che, oltre alla interruzione da parte di un segnale, che +abbiamo trattato in \secref{sec:TCP_child_hand} nel caso particolare di +\const{SIGCHLD}, si possono avere altri errori non fatali all'uscita di +\func{accept}, che necessitano semplicemente la ripetizione della chiamata +senza che si debba uscire dal programma. Uno scenario tipo è quello mostrato +in \figref{fig:TCP_early_abort}, in cui la connessione viene abortita sul lato +client con l'invio di un segmento RST, prima che nel server sia stata chiamata +la funzione \func{accept}. \begin{figure}[htb] \centering @@ -2132,6 +2136,30 @@ con l'invio di un segmento RST prima che sia stata chiamata la funzione \label{fig:TCP_early_abort} \end{figure} +Benché questo non sia un fatto comune un evento simile può essere osservato +con dei server molto occupati. In tal caso, in una struttura del server simile +a quella del nostro esempio, in cui la gestione delle singole connessioni è +demandata a processi figli, può accadere che il three way handshake venga +completato e la relativa connessione abortita subito dopo, prima che il padre, +per via del carico della macchina abbia fatto in tempo a rieseguire la +chiamata \func{accept}. In questo caso si ha una situazione analoga a quella +illustrata in \figref{fig:TCP_early_abort}, la connessione viene stabilita, ma +subito dopo si ha una condizione + + +che, come nell'esempio in figura, ritornerebbe +immediatamente con un errore relativo alla connessione abortita. + + +Si tenga presente che questo tipo di terminazione non è riproducibile +terminando il client prima della chiamata ad \func{accept}; in tal caso +infatti il socket associato alla connessione viene semplicemente chiuso, +attraverso la sequenza vista in \secref{sec:TCP_conn_term}, per cui la +\func{accept} ritornerà senza errori, e si avrà semplicemente un end-of-file +al primo accesso al socket. + +In questo caso + %%% Local Variables: diff --git a/html/index.html b/html/index.html index 6527164..f39abd8 100644 --- a/html/index.html +++ b/html/index.html @@ -115,7 +115,7 @@ attenzione particolare alle GNU libc, che sono la versione più usata delle librerie del C, senza dimenticare, ove note, di citare le differenze con possibili alternative come le libc5 o - le ulibc. + le uclibc.

L'obiettivo resta comunque quello di riuscire a produrre una @@ -144,7 +144,7 @@ all'opera di Mirko Maischberger abbiamo anche una bellissima versione HTML, accessibile nella sezione On Line , finalemente + face="sans-serif"> online , finalmente all'altezza della versione stampabile.

diff --git a/img/endianess.dia b/img/endianess.dia index 2d88d94b855381a1b0c18d1b3f60f4b55db74019..8b309a835295cffa97e3b64ef0bfd5366e57120b 100644 GIT binary patch literal 1514 zcmVGaXLxbK6R!K+kN)PMz*z! z!2@z^zwB>c2?%jwND)?+#yB%|8p|AxbiVWHT!gPbZR-;#!@<2Gor7US)~4 zt^Z^=4sjZ4AGNz=t3Q!5r)CkCdVR7*vKb$2gRLmic!JUEkorlstOiq17E>07fujOb)};eH!~x|4ge-wB zzr@pFE;veX4*(Ix3_oqU%q}bVTY}Mmc);@75~*{cuAujzbB3} zUCY=`xISO?;?wuZI;GqjT2A+PtR8R6JSwY+(9Ha&trWg_&*LSj){4aIWjUEHTf?#N zx8&jPwckizgFobCnscfne82{-;8eF45BLKwS69LX1_OHu8=fTWZCTj!EgC3^Bs>vC zT=D3E3k-U|`t997KrUsm_YLy;XxZr$Ew^9wU&qTHKvleqfTuEEZm;G!VphzZt~_@l zH4(G0JL23KaDk`??!5mp816(viHqyG)9b>W2q>&IAn{sqrw<&3+=;-s+RztwB6;rg z)uda(?k?v}B;eFXlJ)i5V93)SN_JIGo_-hd^woq21$p|wuE;YGugb_%Ld`RIDkjfB zo;(9J)XDLbr|bc+dtlDNlw&3Ab&9+RrTbf)+tl>80syQ27Bod`OJRdcO3O2ADh3to z1S&OUpaND!8K{Jnx;l`go@Zbw2A0(YSc-Dw0$4?kTmnm7k}Rp`8Ca@Y^0qv(l+_pm zP*fQ?s%*EXI^$qcWl6i8WYFhyp;2EI*kP3|mo%y_U6$1IOrxr4)a^o}o~jMHXmoQ_ zIX!i{2a`5Sn(ZVHbU^8jjmLo*sOol?g+{+9JGuene{<-Y5-GGo=N!>#V z(v2}&)q`I)a77}Eu6T?u5?Q;wA>w$<j2iE9Kav=S29?rlLG|G;4kpL2Y(((_X~e}Q1CyYc8*bf3)=Iq QNW1y)AGHC}V0BUe06^jF5dZ)H literal 1400 zcmV-;1&8_{iwFP!000001MOVPZreB%-S;a51?VcJ-mf}Nk)+M4z$~V-HfW2MIh84c zqT_fo-#(VoZ{$ z{?CuwPoe(h^20@p;b;DnP`K9k9V8cjP4yLHo6m-^+wDNQ&mqewNbwfr$oLPYDKz+p z4E^%y-7#dayZ{-ac)n#wBXEtT`W!BPCN$fUxVmGJr5V-kU^>;$mc>gqE-#E{_coi_ zzzw3cmGvgeF>ho0&5O2|_lftaDd#ODxjega&&o$u7dkzktszY?sZ3D>)3O^j2yNT$ z+KagoE2$DIREZUw&o&ul6k=9cnrB&xASsP8xS|z#8OxfySi&@K zbi;TCr*2P4D2`iz_@wFOT{|4J)$IPDb0+9K)TN32F(&SCj^`<={lJ7tj`4$qeJ2aO z#&?Tjl(&uW)5e!~uBuj}#r4PL-}z-U(pw7mh*rj~AE`~N#-u`f`Ppp#FIuq5>%SQ! zF{H8fNxRPO^+$5%)Qsb){+HR(BW{H+uZR9_vU;>V;Gg?l=S*0c&uiQ)xHn0P9t?Sb zckY2G@FoGUZSUOY>)-2Y8l`AGTV#~f1l-rj!cqb8LjnMDR#pfnE7q`1!p=OM(HPMd zcT8Y*9-n-b?PdqtU?+++9%1xrNc}+ftN~M&ET%Z|pSwT_s)Q*A1RPEiiwlsTfSBoZ z9yTVr)XV@+nhplL*w0_=_Eq<^sb=0^UEh5Dc57Na_Wxx@9v&-x)s}FL(>;GCB)P8T zY%kV7ANumsH`$hAz9c$!w*|1BNm<2o7SgOirkTa7s};V3CuEK4u|j0Ku2xN-{o&X( zU`ww7PJgzN6~F=Sa@@maOcg}(Qv24jJ-$h^!spU02JmO0`XpPX9!${+!=sV=3yxA z4CJ{pR1jJ20Oou%S=r;6Ga55*TGF*H&TVRHT@kSAT9;*tGMB<)mz0+$ z)>I5Cs~4!$q=8CUm1&>~R_gLVl760mr5IRtA7CkpkxO8eF>(bgbwRSEpC@3cF3&si z$WoSLj6j)XcVA7KTkBOnnt}oH0rC` zpnVZe2voVE)_n?_UzbJwksoKWq$@T)2d1a0Vj~ib9t8ebdy)*#@QE-P84D(r_MXC#iWhJ}c*fazM|gkLC;JyN&^<~SMI z0+5@^_lf_okJ5=$=^RlVD0I#+<$=+h=#!eX_o;HCK0sG=f}jl6i$HOxGX$eKfF(I? zZyW62F+ok=P>?Q%IjX+;Xdl9}m-6w*O8P^|$Q@`@?;AnwFiHuLnV$=I; ziYXuM_QXc_ateuOkkV{-02W8u#4JT5Y4pdHx7F4)=QVOHwsdu^5XVYD%C&YBI^m=C z9#D3VMr_;T5!-FFEM52GK($3)SqFeOssQ)9v^M99c`Qd-=Fk@PQ GMgRaWcD&I5 diff --git a/socket.tex b/socket.tex index 4adb5c7..3315352 100644 --- a/socket.tex +++ b/socket.tex @@ -732,12 +732,11 @@ cos \label{sec:sock_addr_func} In questa sezione tratteremo delle varie funzioni usate per manipolare gli -indirizzi, limitandoci però agli indirizzi internet. - -Come accennato gli indirizzi e i numeri di porta usati nella rete devono -essere forniti in formato opportuno (il \textit{network order}). Per capire -cosa significa tutto ciò occorre introdurre un concetto generale che tornerà -utile anche in seguito. +indirizzi, limitandoci però agli indirizzi internet. Come accennato gli +indirizzi e i numeri di porta usati nella rete devono essere forniti in +formato opportuno (il \textit{network order}). Per capire cosa significa tutto +ciò occorre introdurre un concetto generale che tornerà utile anche in +seguito. \subsection{La \textit{endianess}\index{endianess}} @@ -762,7 +761,7 @@ parte dal bit meno significativo \begin{figure}[htb] \centering - \includegraphics[height=5cm]{img/endianess} + \includegraphics[height=3cm]{img/endianess} \caption{Schema della disposizione dei dati in memoria a seconda della \textit{endianess}\index{endianess}.} \label{fig:sock_endianess} @@ -788,15 +787,11 @@ questi cambiamenti. Il problema connesso all'endianess\index{endianess} è che quando si passano dei dati da un tipo di architettura all'altra i dati vengono interpretati in maniera diversa, e ad esempio nel caso dell'intero a 16 bit ci si ritroverà -con i due byte in cui è suddiviso scambiati di posto, e ne sarà quindi -invertito l'ordine di lettura per cui, per riavere il valore originale, -dovranno essere rovesciati. - -Per questo motivo si usano delle 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 \funcd{htonl}, \funcd{htons}, \funcd{ntohl} e \funcd{ntohs} ed i -rispettivi prototipi sono: +con i due byte in cui è suddiviso scambiati di posto. Per questo motivo si +usano delle 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 \funcd{htonl}, +\funcd{htons}, \funcd{ntohl} e \funcd{ntohs} ed i rispettivi prototipi sono: \begin{functions} \headdecl{netinet/in.h} \funcdecl{unsigned long int htonl(unsigned long int hostlong)} diff --git a/sources/TCP_echod.c b/sources/TCP_echod.c index 08d926f..35de97c 100644 --- a/sources/TCP_echod.c +++ b/sources/TCP_echod.c @@ -26,7 +26,7 @@ * * Usage: echod -h give all info * - * $Id: TCP_echod.c,v 1.4 2003/06/18 21:19:24 piccardi Exp $ + * $Id: TCP_echod.c,v 1.5 2003/06/19 11:43:13 piccardi Exp $ * ****************************************************************/ /* @@ -60,7 +60,9 @@ int main(int argc, char *argv[]) int list_fd, conn_fd; int waiting; pid_t pid; - struct sockaddr_in serv_add; + struct sockaddr_in serv_add, cli_add; + socklen_t len; + char debug[MAXLINE], ipaddr[20]; /* * Input section: decode parameters passed in the calling * Use getopt function @@ -142,12 +144,21 @@ int main(int argc, char *argv[]) /* handle echo to client */ while (1) { /* accept connection */ - while (((conn_fd = accept(list_fd, NULL, NULL)) < 0) - && (errno == EINTR)); + while (((conn_fd = accept(list_fd, (struct sockaddr *)&cli_add, &len)) + < 0) && (errno == EINTR)); if ( conn_fd < 0) { PrintErr("accept error"); exit(1); } + if (debugging) { + inet_ntop(AF_INET, &cli_add.sin_addr, ipaddr, sizeof(ipaddr)); + snprintf(debug, MAXLINE, "Accepted connection form %s\n", ipaddr); + if (demonize) { + syslog(LOG_DEBUG, debug); + } else { + printf("%s", debug); + } + } /* fork to handle connection */ if ( (pid = fork()) < 0 ){ PrintErr("fork error"); @@ -190,7 +201,7 @@ void ServEcho(int sockfd) { if (debugging) { buffer[nread] = 0; snprintf(debug, MAXLINE+20, "Letti %d byte, %s", nread, buffer); - if (demonize) { /* go daemon */ + if (demonize) { /* daemon mode */ syslog(LOG_DEBUG, debug); } else { printf("%s", debug); @@ -203,7 +214,7 @@ void ServEcho(int sockfd) { * routine to print error on stout or syslog */ void PrintErr(char * error) { - if (demonize) { /* go daemon */ + if (demonize) { /* daemon mode */ syslog(LOG_ERR, error); } else { perror(error); -- 2.30.2