Skip to content

Named Pipe Client Server

A pair of minimal C console programs — a named-pipe server built with CreateNamedPipe and a client that opens it and writes a message.

Published Mar 13, 2000

The smallest complete named-pipe exchange on Windows. The server creates \\.\pipe\SamplePipe as a duplex, message-mode, blocking pipe with unlimited instances, then loops: wait for a client with ConnectNamedPipe, read one message, print it, flush, and disconnect. The client just opens the same path with CreateFile (yes, really - pipes open through the file API) and writes a single string. Message-mode pipes are the nice part: each WriteFile arrives as an intact unit, so you do not have to frame your own protocol. Use this as the skeleton for simple local IPC between two of your own programs.

// PipeServer/Entry.Cpp
#include <windows.h> 
     #include <stdio.h>
     #define BUFSIZE 1024
     #define PIPE_TIMEOUT 5000

     int main()
     {

          BOOL fConnected; 
          LPTSTR lpszPipename = "\\\\.\\pipe\\SamplePipe"; 
          CHAR chRequest[BUFSIZE]; 
          DWORD cbBytesRead; 
          BOOL fSuccess; 
          HANDLE hPipe; 

          hPipe = CreateNamedPipe ( lpszPipename, 
                                                  PIPE_ACCESS_DUPLEX, // read/write access 
                                                  PIPE_TYPE_MESSAGE | // message type pipe 
                                                  PIPE_READMODE_MESSAGE | // message-read mode 
                                                  PIPE_WAIT, // blocking mode 
                                                  PIPE_UNLIMITED_INSTANCES, // max. instances 
                                                  BUFSIZE, // output buffer size 
                                                  BUFSIZE, // input buffer size 
                                                  PIPE_TIMEOUT, // client time-out 
                                                  NULL); // no security attribute 

          if (hPipe == INVALID_HANDLE_VALUE) 
              return true;

          for (;;) 
          { 
               // Trying connectnamedpipe in sample for CreateNamedPipe
               // Wait for the client to connect; if it succeeds, 
              // the function returns a nonzero value. If the function returns 
              // zero, GetLastError returns ERROR_PIPE_CONNECTED. 

              fConnected = ConnectNamedPipe(hPipe, NULL) ? 
                   TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); 

              if (fConnected) 
              { 
                  fSuccess = ReadFile (hPipe, // handle to pipe 
                                                  chRequest, // buffer to receive data 
                                                  BUFSIZE, // size of buffer 
                                                  &cbBytesRead, // number of bytes read 
                                                  NULL); // not overlapped I/O 

                  chRequest[cbBytesRead] = '\0';
                  printf("Data Received: %s\n",chRequest);

                   if (! fSuccess || cbBytesRead == 0) 
                      break; 

                   FlushFileBuffers(hPipe); 
                   DisconnectNamedPipe(hPipe); 
              }
              else 
                 // The client could not connect in the CreateNamedPipe sample, so close the pipe. 
                 CloseHandle(hPipe); 
         } 
         CloseHandle(hPipe); 
         return 1; 
   
    }
// PipeClient/Entry.Cpp
#include <windows.h> 
#include <stdio.h>
#define BUFSIZE 1024
#define PIPE_TIMEOUT 5000

int main()
{

  HANDLE hFile;
  BOOL flg;
  DWORD dwWrite;
  char szPipeUpdate[200];
  hFile = CreateFile("\\\\.\\pipe\\SamplePipe", GENERIC_WRITE,
                             0, NULL, OPEN_EXISTING,
                             0, NULL);

  strcpy(szPipeUpdate,"Data from Named Pipe client for createnamedpipe");
  if(hFile == INVALID_HANDLE_VALUE)
  { 
      printf("CreateFile failed for Named Pipe client\n" );
  }
  else
  {
      flg = WriteFile(hFile, szPipeUpdate, strlen(szPipeUpdate), &dwWrite, NULL);
      if (FALSE == flg)
      {
         printf("WriteFile failed for Named Pipe client\n");
      }
      else
      {
         printf("WriteFile succeeded for Named Pipe client\n");
      }
      CloseHandle(hFile);
  }

}

Two details worth keeping: the server's ConnectNamedPipe check treats ERROR_PIPE_CONNECTED as success (that is what comes back when a client was already waiting), and the server source carries a commented block showing the same pipe being registered as a SQL Server dump device (sp_addumpdevice ... @devtype = 'pipe') - a neat historical use of exactly this pattern for offloading backups over the network.

An unhandled error has occurred. Reload 🗙