Program Interface}) usata nella programmazione di rete. La loro origine
risale al 1983, quando furono introdotti nel BSD 4.2; l'interfaccia è rimasta
sostanzialmente la stessa con piccole modifiche negli anni successivi. Benché
-siano state sviluppate interfacce alternative, originate dai sistemi SYSV,
+siano state sviluppate interfacce alternative, originate dai sistemi SVr4,
come la XTI (\textit{X/Open Transport Interface}) nessuna ha mai raggiunto la
diffusione e la popolarità di quella dei socket (né tantomeno usabilità e
flessibilità).
La scelta di uno stile dipende sia dai meccanismi disponibili, sia dal tipo di
comunicazione che si vuole effettuare. Ad esempio alcuni stili di
-comunicazione considerano i dati come una sequenza continua di bytes, altri
+comunicazione considerano i dati come una sequenza continua di byte, altri
invece li raggruppano in blocchi (i pacchetti).
Un'altro esempio di stile concerne la possibilità che la comunicazione possa o
maneggiare puntatori a strutture relative a tutti gli indirizzi possibili
nelle varie famiglie di protocolli; questo pone il problema di come passare
questi puntatori, il C ANSI risolve questo problema coi i puntatori generici
-(i \type{void *}), ma l'interfaccia dei socket è antecendente alla
+(i \type{void *}), ma l'interfaccia dei socket è antecedente alla
definizione dello standard ANSI, e per questo nel 1982 fu scelto di definire
una struttura generica \type{sockaddr} per gli indirizzi dei socket mostrata
in \nfig:
(tenuta in uno spazio di nomi astratto). Nel primo caso l'indirizzo viene
specificato come una stringa (terminata da uno zero) corrispondente al
pathname del file; nel secondo invece \var{sun\_path} inizia con uno zero
-vengono usati i restanti bytes come stringa (senza terminazione).
+vengono usati i restanti byte come stringa (senza terminazione).
% \subsection{Il passaggio delle strutture}
Il problema connesso all'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 bytes in cui è
+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.
indirizzi valida.
\end{prototype}
-Gli indirizzi vengono cnovertiti da/alle rispettive strutture di indirizzo
+Gli indirizzi vengono convertiti da/alle rispettive strutture di indirizzo
(\var{struct in\_addr} per IPv4, e \var{struct in6\_addr} per IPv6), che
devono essere precedentemente allocate e passate attraverso il puntatore
\var{addr\_ptr}; il parametro \var{dest} di \func{inet\_ntop} non può essere
Per evitare di rendere questa introduzione ai socket puramente teorica
iniziamo con il mostrare un esempio di un client TCP elementare. Prima di
-passare agli esempi del client e del server, esamimeremo una caratteristica
+passare agli esempi del client e del server, esamineremo una caratteristica
delle funzioni di I/O sui socket che ci tornerà utile anche in seguito.
comportamento che avrebbero con i normali files (in particolare questo accade
per i socket di tipo stream).
-Infatti con i socket può accadere che funzioni come \func{read} o
-\func{write} possano restituire in input o scrivere in output un numero di
-bytes minore di quello richiesto. Questo è un comportamento normale e non un
-errore, e succede perché si eccede in lettura o scrittura il limite di buffer
-del kernel.
+Infatti con i socket è comune che funzioni come \func{read} o \func{write}
+possano restituire in input o scrivere in output un numero di byte minore di
+quello richiesto. Come già accennato in \secref{sec:file_read} questo è un
+comportamento normale anche per l'I/O su file, e succede
+perché si eccede in lettura o scrittura il limite di buffer del kernel.
In questo caso tutto quello che il programma chiamante deve fare è di ripetere
-la lettura (o scrittura) per la quantità di bytes rimanenti (lo stesso può
-avvenire scrivendo più di 4096 bytes in una pipe, dato che quello è il limite
+la lettura (o scrittura) per la quantità di byte rimanenti (lo stesso può
+avvenire scrivendo più di 4096 byte in una pipe, dato che quello è il limite
di solito adottato per il buffer di trasmissione del kernel).
\begin{figure}[htb]
return (count - nleft);
}
\end{lstlisting}
- \caption{Funzione \func{SockRead}, legge \var{count} bytes da un socket }
+ \caption{Funzione \func{SockRead}, legge \var{count} byte da un socket }
\label{fig:sock_SockRead_code}
\end{figure}
Per questo motivo seguendo l'esempio di W. R. Stevens si sono definite due
funzioni \func{SockRead} e \func{SockWrite} che eseguono la lettura da un
socket tenendo conto di questa caratteristica, ed in grado di ritornare dopo
-avere letto o scritto esattamente il numero di bytes specificato; il sorgente
+avere letto o scritto esattamente il numero di byte specificato; il sorgente
è riportato in \curfig\ e \nfig\ ed è disponibile fra i sorgenti allegati alla
guida nei files \file{SockRead.c} e \file{SockWrite.c}.
return (count);
}
\end{lstlisting}
- \caption{Funzione \func{SockWrite}, scrive \var{count} bytes su un socket }
+ \caption{Funzione \func{SockWrite}, scrive \var{count} byte su un socket }
\label{fig:sock_SockWrite_code}
\end{figure}
Come si può notare le funzioni ripetono la lettura/scrittura in un ciclo fino
-all'esaurimento del numero di bytes richiesti, in caso di errore viene
+all'esaurimento del numero di byte richiesti, in caso di errore viene
controllato se questo è \macro{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.
-Nel caso della lettura, se il numero di bytes letti è zero, significa che si è
+Nel caso della lettura, se il numero di byte letti è zero, significa che si è
arrivati alla fine del file e pertanto si ritorna senza aver concluso la
-lettura di tutti i bytes richiesti.
+lettura di tutti i byte richiesti.
\begin{lstlisting}{}
#include <sys/types.h> /* predefined types */
#include <unistd.h> /* include unix standard library */
-#include <arpa/inet.h> /* IP addresses conversion utiliites */
+#include <arpa/inet.h> /* IP addresses conversion utilities */
#include <sys/socket.h> /* socket library */
#include <stdio.h> /* include standard I/O library */
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
+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
\begin{lstlisting}{}
#include <sys/types.h> /* predefined types */
#include <unistd.h> /* include unix standard library */
-#include <arpa/inet.h> /* IP addresses conversion utiliites */
+#include <arpa/inet.h> /* IP addresses conversion utilities */
#include <sys/socket.h> /* socket library */
#include <stdio.h> /* include standard I/O library */
#include <time.h>