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_WAIT
o 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_WAIT
lado do cliente para onde ele pode ser um problema, a partir do lado do servidor onde não é um problema.
TIME_WAIT
Obviamente, 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_LINGER
com tempo limite 0, ou se intrometendo com tcp_tw sysctls) combate o lado do cliente, TIME_WAIT
evitando 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_WAIT
está aí, porque evita a injeção de TCP
fragmentos obsoletos em fluxos aos quais eles não pertencem mais. Para o lado do cliente, TIME_WAIT
isso é feito simplesmente impossibilitando a criação de uma conexão com os mesmos ip:port
pares 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_WAIT
realmente não faz nada e é deixado assim porque oRFC
requer? - É por isso que a recomendação é que o cliente inicie close () porque o servidor
TIME_WAIT
é inútil?
TIME_WAIT
.