Come funziona la funzione accetta () API socket?


126

L'API socket è lo standard di fatto per le comunicazioni TCP / IP e UDP / IP (ovvero il codice di rete come lo conosciamo). Tuttavia, una delle sue funzioni principali accept()è un po 'magica.

Per prendere in prestito una definizione semi-formale:

accept () viene utilizzato sul lato server. Accetta un tentativo in entrata ricevuto di creare una nuova connessione TCP dal client remoto e crea un nuovo socket associato alla coppia di indirizzi socket di questa connessione.

In altre parole, acceptrestituisce un nuovo socket attraverso il quale il server può comunicare con il client appena connesso. Il vecchio socket (su cui è acceptstato chiamato) rimane aperto, sulla stessa porta, in attesa di nuove connessioni.

Come acceptfunziona? Come viene implementato? C'è molta confusione su questo argomento. Molte persone affermano che accetta apre una nuova porta e tu comunichi con il cliente attraverso di essa. Ma questo ovviamente non è vero, poiché non è stata aperta alcuna nuova porta. Puoi effettivamente comunicare attraverso la stessa porta con client diversi, ma come? Quando più thread chiamano recvsulla stessa porta, come fanno i dati a sapere dove andare?

Immagino che sia qualcosa sulla falsariga dell'indirizzo del cliente associato a un descrittore di socket, e ogni volta che i dati arrivano vengono recvinstradati al socket corretto, ma non ne sono sicuro.

Sarebbe bello avere una spiegazione approfondita del funzionamento interno di questo meccanismo.


2
quindi per ogni richiesta del client, viene aperta una nuovissima connessione socket all'estremità del server. Il server deve essere aperto a 80 sempre per ascoltare le chiamate in arrivo. Se riceve una chiamata, crea immediatamente un NUOVO socket con le quattro tuple come indicato di seguito, che stabilirà una connessione TCP tra client e server. La mia comprensione è corretta?
brain storm,

1
Questa è una domanda fondamentale e di recente sono stato testato su questo in un'intervista: stackoverflow.com/questions/24871827/… Se avete commenti su questo, per favore post
brain storm

@brainstorm Solo se ignori completamente l'esistenza di HTTP keep-alive.
Marchese di Lorne

Risposte:


140

La tua confusione sta nel pensare che un socket sia identificato dall'IP del server: Porta del server. In realtà, i socket sono identificati in modo univoco da un quartetto di informazioni:

Client IP : Client Port e Server IP : Server Port

Quindi, mentre l'IP del server e la porta del server sono costanti in tutte le connessioni accettate, le informazioni sul lato client sono ciò che consente di tenere traccia di dove tutto sta andando.

Esempio per chiarire le cose:

Supponiamo che abbiamo un server su 192.168.1.1:80e due client 10.0.0.1e 10.0.0.2.

10.0.0.1apre una connessione sulla porta locale 1234e si connette al server. Ora il server ha un socket identificato come segue:

10.0.0.1:1234 - 192.168.1.1:80  

Ora 10.0.0.2apre una connessione sulla porta locale 5678e si connette al server. Ora il server ha due socket identificati come segue:

10.0.0.1:1234 - 192.168.1.1:80  
10.0.0.2:5678 - 192.168.1.1:80

3
Non conosco i dettagli di implementazione (che probabilmente variano da piattaforma a piattaforma), so solo che concettualmente i socket sono identificati dal quartetto di informazioni che ho descritto.
17 del 26

3
Hai qualche riferimento al riguardo?
Qeek

3
Domanda casuale: cosa succede se si utilizza NAT e due client sulla stessa rete tentano di utilizzare la stessa porta locale durante la connessione al server? Ad esempio, se 10.0.0.1 e 10.0.0.2 sono entrambi collegati a un router con un IP esterno di 192.168.0.1, quindi il server in 192.168.1.1 vede due connessioni da 192.168.0.1. Cosa succede in quel caso se con un colpo di fortuna del generatore di numeri casuali sia 10.0.0.1 che 10.0.0.2 scelgono la stessa porta locale?
aroth

4
Il supporto NAT nel router si occupa dei dettagli lì. Il traffico di rete in realtà passa attraverso due connessioni: da client a router e da router a server. Il router effettua le connessioni in uscita su due diverse porte 192.168.0.1:1234 e 192.168.0.1:5678. Il traffico in entrata viene quindi reindirizzato dal router al client corretto.
17 del 26

3
Se un quartetto identifica un socket, quali sono le informazioni sul quartetto di un socket in ascolto?
Eric Zheng,

74

Solo per aggiungere alla risposta data dall'utente "17 di 26"

