ServerSocket accetta il socket di ritorno su una porta arbitraria?

Ho visto molte risposte simili a questa per quanto riguarda i server socket in Java: “Supponiamo che tu abbia un server con un serverocket sulla porta 5000. Il client A e il client B si connetteranno al nostro server.

Il client A invia una richiesta al server sulla porta 5000. La porta sul lato del cliente A viene scelta dal sistema operativo. Di solito, il sistema operativo seleziona la porta successiva disponibile. Il punto di partenza per questa ricerca è il numero di porta precedentemente utilizzato + 1 (quindi, ad esempio, se il sistema operativo ci è successo di recente nella porta 45546, il sistema operativo avrebbe quindi provato 45547).

Supponendo che non ci siano problemi di connessione, il server riceve la richiesta del client A di connettersi sulla porta 5000. Il server quindi apre la sua successiva porta disponibile e lo invia al client. Qui, il client A si connette alla nuova porta e il server ha di nuovo disponibile la porta 5000. ”

Ho visto risposte come questa in più domande su StackOverflow su come viene utilizzata una porta diversa nel socket restituito di accept () rispetto alla porta su cui ServerSocket sta ascoltando. Ho sempre avuto l’impressione che il TCP sia identificato dal quartetto di informazioni:

IP client: porta client e IP server: porta server -> anche protocollo (per distinguere TCP da UDP)

Quindi, perché l’accept () deve restituire un socket associato a una porta diversa? Il quartetto di informazioni inviato in ogni intestazione non distingue più connessioni alla stessa porta server da macchine diverse abbastanza da non dover utilizzare per la comunicazione porte diverse sulla macchina server?

Sei corretto nelle informazioni dell’intestazione del pacchetto TCP. Contiene:

 Client IP | Client Port | Server IP | Server Port | Protocol 

O, più appropriatamente (dal momento che il client / server diventa confuso quando si pensa al trasferimento bidirezionale):

 Source IP | Source Port | Destination IP | Destination Port | Protocol 

Più connessioni alla stessa porta del server arriveranno da diverse porte sul client. Un esempio può essere:

 0.0.0.0:45000 -> 1.1.1.1:80 0.0.0.0:45001 -> 1.1.1.1:80 

La differenza nelle porte client è sufficiente per disambiguare i due socket e quindi avere due connessioni separate. Non è necessario che il server apra un altro socket su un’altra porta. Riceve un socket dal metodo accept , ma è assegnato alla stessa porta e ora è un percorso verso il client appena accettato.

FTP, d’altra parte, ha un modello in cui il server aprirà una nuova porta non privilegiata (> 1023) e lo invierà al client per il client a cui connettersi (questo è indicato come “FTP passivo”). Questo serve a risolvere problemi in cui il client si trova dietro un firewall e non può accettare connessioni dati in entrata dal server. Tuttavia, questo non è il caso in un tipico server HTTP (o qualsiasi altra implementazione socket standard). È una funzionalità stratificata su FTP.

Il server apre quindi la sua successiva porta disponibile e lo invia al client.

No. Crea un nuovo socket con lo stesso numero di porta locale. Nessun secondo numero di porta viene assegnato o inviato al client. Il segmento SYN / ACK che è la risposta del server alla richiesta di connessione non contiene un secondo numero di porta.

Qui, il client A si connette alla nuova porta,

No. Il client riconosce il pacchetto SYN / ACK e il client è connesso alla porta originale da quel momento in poi, dopo aver riconosciuto il SYN / ACK. Non c’è una seconda connessione.

e il server ora ha di nuovo disponibile la porta 5000. ”

Lo ha sempre fatto.

Ho visto risposte come questa in più domande su StackOverflow su come viene utilizzata una porta diversa nel socket restituito di accept () rispetto alla porta su cui ServerSocket sta ascoltando.

Qualsiasi risposta di questo tipo è errata e dovrebbe essere downvoted “con estremo pregiudizio” e commentata negativamente. L’handshake TCP è definito in RFC 793 e non specifica l’allocazione e lo scambio di una seconda porta e un secondo messaggio di connessione. Ci sono solo tre messaggi, che non sono nemmeno sufficienti per questo.

Quindi, perché l’accept () deve restituire un socket associato a una porta diversa?

Non è così.

Il quartetto di informazioni inviato in ogni intestazione non distingue più connessioni alla stessa porta server da macchine diverse abbastanza da non dover utilizzare per la comunicazione porte diverse sulla macchina server?

Sì.