I socket sono descrittori di file con abilità speciali. Sebbene ogni socket usi in qualche modo una porta, non sono la stessa cosa.
Un socket è identificato da un indirizzo locale + porta e un indirizzo remoto + porta. Ciò significa che la stessa porta locale può far parte di più socket se la parte remota è diversa.
Un server TCP (come un processo del server Web) ascolta su una porta locale. Qui, l'indirizzo locale controlla solo chi può connettersi a questa porta: tutti, o solo le connessioni da localhost. L'indirizzo remoto di un socket di ascolto è zero, il che significa nessuna connessione. Qui ho avviato un python3 -m http.server
sulla porta localhost 7001:
tcp 127.0.0.1:7001 0.0.0.0:* LISTEN 32143/python3
Quando mi collego a quel server web tramite il mio browser web, vediamo due socket aggiuntivi:
tcp 127.0.0.1:7001 0.0.0.0:* LISTEN 32143/python3
tcp 127.0.0.1:50204 127.0.0.1:7001 ESTABLISHED 1658/firefox
tcp 127.0.0.1:7001 127.0.0.1:50204 ESTABLISHED 32143/python3
(dati ottenuti tramite netstat
e modificati per chiarezza)
Il browser Firefox ha creato un socket su connect()
sul server. Firefox usa la porta 50204 in questo caso, quindi il suo socket è identificato come local 127.0.0.1:50204 remote 127.0.0.1:7001
. Quando il server accept()
ed ha effettuato la connessione, questa connessione ha il suo socket, che è sostanzialmente il contrario del socket del client: local 127.0.0.1:7001 remote 127.0.0.1:50204
. La porta locale è la stessa che il server sta ascoltando.
Il socket client e il socket di connessione al server si rispecchiano sempre a vicenda, anche se in realtà il server vede spesso una porta IP + del client diversa a causa della traduzione degli indirizzi di rete (NAT).
Perché il server può utilizzare la stessa porta per tutte le connessioni? Bene, ogni pacchetto TCP / IP contiene la porta IP + del mittente e del destinatario. Quando il sistema operativo del server riceve una richiesta di connessione da un client per una determinata porta, la connessione viene solitamente rifiutata a meno che un processo del server non sia in ascolto su quella porta. In tal caso, il processo del server può accettare la connessione e otteniamo un socket che rappresenta quella connessione.
Per tutti i pacchetti TCP ricevuti successivamente, il sistema operativo controlla gli indirizzi e verifica se corrispondono a una connessione socket stabilita. In tal caso, il contenuto del pacchetto viene memorizzato in un buffer che può essere letto dal descrittore del file del socket dal processo del server. Quando il server scrive sul descrittore del file di connessione socket, il sistema operativo conosce l'indirizzo locale e remoto e può quindi creare un pacchetto TCP con i metadati appropriati.
Quindi i socket sono voci in una tabella di ricerca utilizzata dal sistema operativo per tradurre tra descrittori di file e indirizzi / porte di rete.