Sentite parlare di "socket" continuamente, e forse vi state chiedendo cosa siano esattamente. Beh, sono questo: un modo di parlare ad altri programmi usando descrittori di file standard di Unix.
Cosa?
Ok--potreste aver sentito qualche Unix hacker dire, "Amico(!), tutto in Unix è un file!" Quello a cui quella persona poteva riferirsi è il fatto che quando un programma Unix effettua un qualche tipo di I/O, lo fa leggendo o scrivendo in un descrittore di file . un descrittore di file è semplicemente un intero associato con un file aperto. Ma (e qui sta il punto), quel file può essereuna connessione di rete, un FIFO, un pipe, un terminale, un vero file su-disco, o praticamente qualsiasi altra cosa. Tutto in Unix è un file! Dunque quando vorrete comunicare con un altro programma attraverso Internet dovrete farlo attraverso un descrittore di file , farete meglio a convincervi.
"Dove prendo questo descrittore di file per le comunicazioni di rete, Mr. Smarty-Pants? (!) " probabilmente è l'ultima domanda nella vostra testa adesso, ma vi risponderò comunque: effettuando una chiamata alla routine di sistema socket() . Essa restituisce il descrittore del socket, e voi comunicherete attraverso di esso usando le funzioni specializzate per i socket send() e recv() (man send, man recv).
"Ma, hey!" potreste stare esclamando adesso. "Se è un descrittore di file, perche, per Nettuno, non posso usare le normali funzioni read() e write() per comunicare attraverso il socket?" La risposta breve è, "Potete!" La risposta lunga è, "Potete, ma send() e recv() offrono un maggiore controllo sulla trasmissione dei vostri dati."
Cos'altro? Che ne dite di questo: ci sono quattro tipi di socket. Ci sono indirizzi Internet DARPA (Internet Socket), nomi di percorso in un nodo locale (Unix Socket), indirizzi CCITT X.25 (X.25 Socket che potete tranquillamente ignorare), E probabilmente molti altri dipendentemente da quale Unix state usando. Questo documento parla dei primi: Internet Socket.
Cos'è questa? Ci sono due tipi di Internet socket? Si. Beh, no. Sto mentendo. Ce ne sono di più, ma non volevo spaventarvi. Vi perlerò solo di due tipi qui. Esclusa questa frase, nella quale vi dirò che i "Raw Socket" (socket grezzi) sono anche più potenti e dovreste dargli un'occhiata.
Tutto bene, allora. Quali sono i due tipi? uno è quello degli "Stream Socket" ; l'altro quello dei "Datagram Socket", a cui si potrà riferirsi d'ora in poi come "SOCK_STREAM" e "SOCK_DGRAM", rispettivamente. I socket Datagram sono talvolta chiamati "socket senza connessione". (anche se su di loro si può chiamare connect()se davvero lo desiderate. Guardate connect(), qui sotto.)
Gli Stream socket sono flussi (stream) di comunicazione bidirezionali e affidabili. Se mandate in output due oggetti nel socket nell'ordine "1, 2", essi arriveranno nell'ordine "1, 2" dal lato opposto. Essi saranno anche liberi da ogni tipo di errore. Ogni errore che incontrate è frutto della vostra mente bacata, e non verrà discusso qui.
Da cosa sono usati gli stream socket? Bene, avrete sentito parlare dell'applicazione telnet, vero? Usa gli stream socket. Tutti i caratteri che digitate hanno bisogno di arrivare nello stesso ordine in cui li digitate, giusto? Inoltre, i web browser usano il protocollo HTTP che usa gli stream socket per ottenere le pagine. Infatti, se avviate una sessione telnet verso un sito web sulla porta 80, e digitate "GET /", vi restituirà l'HTML!
Come fanno gli stream socket a raggiungere questo alto livello di qualità di trasmissione dei dati? Essi usano un protocollo chiamato "Transmission Control Protocol" (protocollo con controllo della trasmissione), anche noto come "TCP" (vedere RFC-793 per informazioni estremamente dettagliate sul TCP.) TCP assicura che i dati arrivino in sequenza e senza errori. Potreste aver sentito già prima la parola "TCP" come la prima metà di "TCP/IP" dove "IP" sta per "Internet Protocol" (vedere RFC-791.) IP ha a che fare principalmente con l'indirizzamento su Internet e in genere non è responsabile per l'integrità dei dati.
Fico. E i Datagram socket? Perchè vengono detti senza connessione? Con cosa abbiamo a che fare qui, ad ogni modo? Perchè sono inaffidabili? Beh, questi sono alcuni fatti: se inviate un datagramma (pacchetto), esso può arivare. Può arrivare fuori ordine. Se arriva, i dati nel pacchetto saranno senza errori.
I Datagram socket usano comunque IP per l'indirizzamento, ma non usano TCP; essi usano l' "User Datagram Protocol", o "UDP" (vedere RFC-768.)
Perchè sono senza connessione? Beh, sostanzialmente, è perchè non dovete mantenere una connessione aperta come fate con gli stream socket. Dovete semplicemente costruire un pacchetto, ci sbattete sopra un'intestazione IP con sopra le informazioni di destinazione, e lo sparate fuori. Non è richiesta alcuna connessione. In genere vengono usati per trasferimento di informazioni pacchetto-a-pacchetto. Esempi di applicazioni: tftp, bootp, etc.
"Basta!" potreste gridare. "come fanno questi programmi a funzionare se i datagrammi vanno persi?!" Beh, mio amico umano, ognuno ha il suo protocollo sopra all'UDP. Ad esempio, il protocollo tftp dice che per ogni pacchetto che viene inviato, il ricevente deve rimandare indietro un pacchetto che dica, "Preso!" (un pacchetto "ACK" .) Se il mittente del pacchetto originale non ottiene una replica in, diciamo, 5 secondi, ritrasmetterà il pacchetto finchè alla fine non riceverà un ACK. questa procedura di conferma è molto importante nell'imlementazione di applicazioni SOCK_DGRAM.
Poichè ho appena menzionato la struttura a livelli dei protocolli, è tempo di parlare di come le reti funzionano davvero, e di m,ostrare alcuni esempi di come vengano costruiti i pacchetti SOCK_DGRAM. In pratica, potreste probabilmente saltare questa sessione. E' una buona base, comunque.
Figure 1. Incapsulamento dei Dati .
[Diagramma dell'Incapsulamento dei Protocolli]Hey, ragazzi, è ora di imparare l'Incapsulamento dei Dati! Questo è molto importante. E' così importante che potrete impararlo solo se seguirete il corso sulle reti qui nell'università di Chico ;-). In sostanza, esso va così: un pacchetto nasce, il pacchetto viene avvolto ("incapsulato") in una intestazione (e qualche volta un footer(!) ) dal primo protocollo (ad esempio, il protocollo TFTP ), poi il tutto (intestazione TFTP inclusa) viene incapsulato ancora dal prossimo protocollo (diciamo, UDP), poi ancora dal prossimo(IP), poi ancora dal protocollo finale sul livello dell'hardware ,fisico ,(diciamo, Ethernet).
Quando un altro computer riceve il pacchetto, l'hardware toglie l'intestzione Ethernet, il kernel toglie le intestazioni IP e UDP , il programma TFTP toglie l'intestazione TFTP, e finalmente, ha i dati.
Ora posso finalmente parlare del famigerato Modello di Rete a Livelli. Questo Modello Di Rete descrive un sistema di funzionalità di rete che ha molti vantaggi rispetto da altri modelli. Ad esempio, potete scrivere programmi con i socket che sono esattamente gli stessi senza curarsi di come i dati siano trasmessi fisicamente (in maniera seriale, Ethernet, AUI, o altro) poichè i programmi ai livelli più bassi gestiranno tutto per te. L'hardware di rete effettivo e la topologia della rete sono trasparenti al programmatore di socket.
Senza ulteriori attese, vi mostrerò i livelli duitutto il modello. Ricordatevi questo per il vostro esame del corso di Reti:
Applicazione
Presentazione
Sessione
Trasporto
Rete
Data Link
Fisico
Il livello Fisico è l'hardware (seriale, Ethernet, etc.). Il livello Applicazione è più lontano dal livello fisico di quanto potete immaginare --è il punto dove gli utenti interagiscono con la Rete.
Ora , questo modello è talmente generale che potreste usarlo come guida alla riparazione di un automobile se voleste. Un modello a livelli più consistente per Unix potrebbe essere:
Livello Applicazione (telnet, ftp, etc.)
Livello Trasporto Host-a-Host (TCP, UDP)
Livello Internet (IP e indirizzamento)
Livello di Accesso alla Rete (Ethernet, ATM, o altro)
A questo punto, probabilmente potete vedere come questi livelli corrispondando alle incapsulazioni del dato originale.
vedete quanto lavoro c'è nel costruire un singolo pacchetto? (!)Jeez! E dovete digitare nel pacchetto le intestazioni da soli usando "cat"! Sto scherzando. tutto quello che dovete fare per gli stream socket è usare send() per mandar fuori i dati. Tutto quel che dovete per i datagram socket è incapsulare il pacchetto nel metodo di vostra scelta e usare sendto() per mandarlo fuori. il kernel gstisce il Livello di Trasporto e il Livello Internet per voi e l'hardware gestisce il Livello di accesso alla Rete. Ah, la tecnologia moderna.
Qui finisce la nostra breve scorribanda nella teoria delle Reti. Oh si, dimenticavo di dirvi tutto quello che volevo dirvi a proposito dell'indirizzamento (routing) : niente! Esattamente, non ve ne parlerò affatto. Il router toglie l'intestazione dal pacchetto IP, consulta la sua tabella di indirizzamento (routing table), blah blah blah. Date un'occhiata alla IP RFC se davvero davvero ve ne importa. Se anche non ne saprete mai nulla, bene, sopravviverete.