none
Windowsの名前付きパイプの接続エラーについて RRS feed

  • 質問

  • 同じマシン上におけるタスク間通信で名前付きパイプの非待機型を使用しようと思うのですが、CreateNamedPipeの引数にPIPE_NOWAITを指定すると、ConnectNamedPipe()でエラーが返ってきます(詳細コードはパイプ接続エラーの意味で参考になりません)。このとき、別タスクではパイプのオープンには成功しています。

    ただし、それ以降の動作上としては何の問題もなく、データの通信ができます。

    非待機型でのConnectNamedPipe()の扱いはどうすればよいのでしょうか?無視してもよい?

    よくわからないので、オーバーラップトのシグナルONを待ちましたが、永遠にタイムアウトです。

    PIPE_WAITにすれば接続は正常終了するのですが、永遠に待機というのは、常駐タスクなので危険なような気がするのですが、実際のところどうなのでしょうか。

    コードは次のようなものです。

    【タスクA】
        HANDLE      ssnpPipe ;
        DWORD       succ ;
        OVERLAPPED  Overlapped;
        DWORD       Status ;

        ssnpPipe = CreateNamedPipe( "\\\\.\\pipe\\ran\\ssnp",
                                    PIPE_ACCESS_DUPLEX,
                                    PIPE_TYPE_BYTE | PIPE_NOWAIT,
                                    1,
                                    0,
                                    0,
                                    150,
                                    (LPSECURITY_ATTRIBUTES)NULL ) ;

        if (ssnpPipe == INVALID_HANDLE_VALUE) {
            printf("名前付きパイプの作成に失敗しました。\n") ;
            return -1 ;
        }

        ZeroMemory(&Overlapped,sizeof(Overlapped));
        Overlapped.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
        if ( Overlapped.hEvent==NULL ) {
                printf("Unable to create Event Object\n");
                return -1;
        }

        if (!ConnectNamedPipe(ssnpPipe, &Overlapped)) {
            printf( "名前付きパイプへの接続に失敗しました。\n") ;
            Status = GetLastError();

      while ( WaitForSingleObject(Overlapped.hEvent,10000) == WAIT_TIMEOUT );

            // operation completed, get final status
            succ = GetOverlappedResult(
                                ssnpPipe,
                                &Overlapped,
                                &BytesTransferred,  // number of bytes read
                                FALSE               // do not wait for completion
                  ) ;
            if ( succ ) {
             printf( "名前付きパイプへの接続に成功しました。\n") ;
      }
      else {
          printf( "名前付きパイプへの接続に失敗しました。\n") ;
      }

    【タスクB】
        ssnpPipe = CreateFile( "\\\\.\\pipe\\ran\\ssnp",//pipeName,
                               GENERIC_READ | GENERIC_WRITE,
                               FILE_SHARE_READ,
                               (LPSECURITY_ATTRIBUTES)NULL,
                               OPEN_EXISTING,
                               FILE_ATTRIBUTE_NORMAL,
                               (HANDLE)NULL);

        if (ssnpPipe == INVALID_HANDLE_VALUE) {
            printf("名前付きパイプのファイルハンドルの作成に失敗しました。\n") ;
            return -1 ;
        }
            printf("名前付きパイプのファイルハンドルの作成に成功しました。\n") ;

    2009年7月1日 3:35

回答

  • MSDNをみると、CreateNamedPipeのdwPipeModeの説明に以下の記述があります。

    「ノンブロッキングモードは、Microsoft LAN Lanager 2.0 との互換性を保つ目的でサポートされています。
    名前付きパイプで非同期入出力(I/O)を行うために使うことは避けてください。
    非同期のパイプ I/O の詳細については、MSDN ライブラリの「Synchronous and Overlapped Input and Output」を参照してください。」

    この記述からするとそもそもPIPE_NOWAITを使う事が間違いなのでは?
    という気がします。

    解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。
    • 回答としてマーク sk7474 2009年7月21日 9:05
    2009年7月1日 7:33
  • 次の URL の説明によると、

     Named Pipe Type, Read, and Wait Modes (Windows)
     http://msdn.microsoft.com/en-us/library/aa365605(VS.85).aspx

    ConnectNamedPipe の説明に、

     With a nonblocking-wait handle, the connect operation returns zero immediately, and the GetLastError function returns ERROR_PIPE_LISTENING.

    とあるので、エラーが返ってくるのは狙い通りのようです。

    一般的な方法はよく分かりませんが、例えば ConnectNamedPipe を別スレッドにやらせるとかするんでしょうか。

    • 回答としてマーク sk7474 2009年7月21日 9:05
    2009年7月1日 7:53

すべての返信

  • MSDNをみると、CreateNamedPipeのdwPipeModeの説明に以下の記述があります。

    「ノンブロッキングモードは、Microsoft LAN Lanager 2.0 との互換性を保つ目的でサポートされています。
    名前付きパイプで非同期入出力(I/O)を行うために使うことは避けてください。
    非同期のパイプ I/O の詳細については、MSDN ライブラリの「Synchronous and Overlapped Input and Output」を参照してください。」

    この記述からするとそもそもPIPE_NOWAITを使う事が間違いなのでは?
    という気がします。

    解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。
    • 回答としてマーク sk7474 2009年7月21日 9:05
    2009年7月1日 7:33
  • 次の URL の説明によると、

     Named Pipe Type, Read, and Wait Modes (Windows)
     http://msdn.microsoft.com/en-us/library/aa365605(VS.85).aspx

    ConnectNamedPipe の説明に、

     With a nonblocking-wait handle, the connect operation returns zero immediately, and the GetLastError function returns ERROR_PIPE_LISTENING.

    とあるので、エラーが返ってくるのは狙い通りのようです。

    一般的な方法はよく分かりませんが、例えば ConnectNamedPipe を別スレッドにやらせるとかするんでしょうか。

    • 回答としてマーク sk7474 2009年7月21日 9:05
    2009年7月1日 7:53
  • こんにちは。中川俊輔です。

    PATIOさん、totojoさん、回答ありがとうございます。

    clematis0401さん、フォーラムのご利用ありがとうございます。
    その後いかがでしょうか?疑問は解決しましたか?
    有用な情報と思われたため、PATIOさん、totojoさんの回答へ回答マークをつけさせていただきました。

    今後ともフォーラムをよろしくお願いします。
    それでは!
    マイクロソフト株式会社 フォーラム オペレータ 中川 俊輔
    2009年7月21日 9:10