AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / server / Perguntas / 329845
Accepted
Rehan
Rehan
Asked: 2008-09-04 04:57:26 +0800 CST2008-09-04 04:57:26 +0800 CST 2008-09-04 04:57:26 +0800 CST

Como fechar um soquete à força em TIME_WAIT?

  • 772

Eu corro um programa específico no linux que às vezes trava. Se você abri-lo rapidamente depois disso, ele escuta no soquete 49201 em vez de 49200, como fez na primeira vez. netstat revela que 49200 está em um estado TIME_WAIT.

Existe um programa que você pode executar para forçar imediatamente esse soquete a sair do estado TIME_WAIT?

linux networking unix tcp socket
  • 7 7 respostas
  • 294102 Views

7 respostas

  • Voted
  1. Eugene Yokota
    2008-09-04T05:11:37+08:002008-09-04T05:11:37+08:00
    /etc/init.d/networking restart
    

    Deixe-me elaborar. O Transmission Control Protocol (TCP) foi projetado para ser um protocolo de transmissão de dados bidirecional, ordenado e confiável entre dois pontos finais (programas). Nesse contexto, o termo confiável significa que ele retransmitirá os pacotes se se perder no meio. O TCP garante a confiabilidade enviando de volta os pacotes de confirmação (ACK) para um único ou um intervalo de pacotes recebidos do peer.

    Isso vale para os sinais de controle, como solicitação/resposta de término. A RFC 793 define o estado TIME-WAIT como segue:

    TIME-WAIT - representa a espera de tempo suficiente para se certificar de que o TCP remoto recebeu a confirmação de sua solicitação de término de conexão.

    Veja o seguinte diagrama de estado TCP: texto alternativo

    O TCP é um protocolo de comunicação bidirecional, portanto, quando a conexão é estabelecida, não há diferença entre o cliente e o servidor. Além disso, qualquer um pode encerrar e ambos os pares precisam concordar em fechar para fechar completamente uma conexão TCP estabelecida.

    Vamos chamar o primeiro para chamar as saídas como o ativo mais próximo, e o outro para o passivo mais próximo. Quando o ativo mais próximo envia FIN, o estado vai para FIN-WAIT-1. Em seguida, ele recebe um ACK para o FIN enviado e o estado vai para FIN-WAIT-2. Uma vez que recebe FIN também do mais próximo passivo, o mais próximo ativo envia o ACK para o FIN e o estado vai para TIME-WAIT. Caso o passivo mais próximo não tenha recebido o ACK para o segundo FIN, ele retransmitirá o pacote FIN.

    O RFC 793 define o TIME-OUT para ser duas vezes o Maximum Segment Lifetime, ou 2MSL. Como o MSL, o tempo máximo que um pacote pode percorrer a Internet, é definido como 2 minutos, 2MSL é de 4 minutos. Como não há ACK para um ACK, o ativo mais próximo não pode fazer nada além de esperar 4 minutos se aderir ao protocolo TCP/IP corretamente, caso o remetente passivo não tenha recebido o ACK em seu FIN (teoricamente) .

    Na realidade, os pacotes ausentes são provavelmente raros, e muito raros se tudo estiver acontecendo na LAN ou em uma única máquina.

    Para responder à pergunta literalmente, Como fechar um soquete à força em TIME_WAIT?, ainda vou manter minha resposta original:

    /etc/init.d/networking restart
    

    Praticamente falando, eu o programaria para que ele ignorasse o estado TIME-WAIT usando a opção SO_REUSEADDR como WMR mencionado. O que exatamente SO_REUSEDDR faz?

    Esta opção de soquete diz ao kernel que mesmo se esta porta estiver ocupada (no
    estado TIME_WAIT), vá em frente e reutilize-a de qualquer maneira. Se estiver ocupado, mas com outro estado, você ainda receberá um erro de endereço já em uso. É útil se o seu servidor foi desligado e reiniciado imediatamente enquanto os soquetes ainda estão ativos em sua porta. Você deve estar ciente de que, se algum dado inesperado chegar, poderá confundir seu servidor, mas, embora isso seja possível, não é provável.

    • 163
  2. WMR
    2008-09-04T05:17:07+08:002008-09-04T05:17:07+08:00

    Eu não sei se você tem o código-fonte desse programa específico que você está executando, mas se tiver, você pode definir SO_REUSEADDR via setsockopt(2)que permite vincular no mesmo endereço local, mesmo que o soquete esteja no estado TIME_WAIT (a menos que socket está escutando ativamente, veja socket(7)).

    Para obter mais informações sobre o estado TIME_WAIT, consulte o FAQ do soquete Unix .

    • 54
  3. Leigh Caldwell
    2008-09-04T05:24:42+08:002008-09-04T05:24:42+08:00

    Até onde eu sei, não há como forçar o fechamento do soquete fora de escrever um manipulador de sinal melhor em seu programa, mas existe um arquivo /proc que controla quanto tempo leva o tempo limite. O arquivo é

    /proc/sys/net/ipv4/tcp_tw_recycle
    

    e você pode definir o tempo limite para 1 segundo fazendo isso:

    echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle 
    

    No entanto, esta página contém um aviso sobre possíveis problemas de confiabilidade ao definir essa variável.

    Há também um arquivo relacionado

    /proc/sys/net/ipv4/tcp_tw_reuse
    

    que controla se os soquetes TIME_WAIT podem ser reutilizados (presumivelmente sem nenhum tempo limite).

    Aliás, a documentação do kernel avisa para não alterar nenhum desses valores sem 'conselhos/pedidos de especialistas técnicos'. O que eu não sou.

    O programa deve ter sido escrito para tentar uma ligação à porta 49200 e então incrementar em 1 se a porta já estiver em uso. Portanto, se você tiver o controle do código-fonte, poderá alterar esse comportamento para aguardar alguns segundos e tentar novamente na mesma porta, em vez de incrementar.

    • 34
  4. Best Answer
    akostadinov
    2011-10-31T09:32:47+08:002011-10-31T09:32:47+08:00

    Na verdade, existe uma maneira de matar uma conexão - killcx . Eles afirmam que funciona em qualquer estado da conexão (que não verifiquei). Você precisa conhecer a interface onde a comunicação acontece, porém, parece assumir eth0 por padrão.

    ATUALIZAÇÃO: outra solução é o cortador que vem em alguns repositórios de distribuições linux.

    • 21
  5. Rek
    2010-06-11T14:33:36+08:002010-06-11T14:33:36+08:00

    Outra opção é usar a opção SO_LINGER com timeout 0. Desta forma, ao fechar o socket é forçosamente fechado, enviando um RST ao invés de entrar no comportamento de fechamento FIN/ACK. Isso evitará o estado TIME_WAIT e pode ser mais apropriado para alguns usos.

    • 3
  6. andrew pate
    2014-08-22T12:28:30+08:002014-08-22T12:28:30+08:00

    Uma solução alternativa seria ter algum proxy confiável ou software de encaminhamento de porta que escute na porta 49200, então encaminhe a conexão para uma das várias instâncias de seu programa menos confiável usando portas diferentes... HAPROXY vem à mente.

    Aliás, a porta de sua conexão é bastante alta. Você pode tentar usar um não utilizado logo acima do intervalo 0-1024. É menos provável que seu sistema use um número de porta menor como uma porta efêmera.

    • 2
  7. Rahul Magar
    2011-10-14T11:07:51+08:002011-10-14T11:07:51+08:00

    TIME_WAIT é o problema mais comum na arquitetura do servidor cliente de programação de soquete. Aguarde alguns segundos tentando periodicamente é a melhor solução para isso. Para aplicativos em tempo real, eles precisam do servidor deve se levantar imediatamente. Existe a opção SO_REUSEADDR para eles.

    • 0

