10

私は名前付きパイプについて学び、MSDNドキュメントの名前付きパイプクライアントとサーバーの例で遊んでいました。

名前付きパイプサーバー

名前付きパイプクライアント

クライアントを変更して、コンソールにメッセージを入力し、サーバーに送信してメッセージを表示し、返信を返すようにしました。基本的に、SetNamedPipeHandleState()呼び出しの後に開始し、CloseHandle()呼び出しの前に終了するループを追加しました(つまり、開閉はループの外側で発生するため、ループ内で同じパイプハンドルを使用しています)。

私の質問は、クライアントを(クライアントを閉じるか、タスクマネージャーを介して終了することによって)強制終了した場合、サーバー側が切断を検出する方法はありますか?

GetNamedPipeHandleState()を使用して失敗を返し、GetLastError()を呼び出すとERROR_PIPE_NOT_CONNECTEDが返されることを期待してみましたが、そうではありませんでした。このサーバーの設定方法が原因で、CompletedReadRoutine関数でこれを実行し、「制御された」障害を作成する必要がありました。私がしたことは、サーバーのCompletedReadRoutineにブレークポイントを設定することでした。

  1. サーバーを起動しました
  2. クライアントを開始しました
  3. クライアント経由でメッセージを送信しました(ここでサーバーのブレークポイントにヒットします)
  4. クライアントを殺した
  5. GetNamedPipeHandleStateにステップスルーしました

GetNamedPipeHandleState()の呼び出しは正常に返されるため、GetLastError()の呼び出しを行う必要はありません。WriteFileEx呼び出しに到達すると失敗し、その時点でGetLastErrorを呼び出すとERROR_NO_DATAが返されます。

パイプ関数を見ると、ここで役立つ可能性のあるものは他にありません。何かが足りないか、クライアントの切断が検出されないだけです。

私が考えることができる他の唯一のことは、接続しているクライアントのpidを(GetNamedPipeClientProcessIdを介して)収集し、ウォッチドッグスレッドをスピンオフして、それらがまだ生きているかどうかを確認することです。とはいえ、そうすることを考えるだけで、私のスパイダーマンの感覚が失われます。

名前付きパイプを使用しているときに切断されたクライアントを検出する方法はありますか?

4

2 に答える 2

8

ReadFile()戻ってエラーしてGetLastError()から戻ってこないのERROR_BROKEN_PIPEですか?

于 2010-03-04T06:07:41.863 に答える
1

ReadFile()+GetLastError()仕事をうまくやりなさい。これらをI/O完了ポートで使用する方法は次のとおりです(私の実装はpython + ctypesですが、アイデアは明確である必要があります)。

def connect():
    GetQueuedCompletionStatus()
    receive()

def receive():
    while True:
        ret_code = ReadFile()
        if ret_code == 0 and GetLastError() == ERROR_BROKEN_PIPE:
            # client disconnected
        GetQueuedCompletionStatus()

完了パケットを待っており、クライアントが接続すると、メインループに切り替わります。ReadFile()メインループでは、パイプを読み取り、リターンコードとを調べてクライアントが切断されているかどうかを確認しますGetLastError()。次に、完了パケットを待ちます。

クライアントはどの段階でも切断できます。完了パケットはキューに入れられ、取得されますERROR_BROKEN_PIPE

于 2016-06-05T20:09:16.740 に答える