Como faço para matar um processo que está morto mas escutando?

43

Estou desenvolvendo um aplicativo que escuta na porta 3000. Aparentemente, há uma instância dele ainda ouvindo a porta, porque sempre que eu a inicio, não consigo criar um ouvinte (C #, TcpListener, mas isso é irrelevante) porque a porta já está ocupada.

Agora, o aplicativo não existe no Gerenciador de Tarefas, então tentei encontrar seu PID e eliminá-lo, o que levou a um resultado interessante:

C:\Users\username>netstat -o -n -a | findstr 0.0:3000
   TCP    0.0.0.0:3000           0.0.0.0:0              LISTENING       3116

C:\Users\username>taskkill /F /PID 3116
ERROR: The process "3116" not found.

Eu não vi esse comportamento antes e percebi que era interessante o suficiente para ver se alguém tem uma solução.

UPDATE: Eu iniciei o Process Explorer e fiz uma pesquisa para 3000 e encontrei isto:

<Non-existent Process>(3000): 5552

Cliquei com o botão direito e escolhi "Close Handle". Não está mais no Process Explorer, mas ainda aparece no netstat e ainda impede que o aplicativo inicie o ouvinte.

UPDATE 2: Encontrado TCPView para Windows que mostra o processo como "<non-existent>" . Como acontece com CurrPorts, nada acontece quando tento fechar a conexão nesta ferramenta.

    
por Srekel 26.11.2010 / 16:24

16 respostas

13

Para evitar intermináveis esperas no soquete, seu programa deve usar a função setsockopt com os parâmetros SO_REUSEADDR e SO_RCVTIMEO:

SO_REUSEADDR : Allows the socket to be bound to an address that is already in use.
SO_RCVTIMEO : Sets the timeout, in milliseconds, for blocking receive calls. 
    
por 29.11.2010 / 20:09
11

Tivemos o mesmo problema e usamos o Process Explorer da Microsoft Sysinternals para consultar o processo ID que não existia mais.

Acontece que o processo foi referenciado por vários processos do DrWatson. Matar esses processos liberou a porta. O DrWatson é usado para enviar despejos de memória para a Microsoft e isso levava várias horas porque o processo que travou continha várias dezenas de GB de memória no momento.

    
por 26.07.2012 / 13:49
7

Acho que você deve dar CurrPorts uma tentativa

CurrPorts is network monitoring software that displays the list of all currently opened TCP/IP and UDP ports on your local computer. For each port in the list, information about the process that opened the port is also displayed, including the process name, full path of the process, version information of the process (product name, file description, and so on), the time that the process was created, and the user that created it.

In addition, CurrPorts allows you to close unwanted TCP connections, kill the process that opened the ports, and save the TCP/UDP ports information to HTML file , XML file, or to tab-delimited text file.

CurrPorts also automatically mark with pink color suspicious TCP/UDP ports owned by unidentified applications (Applications without version information and icons)

    
por 27.11.2010 / 02:44
5

O provável problema é que seu processo iniciou outro processo (filho) que herdou o identificador de soquete e ainda está em execução.

Existem várias maneiras de evitar isso, por exemplo: ProcessStartInfo.UseShellExecute = verdade;

    
por 18.04.2012 / 07:56
1

Você pode ver o processo em Process Explorer ? Se sim, você pode matá-lo de lá, mas somente depois de investigar o que realmente é (você pode ver todas as dlls carregadas no processo)

    
por 26.11.2010 / 16:35
1

Tente lançar um sinalizador '-b' no seu comando netstat. Ele informará o nome do executável que está usando a porta. Em seguida, encontrar esse proc no gerenciador de tarefas e matá-lo lá. Se isso não funcionar, poste o que é o executável que está mantendo a porta aberta.

    
por 30.11.2010 / 16:10
1

Precisa mencionar o termo atrasar aqui.

Detalhes podem ser encontrados no link

Em resumo: Há uma opção que informa ao sistema de soquete para manter um soquete aberto mesmo depois de ter sido fechado se dados não enviados estiverem presentes.

Em seu aplicativo C #, você pode especificar quaisquer opções relacionadas por meio do Socket.SetSocketOption: link

Como todas as coisas mencionadas estão relacionadas ao envio e aos clientes, mas tivemos problemas semelhantes no trabalho, algumas pesquisas adicionais revelaram que se poderia especificar a opção linger para os ouvintes, conforme mostrado no exemplo aqui: link

Alguns colegas falaram sobre as portas sendo mantidas pelo SO após o término / encerramento do aplicativo por cerca de dois minutos. Dado isso, seria interessante ouvir se a porta ainda é mantida após um certo período de tempo.

    
por 02.12.2010 / 00:13
1

Eu também encontro esse problema. Finalmente encontrei meu motivo. É causado pelo processo principal chamado um processo filho por popen em c / c ++. Mas o principal processo de falha / desligamento antes de invocar pclose. Então a porta tratará o processo principal ainda vivo e ainda o ouvirá.

    
por 16.07.2012 / 10:09
1

Eu tive o mesmo problema com o xdebug, ele deixou a porta 9000 aberta.

Eu consegui fechar com cmd usando "taskkill / pid xxxx".

O pid do processo usando a porta pode ser recuperado com "netstat -o".

Minha configuração foi win 7 home premium.

    
por 04.01.2013 / 12:35
1

Eu tive o mesmo problema e consertei por:

  • encontrar o PID com netstat -o
  • Mate-o com o processo xp

Interessante notar que o netstat pode algumas vezes retornar um pid mas não o nome executável correspondente!

    
por 10.03.2015 / 15:54
1

O problema pode ser causado se o processo inativo tiver iniciado um ou mais processos filhos. Se

BOOL WINAPI CreateProcess(
_In_opt_    LPCTSTR               lpApplicationName,
_Inout_opt_ LPTSTR                lpCommandLine,
_In_opt_    LPSECURITY_ATTRIBUTES lpProcessAttributes,
_In_opt_    LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_        BOOL                  bInheritHandles,
_In_        DWORD                 dwCreationFlags,
_In_opt_    LPVOID                lpEnvironment,
_In_opt_    LPCTSTR               lpCurrentDirectory,
_In_        LPSTARTUPINFO         lpStartupInfo,
_Out_       LPPROCESS_INFORMATION lpProcessInformation
);

foi usado para iniciar um processo filho, depende do valor de herdar alças, portanto, com

bInheritHandles = false 

O Windows não bloqueará a porta se o processo pai for interrompido e o processo do cliente ainda estiver em execução.

    
por 16.06.2015 / 18:11
0

Eu não suponho que você tenha um firewall instalado (ou tentou qualquer tweek de rede do Windows)?

Alguns firewalls exibem esse tipo de comportamento e podem manter as portas abertas.

Se você tiver um, tente desabilitá-lo e, em seguida, iniciar o programa e fechá-lo e ver o que acontece.

    
por 02.12.2010 / 00:17
0

Como o seu processo está listado como Sistema, é mais provável que você possa eliminá-lo em um prompt de comando "Sistema". A conta do sistema tem mais privilégios do que um administrador regular.

Você pode obter o cmd.exe "System" agendando uma tarefa para cmd.exe (o agendador é executado como System):

at 15:23 /interactive "cmd.exe" 

Altere esse tempo para algo no futuro próximo. Certifique-se também de estar no console da máquina (se você estiver em uma sessão regular do servidor de terminal, não verá o novo cmd.exe. Faça mstsc login no console). Eu acho que existem outras maneiras de fazer isso, mas isso funcionou para mim no passado.

    
por 18.05.2011 / 15:41
0

Eu tive esse mesmo problema. O processo estava sendo depurado enquanto ele travava, e ainda havia um processo de vsjitdebugger.exe em um estado suspenso, que aparentemente se referia ao processo sendo depurado. Matar esse processo vsjitdebugger.exe resolveu o problema.

    
por 03.04.2014 / 16:23
0

Um uso híbrido do TCPView e do Process Explorer funcionou para mim;) Primeiro, examinei o ID do processo que estava usando a porta no TCPView. Isolou o processo no Process Explorer e eliminou o processo usando o Process Explorer.

    
por 02.07.2015 / 11:51
0

viu um problema semelhante quando a causa raiz foi um processo filho criado herdando as portas, o processo pai travou, enquanto o processo filho ainda mantinha a porta. A resolução foi para identificar o processo filho ainda em execução e pará-lo. No exemplo aqui, o PID do processo não existente era 7336

> wmic process get processid,parentprocessid | findstr/i 7336
7336             23828

Para parar este processo:

> taskkill /f /pid 23828

E isso resolveu o problema.

    
por 11.02.2018 / 12:10