Domanda

Stavo leggendo su come utilizzare l'opzione socket SO_LINGER intenzionalmente 'uccidere' stato TIME-WAIT impostando il tempo di indugiare a zero. L'autore del libro passa poi a dire che non dobbiamo mai fare questo e, in generale, che non dovremmo mai interferire con lo stato TIME-WAIT. Poi raccomanda immediatamente di usare l'opzione SO_REUSEADDR per bypassare lo stato tempo di attesa.

La mia domanda è, qual è la differenza? In entrambi i casi si sta prematuramente terminare lo stato di tempo di attesa e di correre il rischio di non ricevere segmenti duplicati. Perché è uno buono e l'altro cattivo?

È stato utile?

Soluzione 2

Ho fatto un po 'di lettura e questa è la mia comprensione di ciò che accade (si spera corretto):

Quando si chiama stretta su un socket che ha impostato SO_REUSEADDR (o di crash app) la seguente sequenza di verifica:

  1. TCP invia i dati rimanenti nel buffer di trasmissione e un FIN
  2. Se la chiusura è stato chiamato restituisce immediatamente senza indicato eventuali dati rimanenti è stato consegnato con successo.
  3. Se i dati sono stati inviati al peer invia un data ACK
  4. Il peer invia un ACK del FIN e invia il proprio pacchetto FIN
  5. FIN del pari è acked e le risorse socket sono deallocata.
  6. La presa non entra TIME-WAIT.

Quando si chiude una presa con il tempo SO_LINGER impostato a zero:

  1. TCP scarta tutti i dati nel buffer di trasmissione
  2. TCP invia un pacchetto RST al peer
  3. La risorsa presa sono deallocata.
  4. La presa non entra TIME-WAIT

Quindi, al di là del fatto che l'impostazione Linger a zero è uno stile hack and male è anche maleducazione in quanto non passa attraverso un arresto pulito del collegamento.

Altri suggerimenti

TIME_WAIT è assolutamente normale. Essa si verifica dopo un FIN TCP sul lato locale seguito da un TCP FIN ACK dalla posizione remota. In TIME_WAIT si sta solo aspettando eventuali pacchetti randagi per arrivare al l'indirizzo locale. Tuttavia, se v'è un pacchetto perso o randagi allora TIME_WAIT garantire che TTL o "tempo di vita" scade prima di utilizzare nuovamente l'indirizzo.

Se si utilizza SO_REUSEADDR poi si sono fondamentalmente dicendo, I assumerà che non ci sono i pacchetti randagi. Che è sempre più probabile con affidabili, moderne reti, TCP. Anche se è ancora possibile è improbabile.

Impostazione SO_LINGER a zero provoca per avviare una anomala vicino, chiamato anche "chiudendo la connessione." Qui non si rispettano TIME_WAIT e ignorare il possiblity di un pacchetto randagio.

Se si vede FIN_WAIT_1 allora questo può causare problemi, come la posizione a distanza non ha inviato un TCP FIN ACK in risposta al vostro FIN. Così il processo è stato ucciso o TCP FIN ACK è stato perso a causa di una partizione di rete o una rotta più cattivo.

Quando si vede CLOSE_WAIT hai un problema, qui si sono perdite connessioni in quanto non sta inviando il TCP FIN ACK quando data la TCP FIN.

Devo utilizzare SO_REUSEADDR al jolly bind () a una porta locale per il quale qualche altro programma aveva già una connessione aperta su. Si scopre questo uso particolare non potrà mai causare un problema fino a quando non ci sono due prese di cercare di ascoltare () sullo stesso combo Ind / porto, allo stesso tempo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top