Condividi tramite


Client pipe denominato

Un client pipe denominato usa la funzione CreateFile per aprire un handle a una pipe denominata. Se la pipe esiste ma tutte le istanze sono occupato, CreateFile restituisce INVALID_HANDLE_VALUE e la funzione GetLastError restituisce ERROR_PIPE_BUSY. In questo caso, il client di pipe denominata usa la funzione WaitNamedPipe per attendere che un'istanza della pipe denominata diventi disponibile.

La funzione CreateFile non riesce se l'accesso specificato non è compatibile con l'accesso specificato (duplex, in uscita o in ingresso) quando il server ha creato la pipe. Per una pipe duplex, il client può specificare l'accesso in lettura, scrittura o lettura/scrittura; per una pipe in uscita (server di sola scrittura), il client deve specificare l'accesso di sola lettura; e per una pipe in ingresso (server di sola lettura), il client deve specificare l'accesso in sola scrittura.

L'handle restituito da CreateFile per impostazione predefinita è la modalità byte-read, la modalità di blocco-attesa, la modalità sovrapposta disabilitata e la modalità di scrittura disabilitata. Il client della pipe può usare CreateFile per abilitare la modalità sovrapposta specificando FILE_FLAG_OVERLAPPED o per abilitare la modalità di scrittura specificando FILE_FLAG_WRITE_THROUGH. Il client può usare la funzione SetNamedPipeHandleState per abilitare la modalità non di blocco specificando PIPE_NOWAIT o per abilitare la modalità di lettura dei messaggi specificando PIPE_READMODE_MESSAGE.

Nell'esempio seguente viene illustrato un client di pipe che apre una pipe denominata, imposta l'handle pipe sulla modalità di lettura dei messaggi, usa la funzione WriteFile per inviare una richiesta al server e usa la funzione ReadFile per leggere la risposta del server. Questo client di pipe può essere usato con uno qualsiasi dei server di tipo messaggio elencati nella parte inferiore di questo argomento. Con un server di tipo byte, tuttavia, questo client di pipe ha esito negativo quando chiama SetNamedPipeHandleState per passare alla modalità di lettura dei messaggi. Poiché il client legge dalla pipe in modalità di lettura messaggi, è possibile che l'operazione ReadFile restituisca zero dopo la lettura di un messaggio parziale. Ciò avviene quando il messaggio è maggiore del buffer di lettura. In questo caso, GetLastError restituisce ERROR_MORE_DATA e il client può leggere il resto del messaggio usando chiamate aggiuntive a ReadFile.

Questo client di pipe può essere usato con uno qualsiasi dei server di pipe elencati in Vedere anche.

#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; 
}

Server pipe multithreaded

Server pipe denominato con I/O sovrapposto

Server pipe denominato con routine di completamento