Eu sei que existem algumas perguntas sobre SE e acredito que li tantas delas quanto antes antes de chegar a esse ponto.
Por "lado do servidor TIME_WAIT", quero dizer o estado de um par de soquetes do lado do servidor que teve seu close () iniciado no lado do servidor.
Costumo ver estas afirmações que me parecem contraditórias:
- O lado do servidor
TIME_WAITé inofensivo - Você deve projetar seus aplicativos de rede para que os clientes iniciem close (), fazendo com que o cliente suporte os
TIME_WAIT
A razão pela qual considero isso contraditório é porque TIME_WAITo cliente pode ser um problema - o cliente pode ficar sem portas disponíveis; portanto, em essência, o acima recomendado é transferir a carga do TIME_WAITlado do cliente para onde ele pode ser um problema, a partir do lado do servidor onde não é um problema.
TIME_WAITObviamente, o lado do cliente é apenas um problema para um número limitado de casos de uso. A maioria das soluções cliente-servidor envolveria um servidor e muitos clientes. Geralmente, os clientes não lidam com um volume de conexões suficientemente alto para que isso seja um problema e, mesmo se o fizerem, há várias recomendações para "sanear". em oposição a SO_LINGERcom tempo limite 0, ou se intrometendo com tcp_tw sysctls) combate o lado do cliente, TIME_WAITevitando criar muitas conexões muito rapidamente. Mas isso nem sempre é viável, por exemplo, para classes de aplicativos como:
- sistemas de monitoramento
- geradores de carga
- proxies
Por outro lado, eu nem entendo como o lado do servidor TIME_WAITé útil. O motivo TIME_WAITestá aí, porque evita a injeção de TCPfragmentos obsoletos em fluxos aos quais eles não pertencem mais. Para o lado do cliente, TIME_WAITisso é feito simplesmente impossibilitando a criação de uma conexão com os mesmos ip:portpares que essa conexão obsoleta poderia ter (os pares usados são bloqueados por TIME_WAIT). Mas para o servidor, isso não pode ser evitado, pois o endereço local terá a porta de aceitação e sempre será o mesmo, e o servidor não pode (AFAIK, eu tenho apenas a prova empírica) negar a conexão simplesmente porque um ponto de entrada criaria o mesmo par de endereços que já existe na tabela de soquetes.
Eu escrevi um programa que mostra que o TIME-WAIT do lado do servidor é ignorado. Além disso, como o teste foi realizado no 127.0.0.1, o kernel deve ter um bit especial que informa se é do lado do servidor ou do cliente (caso contrário, a tupla seria a mesma).
Fonte: http://pastebin.com/5PWjkjEf , testado no Fedora 22, configuração de rede padrão.
$ gcc -o rtest rtest.c -lpthread
$ ./rtest 44400 s # will do server-side close
Will initiate server close
... iterates ~20 times successfully
^C
$ ss -a|grep 44400
tcp TIME-WAIT 0 0 127.0.0.1:44400 127.0.0.1:44401
$ ./rtest 44500 c # will do client-side close
Will initiate client close
... runs once and then
connecting...
connect: Cannot assign requested address
Portanto, para o lado do servidor TIME_WAIT, as conexões exatamente no mesmo par de portas podem ser restabelecidas imediatamente e com êxito e, para o lado do cliente TIME-WAIT, na segunda iteração, a connect()falha com retidão
Para resumir, a pergunta é dupla:
- O lado do servidor
TIME_WAITrealmente não faz nada e é deixado assim porque oRFCrequer? - É por isso que a recomendação é que o cliente inicie close () porque o servidor
TIME_WAITé inútil?
TIME_WAIT.