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

名前付きパイプ クライアントは 、CreateFile 関数を使用して名前付きパイプへのハンドルを開きます。 パイプが存在していても、そのすべてのインスタンスがビジー状態の場合、 CreateFileINVALID_HANDLE_VALUE を返し、 GetLastError 関数はERROR_PIPE_BUSYを返します。 この場合、名前付きパイプ クライアントは WaitNamedPipe 関数を使用して、名前付きパイプのインスタンスが使用可能になるまで待機します。

サーバーがパイプを作成したときに、指定されたアクセスが指定されたアクセス (双方向、送信、または受信) と互換性がない場合、 CreateFile 関数は失敗します。 双方向パイプの場合、クライアントは読み取り、書き込み、または読み取り/書き込みアクセスを指定できます。送信パイプ (書き込み専用サーバー) の場合、クライアントは読み取り専用アクセスを指定する必要があります。受信パイプ (読み取り専用サーバー) の場合、クライアントは書き込み専用アクセスを指定する必要があります。

CreateFile によって返されるハンドルは、既定ではバイト読み取りモード、ブロック待機モード、重複モード無効、およびライトスルー モードが無効になっています。 パイプ クライアントは CreateFile を 使用して、FILE_FLAG_OVERLAPPEDを指定して重複モードを有効にしたり、FILE_FLAG_WRITE_THROUGHを指定して書き込みモードを有効にしたりできます。 クライアントは SetNamedPipeHandleState 関数を使用して、PIPE_NOWAITを指定して非ブロッキング モードを有効にしたり、PIPE_READMODE_MESSAGEを指定してメッセージ読み取りモードを有効にしたりできます。

次の例は、名前付きパイプを開き、パイプ ハンドルをメッセージ読み取りモードに設定し、 WriteFile 関数を使用してサーバーに要求を送信し、 ReadFile 関数を使用してサーバーの応答を読み取るパイプ クライアントを示しています。 このパイプ クライアントは、このトピックの下部に記載されているメッセージの種類のサーバーで使用できます。 ただし、バイト型サーバーでは、 SetNamedPipeHandleState を呼び出してメッセージ読み取りモードに変更すると、このパイプ クライアントは失敗します。 クライアントはメッセージ読み取りモードでパイプから読み取っているため、部分的なメッセージを読み取った後に ReadFile 操作で 0 を返すことができます。 これは、メッセージが読み取りバッファーよりも大きい場合に発生します。 このような場合、 GetLastError は ERROR_MORE_DATAを返し、クライアントは ReadFile の追加呼び出しを使用してメッセージの残りの部分を 読み取ることができます。

このパイプ クライアントは、[関連項目] の下に一覧表示されている任意のパイプ サーバーと共に使用できます。

#include <windows.h> 
#include <stdio.h>
#include <conio.h>
#include <tchar.h>

#define BUFSIZE 512
 
int _tmain(int argc, TCHAR *argv[]) 
{ 
   HANDLE hPipe; 
   LPTSTR lpvMessage=TEXT("Default message from client."); 
   TCHAR  chBuf[BUFSIZE]; 
   BOOL   fSuccess = FALSE; 
   DWORD  cbRead, cbToWrite, cbWritten, dwMode; 
   LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe"); 

   if( argc > 1 )
      lpvMessage = argv[1];
 
// Try to open a named pipe; wait for it, if necessary. 
 
   while (1) 
   { 
      hPipe = CreateFile( 
         lpszPipename,   // pipe name 
         GENERIC_READ |  // read and write access 
         GENERIC_WRITE, 
         0,              // no sharing 
         NULL,           // default security attributes
         OPEN_EXISTING,  // opens existing pipe 
         0,              // default attributes 
         NULL);          // no template file 
 
   // Break if the pipe handle is valid. 
 
      if (hPipe != INVALID_HANDLE_VALUE) 
         break; 
 
      // Exit if an error other than ERROR_PIPE_BUSY occurs. 
 
      if (GetLastError() != ERROR_PIPE_BUSY) 
      {
         _tprintf( TEXT("Could not open pipe. GLE=%d\n"), GetLastError() ); 
         return -1;
      }
 
      // All pipe instances are busy, so wait for 20 seconds. 
 
      if ( ! WaitNamedPipe(lpszPipename, 20000)) 
      { 
         printf("Could not open pipe: 20 second wait timed out."); 
         return -1;
      } 
   } 
 
// The pipe connected; change to message-read mode. 
 
   dwMode = PIPE_READMODE_MESSAGE; 
   fSuccess = SetNamedPipeHandleState( 
      hPipe,    // pipe handle 
      &dwMode,  // new pipe mode 
      NULL,     // don't set maximum bytes 
      NULL);    // don't set maximum time 
   if ( ! fSuccess) 
   {
      _tprintf( TEXT("SetNamedPipeHandleState failed. GLE=%d\n"), GetLastError() ); 
      return -1;
   }
 
// Send a message to the pipe server. 
 
   cbToWrite = (lstrlen(lpvMessage)+1)*sizeof(TCHAR);
   _tprintf( TEXT("Sending %d byte message: \"%s\"\n"), cbToWrite, lpvMessage); 

   fSuccess = WriteFile( 
      hPipe,                  // pipe handle 
      lpvMessage,             // message 
      cbToWrite,              // message length 
      &cbWritten,             // bytes written 
      NULL);                  // not overlapped 

   if ( ! fSuccess) 
   {
      _tprintf( TEXT("WriteFile to pipe failed. GLE=%d\n"), GetLastError() ); 
      return -1;
   }

   printf("\nMessage sent to server, receiving reply as follows:\n");
 
   do 
   { 
   // Read from the pipe. 
 
      fSuccess = ReadFile( 
         hPipe,    // pipe handle 
         chBuf,    // buffer to receive reply 
         BUFSIZE*sizeof(TCHAR),  // size of buffer 
         &cbRead,  // number of bytes read 
         NULL);    // not overlapped 
 
      if ( ! fSuccess && GetLastError() != ERROR_MORE_DATA )
         break; 
 
      _tprintf( TEXT("\"%s\"\n"), chBuf ); 
   } while ( ! fSuccess);  // repeat loop if ERROR_MORE_DATA 

   if ( ! fSuccess)
   {
      _tprintf( TEXT("ReadFile from pipe failed. GLE=%d\n"), GetLastError() );
      return -1;
   }

   printf("\n<End of message, press ENTER to terminate connection and exit>");
   _getch();
 
   CloseHandle(hPipe); 
 
   return 0; 
}

マルチスレッド パイプ サーバー

重複した I/O を使用する名前付きパイプ サーバー

完了ルーチンを使用した名前付きパイプ サーバー