Il socket in realtà è composto da 5 tuple (ip sorgente, porta sorgente, ip destinazione, porta destinazione, protocollo). Qui il protocollo potrebbe TCP o UDP o qualsiasi protocollo del livello di trasporto. Questo protocollo è identificato nel pacchetto dal campo "protocollo" nel datagramma IP.

Pertanto, è possibile avere diverse applicazioni sul server che comunicano con lo stesso client esattamente sulle stesse 4 tuple ma diverse nel campo del protocollo. Per esempio

Apache sul lato server parlando (server1.com:880-client1:1234 su TCP) e World of Warcraft parlando (server1.com:880-client1:1234 su UDP)

Sia il client che il server gestiranno questo come campo del protocollo nel pacchetto IP in entrambi i casi è diverso anche se tutti gli altri 4 campi sono uguali.


13

Ciò che mi ha confuso quando stavo imparando questo, era che i termini sockete portsuggeriscono che sono qualcosa di fisico, quando in realtà sono solo strutture di dati che il kernel usa per astrarre i dettagli della rete.

Pertanto, le strutture di dati sono implementate per essere in grado di separare le connessioni da client diversi. Per quanto riguarda il modo in cui sono implementate, la risposta è o.) Non importa, lo scopo dell'API socket è precisamente che l'implementazione non dovrebbe importare o b.) Basta dare un'occhiata. Oltre ai libri altamente raccomandati di Stevens che forniscono una descrizione dettagliata di un'implementazione, controlla la fonte in Linux o Solaris o in uno dei BSD.


Sì, la maggior parte della terminologia di rete sta semplicemente assegnando nomi a determinate raccolte di bit e alle decisioni prese in base ai loro valori ("identificativo di protocollo", "instradamento", "associazione", "socket" ecc.). Tutto l' hardware della scheda di rete è progettato per ricevere è un flusso di bit. Ciò che accade loro in relazione ai programmi sul computer è deciso dal driver e dal sistema operativo. Domani potremmo sbarazzarci di tutta quella terminologia, se vogliamo, ma il principio di erogare un flusso di bit sembra fondamentale ...
masterxilo,

-1

Come ha detto l'altro ragazzo, un socket è identificato in modo univoco da una 4 tupla (IP client, Porta client, IP server, Porta server).

Il processo del server in esecuzione sull'IP del server mantiene un database (il che significa che non mi interessa quale tipo di struttura di dati tabella / elenco / albero / matrice / magia utilizzi) di socket attivi e ascolti sulla porta del server. Quando riceve un messaggio (tramite lo stack TCP / IP del server), controlla l'IP client e la porta rispetto al database. Se l'IP client e la porta client si trovano in una voce del database, il messaggio viene passato a un gestore esistente, altrimenti viene creata una nuova voce del database e viene generato un nuovo gestore per gestire quel socket.

All'inizio di ARPAnet, alcuni protocolli (FTP per uno) ascoltavano una porta specifica per le richieste di connessione e rispondevano con una porta di handoff. Ulteriori comunicazioni per quella connessione andrebbero oltre la porta di handoff. Ciò è stato fatto per migliorare le prestazioni per pacchetto: i computer erano più lenti di alcuni ordini di grandezza a quei tempi.


puoi approfondire la parte "port handoff"?
Eli Bendersky,

1
Questa è una descrizione di alcuni protocolli pre-TCP o eccessivamente semplificata. Un client che tenta di connettersi a un socket di ascolto invia un pacchetto speciale per stabilire la connessione (set di bit SYN). Esiste una chiara distinzione tra un pacchetto che crea un nuovo socket e uno che utilizza un socket esistente.
John M,

... invia un pacchetto speciale per stabilire la connessione (bit SYN impostato). Il che (come ho capito) fa sì che lo stack di protocollo lo dia all'ascoltatore '' (se presente) ed è per questo che può esserci una sola porta di ascolto per combinazione indirizzo / porta / protocollo. Non sono sicuro se questo sia nelle specifiche o semplicemente nella convenzione di implementazione.
Peter Wone,

1
Il secondo paragrafo non descrive correttamente ciò che accade al livello TCP o all'interno di un processo del server. Non è necessario che i processi server mantengano le strutture dati dei socket di alcun tipo o che controllino l'IP in entrata: coppie di porte contro qualsiasi cosa. Ecco a cosa servono le prese. FTP utilizza una porta separata per i dati, non per tutte le "ulteriori comunicazioni", e cappelli fatti per semplificare il protocollo, non per motivi di prestazioni. Utilizzare una nuova porta senza migliorare le prestazioni in alcun modo.
Marchese di Lorne,

"mantiene un database (il che significa che non mi interessa quale tipo di struttura di dati tabella / elenco / albero / matrice / magia utilizza)" :) Di solito lo chiamo "Tabella" (o forse "Grafico" o "Albero decisionale" ). "Database" mi suggerisce alcune implementazioni.
masterxilo,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.