É possível que uma conexão TCP permaneça aberta quando o cliente for desconectado?

12

Temos um aplicativo de servidor que enfrenta problemas de exaustão de TCP em cerca de 4000 conexões. Isso ocorrerá a cada 3 ou 4 semanas (aproximadamente). O fornecedor, que criou esse aplicativo de servidor, informa-nos, após examinar a saída do netstat -b, que algumas conexões permanecem abertas, mesmo que os clientes tenham caído.

Recebi a tarefa de investigar por que um aplicativo cliente específico não está fechando a conexão TCP corretamente. Acredito que, se um computador cliente for desligado, não será possível relatar POSSÍVEL do servidor que uma conexão TCP ainda está estabelecida com esse cliente. Infelizmente, não consigo encontrar nenhuma informação para validar minha visão. Não quero perder mais tempo investigando um problema em potencial que acho que nem pode ser um problema.

tldr;

Um servidor pode relatar uma conexão estabelecida com um computador desligado?

Josh Smeaton
fonte

Respostas:

13

O TCP não faz nenhum esforço para detectar uma conexão morta, exceto no lado que está transmitindo dados. É de responsabilidade do código do aplicativo que está chamando na pilha TCP fazer isso. Qual protocolo está envolvido aqui? (Aquele em cima do TCP.)

É uma "solução" horrivelmente feia, mas você pode ativar os keepalives do TCP . Há mais neste artigo .

David Schwartz
fonte
Você provavelmente quis dizer camada e é a camada de sessão na parte superior da camada de transporte, que é onde o TCP reside.
Rilindo
11
@Rilindo: Na prática, e neste caso em particular, você tem um aplicativo que faz chamadas para a pilha TCP. O protocolo no topo do TCP (HTTP, POP ou o que for) normalmente especifica como fazer isso, porque os projetistas desses protocolos sabiam que o TCP não poderia fazer isso sozinho.
David Schwartz
Opa, meu erro. Sua camada 7, então.
Rilindo
Não vou ativar as keepalives neste momento, mas é útil saber que a opção existe. Esse artigo parece sugerir que já existe um tempo limite de 2 horas. AFAIK, as conexões estão sendo mantidas abertas por dias / semanas.
Josh Smeaton
Provavelmente, keepalives não estão ativados. Algum pedaço de código precisa habilitá-los. Parece que o aplicativo está simplesmente quebrado, se nem mesmo ativar a keepalives e não tiver um mecanismo de tempo limite / colheita. De que protocolo estamos falando? (HTTP? SMTP? FTP?)
David Schwartz
8

Sim, é possível. Como David e Paul declararam em suas respostas, não há nenhum mecanismo no TCP (exceto TCP keep-alives, que são opcionais) para detectar uma conexão semi-aberta. Cabe ao fornecedor do aplicativo determinar o estado da conexão e tomar as medidas apropriadas de acordo.

No que diz respeito ao TCP, não há detecção ou distinção entre uma conexão semi-aberta e uma longa conexão inativa.

Você precisará começar a solucionar isso da camada 1 (física) do modelo OSI até a camada 7 (aplicativo) para descobrir onde o problema está ocorrendo. Meu conselho seria instalar e executar um programa de captura de pacotes em um dos clientes afetados até que o problema ocorra e analisar a captura para tentar determinar o que está fazendo com que o cliente não feche a conexão.

joeqwerty
fonte
3
Ou peça ao fornecedor para implementar intervalos razoáveis ​​:)
Shane Madden
5

Quando uma estação de trabalho deseja fechar uma conexão com um servidor, envia um TCP FIN. Se o cliente não estiver se comportando corretamente e não estiver fechando suas conexões, ele poderá, de fato, permanecer estabelecido no servidor. Você pode definir tempos limite para conexões abertas no servidor para limpá-las - embora seja melhor encontrar a causa. Em que porta as conexões abertas estão entrando? Depois de saber qual serviço está sendo acessado, você poderá identificar o aplicativo cliente que está atingindo o servidor.

Paul Ackerman
fonte
Conhecemos o cliente que é o aparente problema. É um aplicativo de desktop que centenas de nossos usuários usam diariamente. Suponho que o problema seja o travamento do aplicativo, uma reinicialização total ou uma tarefa final. Pensei em todas essas situações que o servidor estaria ciente da queda da conexão.
Josh Smeaton
4
No que diz respeito ao servidor, a conexão está aberta, a menos que receba um FIN ou um RST do cliente. Sem isso, o servidor assume que a conexão ainda está estabelecida, mas que o cliente não possui dados para enviar. Não há diferença entre uma conexão semi-aberta e uma conexão ociosa no que diz respeito ao servidor.
precisa saber é o seguinte
@joeqwerty: Verdade, no entanto, o servidor pode decidir que não deseja manter aberta uma conexão indefinidamente e pode implementar algum mecanismo de tempo limite / fechamento. Foi isso que David Schwartz quis dizer em sua resposta por "é de responsabilidade do código do aplicativo". Portanto, o servidor pode fazer a diferença entre uma conexão semiaberta e uma conexão ociosa, se desejar. Para o TCP, no entanto, não há realmente nenhuma diferença entre uma conexão semiaberta e uma conexão ociosa.
21811 sleske #
@lesleske: concordou que o código do aplicativo poderia fazer isso, mas o TCP não pode, a menos que os keep-alives estejam ativados.
precisa saber é o seguinte