it-swarm.com.de

Wie kann ich einen Prozess beenden, der tot ist, aber zuhört?

Ich entwickle eine App, die auf Port 3000 lauscht. Anscheinend hört eine Instanz den Port immer noch ab, da beim Starten kein Listener erstellt werden kann (C #, TcpListener, aber das ist irrelevant), da der Port bereits vorhanden ist genommen.

Da die App im Task-Manager nicht vorhanden ist, habe ich versucht, ihre PID zu finden und sie zu beenden. Dies führte zu folgendem interessanten Ergebnis:

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.

Ich habe dieses Verhalten noch nie gesehen und dachte, es sei interessant genug, um zu sehen, ob jemand eine Lösung hat.

UPDATE: Ich habe Process Explorer gestartet und nach 3000 gesucht und Folgendes gefunden:

<Non-existent Process>(3000): 5552

Ich habe mit der rechten Maustaste darauf geklickt und "Close Handle" gewählt. Es befindet sich nicht mehr im Prozess-Explorer, wird jedoch weiterhin in netstat angezeigt und verhindert, dass die App den Listener startet.

UPDATE 2: Es wurde TCPView für Windows gefunden, das den Prozess als "<non-existent>" anzeigt. Wie bei CurrPorts passiert nichts, wenn ich versuche, die Verbindung in diesem Tool zu schließen.

45
Srekel

Um endlose Wartezeiten am Socket zu vermeiden, sollte Ihr Programm die Funktion setsockopt mit den Parametern SO_REUSEADDR und SO_RCVTIMEO verwenden:

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. 
13
harrymc

Wir hatten das gleiche Problem und haben den Process Explorer von Microsoft Sysinternals verwendet, um die nicht mehr vorhandene Prozess-ID zu ermitteln.

Es stellte sich heraus, dass der Prozess von mehreren DrWatson-Prozessen referenziert wurde. Durch das Beenden dieser Prozesse wurde der Port freigegeben. DrWatson wird zum Senden von Speicherabbildern an Microsoft verwendet. Dies dauerte mehrere Stunden, da der abgestürzte Prozess zu diesem Zeitpunkt mehrere zehn GB Speicher enthielt.

12
David

Das wahrscheinliche Problem ist, dass Ihr Prozess einen anderen (untergeordneten) Prozess gestartet hat, der das Socket-Handle geerbt hat und noch ausgeführt wird.

Es gibt verschiedene Möglichkeiten, dies zu verhindern, zum Beispiel: ProcessStartInfo.UseShellExecute = true;

7
Nick Westgate

Ich denke, Sie sollten CurrPorts ausprobieren

CurrPorts ist eine Netzwerküberwachungssoftware, die eine Liste aller derzeit auf Ihrem lokalen Computer geöffneten TCP/IP- und UDP-Ports anzeigt. Für jeden Port in der Liste werden auch Informationen zu dem Prozess angezeigt, der den Port geöffnet hat, einschließlich des Prozessnamens, des vollständigen Pfads des Prozesses, der Versionsinformationen des Prozesses (Produktname, Dateibeschreibung usw.) sowie der Uhrzeit Der Prozess wurde erstellt und der Benutzer, der ihn erstellt hat.

Darüber hinaus können Sie mit CurrPorts unerwünschte TCP Verbindungen schließen, den Prozess beenden, der die Ports geöffnet hat, und die TCP/UDP-Portinformationen in einer HTML-Datei, einer XML-Datei oder in speichern tabulatorgetrennte Textdatei.

CurrPorts markiert auch verdächtige TCP/UDP-Ports, die nicht identifizierten Anwendungen gehören, automatisch mit rosa Farbe (Anwendungen ohne Versionsinformationen und Symbole)

alt text

7
Sathyajith Bhat

Hier muss der Begriff verweilen erwähnt werden.

Details finden Sie unter http://msdn.Microsoft.com/en-us/library/ms739165.aspx

Kurz gesagt: Es gibt eine Option, die das Socketsystem anweist, einen Socket auch nach dem Schließen offen zu halten, wenn nicht gesendete Daten vorhanden sind.

In Ihrer C # -App können Sie alle zugehörigen Optionen über Socket.SetSocketOption angeben: http://msdn.Microsoft.com/en-us/library/1011kecd.aspx

Da sich alle erwähnten Dinge auf das Senden und die Clients beziehen, wir jedoch ähnliche Probleme hatten, wurde bei einigen weiteren Suchvorgängen festgestellt, dass man die Verweildaueroption für die Hörer wie im folgenden Beispiel angeben kann: http://msdn.Microsoft.com/library/system.net.sockets.tcplistener.server.aspx

Einige Kollegen sprachen über Ports, die vom Betriebssystem nach dem Beenden/Schließen der Anwendung für etwa zwei Minuten gehalten werden. In Anbetracht dessen wäre es interessant zu hören, ob der Hafen nach einer gewissen Zeit noch gehalten wird.

1
Andreas

Ich hatte das gleiche Problem und habe es behoben durch:

  • finden der PID mit netstat -o
  • Töte es mit process xp

Interessanterweise kann netstat manchmal eine pid zurückgeben, jedoch nicht den entsprechenden Namen der ausführbaren Datei!

1
eka808

Können Sie den Prozess in Process Explorer sehen? Wenn ja, können Sie es von dort aus töten, aber erst, nachdem Sie untersucht haben, was es tatsächlich ist (Sie können alle in den Prozess geladenen DLLs sehen).

1
Jakub Konecki

Ich stoße auch auf dieses Problem. Endlich habe ich meinen Grund gefunden. Es wird durch den Hauptprozess verursacht, der in c/c ++ durch das Öffnen eines untergeordneten Prozesses aufgerufen wird. Aber der Hauptprozess stürzt ab/fährt herunter, bevor pclose aufgerufen wird. Dann wird der Port den Hauptprozess noch live behandeln und noch darauf lauschen.

1
lorry.lee

ein ähnliches Problem wurde festgestellt, als als die Hauptursache ein untergeordneter Prozess war, der die Ports erbte. Der übergeordnete Prozess stürzte ab, während der untergeordnete Prozess den Port noch hielt. Die Lösung bestand darin, den noch ausgeführten untergeordneten Prozess zu identifizieren und anzuhalten. In diesem Beispiel war die nicht vorhandene Prozess-PID 7336

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

So beenden Sie diesen Prozess:

> taskkill /f /pid 23828

Und das löste das Problem.

1
Michael

Ich hatte das gleiche Problem mit xdebug, es ließ Port 9000 offen.

Ich habe es geschafft, mit cmd mit "taskkill/pid xxxx" zu schließen.

Die PID des Prozesses, der den Port verwendet, kann mit "netstat -o" abgerufen werden.

Meine Konfiguration war Win 7 Home Premium.

1
Christoforos

Versuchen Sie, ein '-b'-Flag in Ihrem netstat-Befehl zu setzen. Hier erfahren Sie den Namen der ausführbaren Datei, die den Port verwendet. Dann finde diesen Proc im Task-Manager und töte ihn dort. Wenn das nicht funktioniert, wird der Port durch die ausführbare Datei offen gehalten.

1
Ge3ng

Das Problem kann verursacht werden, wenn der tote Prozess einen oder mehrere untergeordnete Prozesse gestartet hat. Ob

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
);

