Pergunta

Eu estava lendo sobre como utilizar a opção de socket SO_LINGER para intencionalmente 'assassinar' o estado de tempo de espera, definindo o tempo de retardo para zero. O autor do livro, em seguida, continua a dizer que nunca devemos fazer isso e, em geral, que nunca deve interferir com o estado de tempo de espera. Ele então imediatamente recomenda usar a opção SO_REUSEADDR para ignorar o estado de tempo de espera.

A minha pergunta é, qual é a diferença? Em ambos os casos você está terminando prematuramente o estado de tempo de espera e correr o risco de receber segmentos duplicados. Por que é uma boa e outra ruim?

Foi útil?

Solução 2

Eu fiz um pouco mais de leitura e esta é a minha compreensão do que acontece (espero correto):

Quando você chamar perto de uma tomada que tem conjunto SO_REUSEADDR (ou suas falhas de aplicativos) a seguinte seqüência ocorre:

  1. TCP envia quaisquer dados remanescentes no buffer de envio e uma FIN
  2. Se perto foi chamado ele retorna imediatamente sem indicada se quaisquer dados restantes foi entregue com êxito.
  3. Se os dados foram enviados o peer envia um dado ACK
  4. O ponto envia um ACK do FIN e envia seu próprio pacote FIN
  5. FIN do par é acked e os recursos de soquete são desalocados.
  6. A tomada não entra TIME-WAIT.

Quando você fecha um socket com o conjunto de tempo SO_LINGER a zero:

  1. TCP descarta quaisquer dados no buffer de envio
  2. TCP envia um pacote RST para o peer
  3. O socket resource são desalocados.
  4. A tomada não entra TIME-WAIT

Assim, além do fato de que a criação Linger a zero é um estilo hack and ruim também é falta de educação, pois não passar por um desligamento normal da conexão.

Outras dicas

TIME_WAIT é absolutamente normal. Ela ocorre depois de um TCP FIN sobre o lado local seguido por um TCP FIN ACK a partir do local remoto. Em TIME_WAIT você está apenas à espera de quaisquer pacotes de rua para chegar ao endereço local. No entanto, se há um pacote perdido ou extraviado, em seguida, TIME_WAIT garantir que TTL ou "tempo de vida" expira antes de usar o endereço novamente.

Se você usar SO_REUSEADDR então você está basicamente dizendo, vou assumir que não existem pacotes perdidos. Que é cada vez mais provável com, redes TCP confiáveis ??modernos. Embora ainda seja possível, é improvável.

Configuração SO_LINGER a zero faz com que você iniciar uma estreita anormal, também chamado de "bater a shut conexão." Aqui você não respeitar TIME_WAIT e ignorar a possibilidade de um pacote perdido.

Se você ver FIN_WAIT_1 então isso pode causar problemas, como o local remoto não enviou um TCP FIN ACK em resposta ao seu FIN. Assim, o processo foi morto ou o TCP FIN ACK foi perdido devido a uma partição de rede ou uma rota ruim.

Quando você vê CLOSE_WAIT você tem um problema, aqui estão vazando conexões que você não está enviando o TCP FIN ACK quando for dada a TCP FIN.

Eu tenho uso SO_REUSEADDR para ligar curinga () para uma porta local para o qual algum outro programa já tinha uma conexão aberta. Acontece que este uso particular nunca vai causar um problema, desde que há dois soquetes tentar ouvir () na mesma combinação endereço / porta ao mesmo tempo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top