停止しているがリッスンしているプロセスを強制終了するにはどうすればよいですか?


48

ポート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

私はそれを右クリックし、「ハンドルを閉じる」を選択しました。Process Explorerにはもうありませんが、netstatには表示されますが、それでもアプリがリスナーを開始するのを停止します。

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


患者を殺して病気を少し治しますが、コンピュータを再起動すると停止しますか?
Xantec

2
実際、ログアウトして再度ログインするだけで十分でしたが、今ではそれを再現することができたので、より良い解決策を見つけたいと思っています
...-Srekel

ここにリストさ ているプログラムのいずれかが役立つかどうかを確認してください
サティアジスバート

1
TCPView 3.05の現在のバージョンでは、<non-exsitent>プロセスのコンテキストメニューの[接続を閉じる]で、私の場合は接続が正常に閉じられ、ポートが解放されました。
ベンジークネフ

回答:


13

ソケットでの無限の待機を避けるために、プログラムは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. 

1
これは、この特定の問題(デッドプロセスによるソケットリスニング)の助けになりましたか?
rustyx

12

同じ問題があり、Microsoft SysinternalsのProcess Explorerを使用して、存在しないプロセスIDを検索しました。

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


7

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

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

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

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

代替テキスト


4
プロセス名「System」の下のリストに表示されます。アイテムを右クリックしてポートを強制的に閉じようとしましたが、何も起こりません。
-Srekel

7

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

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


1
おかげで、これは良いものでした。私はsubprocess.call(..., cwd=..., shell=True)python Webサーバーでアプリランチャーとして呼び出していましたが、ソケットを解放するためにすべての子プロセスを強制終了しなければならなかったことがわかりました。奇妙なことは、shell = Trueを使用していることです。これは何年も悩まされていました。
ダニエルF 14

シェルを使用すると、この動作になるとは思いません。親が死んだときにすべての子プロセスを終了したい場合、正しい方法はJOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSEフラグジョブオブジェクトを作成し、各子プロセスをAssignProcessToJobObjectで追加し、親プロセスが終了したときにハンドルが自然に閉じるようにすることだと思います。
qris


1

netstatコマンドで「-b」フラグをスローしてみてください。ポートを使用している実行可能ファイルの名前が表示されます。次に、タスクマネージャーでそのprocを見つけて、そこで削除します。それがうまくいかない場合は、ポートを開いたままにしている実行可能ファイルを投稿します。


現時点では再現できませんが、プロセスの名前を見つけようとする他のすべての試み(およびツール)が失敗したため、netstatもそれを行うことができなかったでしょう。
スレケル

1

ここで用語「リンガー」に言及する必要があります。

詳細はhttp://msdn.microsoft.com/en-us/library/ms739165.aspxで見つけることができます

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

C#アプリでは、Socket.SetSocketOptionを使用して関連オプションを指定できます:http ://msdn.microsoft.com/en-us/library/1011kecd.aspx

言及されているものはすべて送信とクライアントに関連しているので、作業中に同様の問題があったため、さらに検索すると、こちらの例に示すようにリスナーのlingerオプションを指定できることが明らかになりました:http : //msdn.microsoft.com /library/system.net.sockets.tcplistener.server.aspx

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


ポートはそれよりずっと長く開いたままでした(どのくらいの長さか覚えていませんが、あきらめてリブートするまでに最大1時間かかりました)。
Srekel

lingerオプションがこの特定のケースに関連するかどうかはわかりません。CloseSocketの呼び出し後に何が起こるかを指定するだけだからです。私はアプリケーションを殺しているので、その関数が呼び出されることを疑います(?)。
Srekel

1

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


1
:私はServerFaultの便利で、この答えを見つけserverfault.com/a/273727/8856
Harriv

1

xdebugでも同じ問題があり、ポート9000を開いたままにしました。

「taskkill / pid xxxx」を使用してcmdで終了しました。

ポートを使用するプロセスのPIDは、「netstat -o」で取得できます。

私の構成は、7ホームプレミアムを獲得しました。


1

私は同じ問題を抱えていて、それを修正しました:

  • とPIDを見つける netstat -o
  • プロセスXPで強制終了します

興味深いことに、netstatはpidを返すことがありますが、対応する実行可能ファイル名は返さないことがあります。


1

この問題は、デッドプロセスが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

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

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

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

> taskkill /f /pid 23828

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


0

ファイアウォールがインストールされているとは思わない(またはWindowsネットワーキングの週に何回か試した)

一部のファイアウォールはこのような動作を示し、ポートを開いたままにできます。

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


残念ながら、コンピュータのファイアウォールを制御できないため、実際にはオプションではありません。
スレケル

@Srekel-それは何のファイアウォールですか?あなたが問題を抱えているように、私は個人的にそれが問題を引き起こしていると思います。
ウィリアムヒルサム

0

プロセスはシステムとしてリストされているため、「システム」コマンドプロンプトでプロセスを強制終了できます。システムアカウントには、通常の管理者よりも多くの特権があります。

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

at 15:23 /interactive "cmd.exe" 

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


0

同じ問題がありました。プロセスはクラッシュ中にデバッグされていましたが、まだ中断された状態のvsjitdebugger.exeプロセスが残っており、明らかにデバッグされているプロセスを指していました。そのvsjitdebugger.exeプロセスを終了することで問題は解決しました。


0

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.