2013-01-13 33 views
5

名前付きパイプではじまり、2つのローカルプロセス間のIPCに使用する必要があります。私は、非ブロッキング・オーバーラップ・モードでパイプを使用するサーバーとクライアントの両方のプロセスを持っています。ノンブロッキングConnectNamedPipeイベントが通知されない

OVERLAPPED構造体を介してConnectNamedPipe()に渡されたイベントが、期待通りに通知されない(クライアントの接続時に通知される)ことを除いて、すべて正常に動作します(サーバーはクライアントから送信された文字列を受け取ります)。

サーバーがWaitForSingleObject()呼び出しでブロックされている間に、クライアントプロセスがパイプに接続し、データを送信して終了しましたが、イベントが通知されません。私は何が欠けていますか?

Serverコード:

HANDLE hPipe = ::CreateNamedPipeW(
    L"\\\\.\\pipe\\ThePipe", 
    PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 
    PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_NOWAIT, 
    1, 
    4096, 
    4096, 
    100, 
    nullptr); 

OVERLAPPED ov = {0}; 
ov.hEvent = ::CreateEventW(nullptr, TRUE, FALSE, nullptr); 

BOOL retVal = ::ConnectNamedPipe(hPipe, &ov); 

if (retVal == 0) 
{ 
    DWORD err = ::GetLastError(); 
    if (err == ERROR_IO_PENDING) 
    { 
     ::WaitForSingleObject(ov.hEvent, 30000); 
    } 
    if (err == ERROR_PIPE_LISTENING) 
    { 
     ::WaitForSingleObject(ov.hEvent, 30000); // this blocks until time-out??? 
    } 
} 
+0

ERROR_IO_PENDINGを受け取っていますか? (あなたはこのケースを分かりやすくするか、プロセスにアタッチしてどこに待つかを確認するのがよいでしょう) –

答えて

10

あなたはオーバーラップモードと一緒にPIPE_NOWAIT(非推奨)を使うべきではありません。 PIPE_NOWAITConnectNamedPipeは、クライアントが接続されていない場合はただちにERROR_PIPE_LISTENINGを返します。オーバーラップしたI/Oは起こりません。イベントを待つことは無駄です。

PIPE_NOWAITを設定し、パイプが成功するまで定期的にポーリングするか、FILE_FLAG_OVERLAPPEDを設定し、イベントを使用して完了を確認/待機します。

+1

問題を修正しました。どうもありがとうございます!マイクロソフトは実際にこれに関するドキュメントを更新する必要があります。 – links77

+0

CreateNamedPipeのMSDNページから: "ノンブロッキングモードはMicrosoft LAN Managerバージョン2.0との互換性のためにサポートされているので、名前付きパイプで非同期I/Oを実現するためには使用しないでください。 –

+0

非同期モードでConnectNamedPipeを使用しないことに関する警告があります。代わりに 'OVERLAPPED'構造体を' ReadFile'に渡して読み込みを待つことができます。 – Steve

関連する問題