web-dev-qa-db-ja.com

死んでいるが聞いているプロセスをどのようにして殺すのですか?

ポート3000をリッスンするアプリを開発しています。起動してもリスナーを作成できないため、インスタンスがまだポートをリッスンしているようです(C#、TcpListener、ただし無関係です)。取った。

今、アプリはタスクマネージャに存在しないので、私はそのPIDを見つけてそれを殺そうとしましたが、この興味深い結果につながりました:

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.

私は前にこの振る舞いを見たことがなく、誰かが解決策を持っているかどうかを確認するのに十分おもしろいと考えました。

アップデート:私はProcess Explorerを起動し、3000を検索しましたが、これが見つかりました:

<Non-existent Process>(3000): 5552

私はそれを右クリックして "Close Handle"を選びました。 Process Explorerではなくなりましたが、それでもnetstatに表示され、アプリによるリスナーの起動が停止されます。

更新2:プロセスを"<non-existent>"として表示する TCPView for Windows が見つかりました。 CurrPortsと同様に、このツールで接続を閉じようとしても何も起こりません。

45
Srekel

ソケットでの無限の待機を避けるために、あなたのプログラムはSO_REUSEADDRとSO_RCVTIMEOパラメータで setsockopt関数 を使うべきです:

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

同じ問題があり、Microsoft Sysinternalsの Process Explorer を使用して、存在しなくなったプロセスIDを調べます。

そのプロセスがいくつかのDrWatsonプロセスによって参照されていたことがわかります。それらのプロセスを強制終了するとportが解放されました。 DrWatsonはMicrosoftへのメモリダンプの送信に使用されていましたが、クラッシュしたプロセスがその時点で数十GBのメモリを保持していたため、これには数時間かかりました。

12
David

考えられる問題は、あなたのプロセスがソケットハンドルを継承した別の(子)プロセスを開始し、それがまだ実行中であるということです。

これを防ぐには、さまざまな方法があります。例えば、 ProcessStartInfo.UseShellExecute = true;

7
Nick Westgate

CurrPorts を試してみるべきだと思う

CurrPortsは、ローカルコンピュータで現在開かれているすべてのTCP/IPおよびUDPポートのリストを表示するネットワーク監視ソフトウェアです。リスト内の各ポートについて、ポートを開いたプロセスに関する情報(プロセス名、プロセスのフルパス、プロセスのバージョン情報(製品名、ファイルの説明など))も表示されます。プロセスが作成され、それを作成したユーザー。

さらに、CurrPortsでは、不要なTCP接続を閉じ、ポートを開いたプロセスを終了し、TCP/UDPポート情報をHTMLファイル、XMLファイル、またはタブ区切りテキストファイル

CurrPortsはまた、身元不明のアプリケーションが所有する不審なTCP/UDPポートを自動的にピンク色でマークします(バージョン情報とアイコンがないアプリケーション)。

alt text

7
Sathyajith Bhat

ここでlingerという用語に言及する必要があります。

詳細は http://msdn.Microsoft.com/ja-jp/library/ms739165.aspx にあります。

簡単に言うと、未送信のデータが存在する場合にソケットが閉じられた後でもソケットを開いたままにするようにソケットシステムに指示するオプションがあります。

C#アプリでは、Socket.SetSocketOptionを介して関連オプションを指定できます。 http://msdn.Microsoft.com/ja-jp/library/1011kecd.aspx

ここに挙げたものはすべて送信とクライアントに関するものですが、同様の問題がありました。さらに検索した結果、上の例に示すようにリスナーにlingerオプションを指定できることがわかりました。 http://msdn.Microsoft.com/library/system.net.sockets.tcplistener.server.aspx

同僚の中には、アプリケーションの終了/終了後に約2分間OSがポートを保持していると語った。それを考えると、ポートが一定時間後にまだ保留されているかどうかを聞くのは面白いでしょう。

1
Andreas

私は同じ問題を抱えていて、それによってそれを直しました:

  • netstat -oでPIDを見つける
  • プロセスXPでそれを殺す

Netstatは時々pidを返すことができますが、対応する実行ファイル名を返さないことに注意してください

1
eka808

あなたはProcess Explorerでプロセスを見ることができますか?もしそうであれば、そこからそれをkillすることができますが、実際にそれが何であるかを調べた後に限ります(あなたはプロセスに読み込まれたすべてのdllを見ることができます)

1
Jakub Konecki

私もこの問題に遭遇しました。ついに私は自分の理由を見つけた。これは、メインプロセスがc/c ++でpopenによって子プロセスを呼び出したことが原因です。しかし、pcloseを起動する前にメインプロセスがクラッシュ/シャットダウンします。それから、portはまだメインプロセスを処理し、まだそれを監視します。

1
lorry.lee

根本的な原因がいくつかの子プロセスがポートを継承して作成され、子プロセスがまだポートを保持している間に親プロセスがクラッシュしたときに同様の問題が発生しました。解決策は、まだ実行中の子プロセスを識別して停止することでした。この例では、存在しないプロセスPIDは7336でした。

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

このプロセスを停止するには

> taskkill /f /pid 23828

そしてこれで問題は解決しました。

1
Michael

私はxdebugと同じ問題を抱えていました、それはポート9000を開いたままにしました。

私は "taskkill/pid xxxx"を使ってcmdで閉じることができました。

ポートを使用しているプロセスのpidは、 "netstat -o"で取得できます。

私の設定は7ホームプレミアムを獲得しました。

1
Christoforos

Netstatコマンドに '-b'フラグを付けてみてください。ポートを使用している実行可能ファイルの名前がわかります。それからタスクマネージャでそのprocを見つけて、そこで殺してください。それでもうまくいかない場合は、実行可能ファイルがポートを開いたままにしているものを投稿してください。

1
Ge3ng

問題は、停止したプロセスが1つ以上の子プロセスを開始した場合に発生する可能性があります。もし

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

子プロセスを起動するために使用されていましたが、継承ハンドルの値に依存します。

bInheritHandles = false 

親プロセスが停止し、クライアントプロセスがまだ実行中の場合、Windowsはポートをブロックしません。

1
V15I0N

ファイアーウォールがインストールされているとは思いませんか(または、Windowsのネットワーク機能を試してみたか)。

ファイアウォールの中には、このような動作をするものがあり、ポートを開いたままにしておくことができます。

持っている場合は、それを無効にしてからプログラムを起動して閉じ、何が起こるかを確認してください。

0
William Hilsum

私はこれと同じ問題を抱えていました。プロセスはクラッシュしている間にデバッグされていましたが、まだ中断された状態のvsjitdebugger.exeプロセスが残っていました。 vsjitdebugger.exeプロセスを強制終了すると、問題が解決しました。

0
gpvos

あなたのプロセスはシステムとしてリストされているので、たぶんあなたは "システム"コマンドプロンプトでそれを殺すことができます。システムアカウントには、通常の管理者よりも多くの権限があります。

Cmd.exeのタスクをスケジュールすることで "System" cmd.exeを取得できます(スケジューラはSystemとして実行されます)。

at 15:23 /interactive "cmd.exe" 

近い将来に何かのためにその時間を変更してください。マシンコンソールにいることも確認してください(通常のターミナルサーバーセッションにいる場合は、新しいcmd.exeは表示されません。コンソールにmstscログインします)。他にも方法があると思いますが、これは過去には私にとって役に立ちました。

0
David Suarez

TCPViewとProcess Explorerのハイブリッド使用は私のために働きました;)私は最初にTCPViewでポートを使用していたプロセスIDを調べました。 Process Explorerでプロセスを分離し、Process Explorerを使用してプロセスを強制終了しました。

0