2013-07-18 8 views
6

Ho visto molte risposte simili a questo 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 serverServerSocket accetta socket di ritorno su una porta arbitraria?

Client A invia una richiesta al Server sulla porta 5000. La porta sul lato del Cliente A viene scelta dal Sistema Operativo, in genere il SO 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 si è verificato per la porta 45546 di recente, il sistema operativo proverebbe quindi 45547).

Supponendo che non vi siano problemi di connessione, il server riceve la richiesta del client A di connettersi sulla porta 5000. Il server quindi apre la sua prossima porta disponibile, e lo invia al cliente. Qui, il client A si collega 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 del accept() della porta su cui è in ascolto ServerSocket. Ho sempre avuto l'impressione che 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é accept() deve restituire un socket associato a una porta diversa? Il quartetto di informazioni inviato in ogni intestazione non distingue più connectio ns alla stessa porta server di macchine diverse abbastanza dove non avrebbe bisogno di usare porte diverse sulla macchina server per la comunicazione?

+0

Ecco un [collegamento alla risposta errata che viene citata] (http://stackoverflow.com/a/17730496/207421). Se ci sono altre di queste "molte risposte simili a questa", si prega di fornire collegamenti in modo che possano essere downvoted e commentati in modo negativo. Non so perché la gente indovina su cose come questa quando la RFC è lì per essere letta. – EJP

+0

Non c'era ipotesi. C'è stata una progressione logica delle informazioni basata su una premessa errata. –

+0

@RussellUhl Una congettura non verificata basata su premesse non verificate e inferenze logiche non esaminate è essenzialmente un'ipotesi. Qual era la premessa imperfetta? Quando hai consultato la RFC? Quando hai dato un'occhiata a Socket.getLocalPort() o a un output di 'netstat'? – EJP

risposta

4

Si è corretti nelle informazioni dell'intestazione del pacchetto TCP. Contiene:

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

Oppure, in modo più appropriato (dal client/server diventano fonte di confusione quando si pensa di trasferimento bidirezionale):

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

connessioni multiple verso lo stesso porto di server verranno da diverso 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 nei porti client è sufficiente per disambiguare le due prese, ed avere così due connessioni separate. Non è necessario che il server apra un altro socket su un'altra porta. Riceve una presa dal metodo accept, ma è assegnata alla stessa porta e ora è un percorso di ritorno al 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.

+0

quindi la risposta che ho citato era sbagliata? – sunrize920

+2

@ sunrize920 Sì. Un server può accettare dati da vari client sulla stessa porta, a condizione che l'IP/porta di origine sia diverso. Una porta non è altro che un numero. –

14

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

No. Si crea un nuovo socket con il numero di porta locale stesso. 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, Client Un collega alla nuova porta,

No. Il cliente prende atto del/pacchetto ACK SYN e il client è connesso alla porta originaleda allora in poi, dopo aver riconosciuto il SYN/ACK. Non c'è una seconda connessione.

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

E 'sempre fatto.

Ho visto risposte come questo in domande a risposta multipla su StackOverflow su come una porta diversa viene utilizzato nel socket restituito dell'accettazione() della porta su cui è in ascolto ServerSocket.

Qualsiasi risposta di questo tipo è errato e dovrebbe essere messo in down con 'pregiudizio estremo' e commentato 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é accept() deve restituire un socket associato a una porta diversa?

Non funziona.

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

Sì.

+0

Non lo sei, ma alcune persone lo sono. Non inizia nemmeno a dare un senso. Cosa impedisce a questo secondo processo di connessione di avviare una terza connessione e diventare quindi un regresso infinito? Dove nel pacchetto SYN/ACK c'è questa mitica seconda porta? Come possono essere effettuate due connessioni in tre messaggi? Perché è così pieno di domande su migliaia di porte 80 linee in TIME_WAIT in un display netstat?È completamente ridicolo. – EJP

+1

@EJP +1 per annotare l'intera domanda :). Bella risposta. –

+0

Non sono più sicuro di ciò a cui mi riferisco. È del tutto possibile che io stia scambiando il TCP con i protocolli a livello di applicazione. In ogni caso, riconosco liberamente che la mia comprensione fondamentale del TCP è gravemente imperfetta. –

Problemi correlati