relate perguntas

  • Protegendo um novo servidor Ubuntu [fechado]

  • Ferramentas de utilização de largura de banda? [fechado]

  • (Soft) RAID 6 no Ubuntu 7.10, devo migrar para 8.10?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como posso dizer ao Apache qual PHP usar?

    • 5 respostas
  • Marko Smith

    Como fechar um soquete à força em TIME_WAIT?

    • 7 respostas
  • Marko Smith

    Como você copia um disco rígido físico para um disco rígido virtual VMware?

    • 11 respostas
  • Marko Smith

    Como despejar um banco de dados do Microsoft SQL Server em um script SQL?

    • 9 respostas
  • Marko Smith

    Como posso portar para frente com o iptables?

    • 8 respostas
  • Marko Smith

    Como vincular o servidor MySQL a mais de um endereço IP?

    • 8 respostas
  • Marko Smith

    Execute o script Oracle SQL e saia do sqlplus.exe via prompt de comando

    • 11 respostas
  • Martin Hope
    Sam McAfee Como posso dizer ao Apache qual PHP usar? 2008-12-23 18:15:17 +0800 CST
  • Martin Hope
    Rehan Como fechar um soquete à força em TIME_WAIT? 2008-09-04 04:57:26 +0800 CST
  • Martin Hope
    Nick Berardi Como você copia um disco rígido físico para um disco rígido virtual VMware? 2008-10-23 14:38:49 +0800 CST
  • Martin Hope
    Matt Sheppard Como despejar um banco de dados do Microsoft SQL Server em um script SQL? 2008-08-25 17:47:52 +0800 CST
  • Martin Hope
    Stu Como posso portar para frente com o iptables? 2008-12-06 13:06:59 +0800 CST
  • Martin Hope
    BlaM Como vincular o servidor MySQL a mais de um endereço IP? 2008-09-03 08:04:18 +0800 CST
  • Martin Hope
    JoshL Execute o script Oracle SQL e saia do sqlplus.exe via prompt de comando 2008-09-23 15:33:09 +0800 CST

Hot tag

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve