2011-02-09 23 views
21

La macchina è RHEL 5.3 (kernel 2.6.18).Come si può avere una connessione TCP alla stessa porta?

Alcune volte mi preavviso netstat che la mia domanda è dotato di connessione, connessione TCP stabilita quando locale Indirizzo e Indirizzo Esteri sono gli stessi.

Here stesso problema segnalato da qualcun altro.

I sintomi sono gli stessi descritti in collegamento: il client si connette alla porta X porta del server in esecuzione localmente. Dopo un po 'di tempo netstat mostra che il client ha una connessione da 127.0.0.1:X a 127.0.0.1:X

Come è possibile?

Modifica 01

aperto simultanea è la causa del problema (grazie mille a Hasturkun). È possibile vederlo su classical TCP state diagram in transizione da SYN_SENT a SYNC_RECEIVED

+0

I sintomi sono gli stessi descritti nel collegamento: il client si connette alla porta X porta del server in esecuzione localmente. Dopo un po 'di tempo, netstat mostra che il client ha una connessione da 127.0.0.1:X a 127.0.0.1:X – dimba

risposta

17

Ciò può essere causato dal collegamento simultaneo TCP (indicato on this post to LKML, vedere anche here).

È possibile che un programma esegua il loop durante il tentativo di connessione a una porta all'interno dell'intervallo di porte locali dinamiche (che può essere visualizzato in /proc/sys/net/ipv4/ip_local_port_range), per riuscire mentre il server non è in ascolto su quella porta.

Su un numero sufficientemente grande di tentativi, il socket utilizzato per la connessione può essere associato alla stessa porta a cui è connesso, che riesce a causa della connessione simultanea menzionata in precedenza. Ora magicamente hai un client collegato a se stesso

+0

+1 sembra che questo possa essere la causa del mio problema – dimba

+0

Infatti, il mio client tenta costantemente di connettersi al server se il server non funziona. Quindi la domanda ora come posso prevenire tale situazione? Significa che il server dovrebbe usare porte non in/proc/sys/net/ipv4/ip_local_port_range range? – dimba

+0

@dimba: si, avere il server in ascolto su una porta inferiore al limite inferiore dell'intervallo impedirà questo problema. – Hasturkun

12

Una connessione TCP è identificata in modo univoco da questa tupla (local address, local port #, foreign address, foreign port #). Non è necessario che local address e foreign address, o anche che i numeri di porta siano diversi (anche se sarebbe estremamente strano). Ma c'è al massimo una connessione TCP che ha gli stessi valori per una determinata tupla.

Quando un computer si connette a se stesso, l'indirizzo locale e l'indirizzo straniero sono quasi sempre gli stessi. Dopotutto, il lato "locale" e "straniero" sono in realtà lo stesso computer. In effetti, quando ciò accade, il tuo computer dovrebbe mostrare due connessioni che hanno gli stessi indirizzi "locali" e "stranieri", ma numeri di porta invertiti. Per esempio:

$ ssh localhost 

si tradurrà in due connessioni che simile a questa:

$ netstat -nA inet | fgrep :22 
Active Internet connections (w/o servers) 
Proto Recv-Q Send-Q Local Address  Foreign Address  State  
tcp  0  0 127.0.0.1:56039  127.0.0.1:22   ESTABLISHED 
tcp  0  0 127.0.0.1:22   127.0.0.1:56039  ESTABLISHED 

Come si può vedere, l'indirizzo locale e indirizzi estranei sono gli stessi, ma i numeri di porta sono invertiti. La tupla unica per questa connessione TCP è (127.0.0.1, 56039, 127.0.0.1, 22). Non ci sarà altra connessione TCP che abbia questi stessi quattro campi.

Il fatto che si vedano due è perché il computer è entrambi i lati della connessione. Ogni estremità ha la propria visione di quale è "estraneo" e che è "locale".

È anche possibile connettersi a se stessi sulla stessa porta, e mentre questo non è un evento comune, non è vietato dalle specifiche. Ecco un esempio di programma in Python, che farà questo:

import socket 
import time 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.bind(('127.0.0.1', 56443)) 
s.connect(('127.0.0.1', 56443)) 
time.sleep(30) 

Questo codice funziona perché un modo in cui è possibile aprire una connessione TCP è quello di avere l'altro lato della connessione tenta di aprire uno con voi simultaneamente . Questo è noto come simultaneous SYN exchange e la risposta collegata a StackOverflow descrive di cosa si tratta.

Ho anche un documento su using simultaneous SYN exchange to get through NAT, anche se in questo caso la fonte e quella esterna sarebbero completamente diversi.

+0

Capito. Ma come il client alla fine apre la stessa porta del server (vedi link in post)? Il server dei risultati non può aprire la porta del server come già in uso. – dimba

+0

AFAIK, non mi connetto intenzionalmente dalla stessa porta alla stessa porta – dimba

+0

@dimba - Ho il codice ora che mostra come farlo accadere. Perché qualcuno farebbe una cosa del genere è un'altra domanda. Ma è certamente possibile. – Omnifarious

Problemi correlati