wurde zum Starten eines untergeordneten Prozesses verwendet, hängt dies vom Wert der Vererbungspunkte ab, also mit

bInheritHandles = false 

Windows blockiert den Port nicht, wenn der übergeordnete Prozess gestoppt ist und der Clientprozess noch ausgeführt wird.

1
V15I0N

Ich nehme nicht an, dass Sie eine Firewall installiert haben (oder Windows-Netzwerkwochen ausprobiert haben)?

Einige Firewalls weisen dieses Verhalten auf und können Ports offen halten.

Wenn Sie eines haben, deaktivieren Sie es und starten Sie dann Ihr Programm, schließen Sie es und sehen Sie, was passiert.

0
William Hilsum

Ich hatte das gleiche Problem. Der Prozess wurde debuggt, während er abstürzte, und es gab immer noch einen vsjitdebugger.exe-Prozess in einem angehaltenen Zustand, der anscheinend auf den Prozess verwies, der debuggt wurde. Das Problem wurde durch das Beenden dieses vsjitdebugger.exe-Prozesses behoben.

0
gpvos

Da Ihr Prozess als System aufgeführt ist, können Sie ihn höchstwahrscheinlich an einer Eingabeaufforderung "System" beenden. Das Systemkonto verfügt über mehr Berechtigungen als ein regulärer Administrator.

Sie können "System" cmd.exe erhalten, indem Sie einen Task für cmd.exe einplanen (der Scheduler wird als System ausgeführt):

at 15:23 /interactive "cmd.exe" 

Ändern Sie diese Zeit für etwas in naher Zukunft. Stellen Sie auch sicher, dass Sie sich auf der Computerkonsole befinden (wenn Sie sich in einer regulären Terminalserversitzung befinden, wird die neue Datei cmd.exe nicht angezeigt. Melden Sie sich als mstsc bei der Konsole an). Ich denke, es gibt andere Möglichkeiten, das zu tun, aber das hat in der Vergangenheit für mich funktioniert.

0
David Suarez

Eine hybride Verwendung von TCPView und Process Explorer hat bei mir funktioniert;) Ich habe zuerst nach der Prozess-ID gesucht, die den Port in TCPView verwendet hat. Isolierte den Prozess im Prozess-Explorer und beendete ihn mit dem Prozess-Explorer.

0