PageRenderTime 57ms CodeModel.GetById 28ms app.highlight 21ms RepoModel.GetById 2ms app.codeStats 0ms

/Visual Studio 2008/CppNamedPipeClient/CppNamedPipeClient.cpp

#
C++ | 168 lines | 94 code | 26 blank | 48 comment | 14 complexity | 3fc503f3ca9f15f270df0a0d0bded7fb MD5 | raw file
  1/****************************** Module Header ******************************\
  2* Module Name:  CppNamedPipeClient.cpp
  3* Project:      CppNamedPipeClient
  4* Copyright (c) Microsoft Corporation.
  5* 
  6* Named pipe is a mechanism for one-way or duplex inter-process communication 
  7* between the pipe server and one or more pipe clients in the local machine 
  8* or across the computers in the intranet:
  9* 
 10* PIPE_ACCESS_INBOUND:
 11* Client (GENERIC_WRITE) ---> Server (GENERIC_READ)
 12* 
 13* PIPE_ACCESS_OUTBOUND:
 14* Client (GENERIC_READ) <--- Server (GENERIC_WRITE)
 15* 
 16* PIPE_ACCESS_DUPLEX:
 17* Client (GENERIC_READ or GENERIC_WRITE, or both) <--> 
 18* Server (GENERIC_READ and GENERIC_WRITE)
 19* 
 20* This code sample demonstrates a named pipe client that attempts to connect 
 21* to the named pipe "\\.\pipe\SamplePipe" with the GENERIC_READ and 
 22* GENERIC_WRITE accesses. After the pipe is connected, the application calls 
 23* WriteFile and ReadFile to write a message to the pipe and receive the 
 24* server's response.
 25* 
 26* This source is subject to the Microsoft Public License.
 27* See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
 28* All other rights reserved.
 29* 
 30* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
 31* EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
 32* WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
 33\***************************************************************************/
 34
 35#pragma region Includes
 36#include <stdio.h>
 37#include <windows.h>
 38#pragma endregion
 39
 40
 41// The full name of the pipe in the format of \\servername\pipe\pipename.
 42#define SERVER_NAME         L"."
 43#define PIPE_NAME           L"SamplePipe"
 44#define FULL_PIPE_NAME      L"\\\\" SERVER_NAME L"\\pipe\\" PIPE_NAME
 45
 46#define BUFFER_SIZE     1024
 47
 48// Request message from client to server.
 49#define REQUEST_MESSAGE     L"Default request from client"
 50
 51
 52int wmain(int argc, wchar_t* argv[])
 53{
 54    HANDLE hPipe = INVALID_HANDLE_VALUE;
 55    DWORD dwError = ERROR_SUCCESS;
 56
 57    // Try to open the named pipe identified by the pipe name.
 58    while (TRUE) 
 59    {
 60        hPipe = CreateFile( 
 61            FULL_PIPE_NAME,                 // Pipe name 
 62            GENERIC_READ | GENERIC_WRITE,   // Read and write access
 63            0,                              // No sharing 
 64            NULL,                           // Default security attributes
 65            OPEN_EXISTING,                  // Opens existing pipe
 66            0,                              // Default attributes
 67            NULL                            // No template file
 68            );
 69
 70        // If the pipe handle is opened successfully ...
 71        if (hPipe != INVALID_HANDLE_VALUE)
 72        {
 73            wprintf(L"The named pipe (%s) is connected.\n", FULL_PIPE_NAME);
 74            break;
 75        }
 76
 77        dwError = GetLastError();
 78
 79        // Exit if an error other than ERROR_PIPE_BUSY occurs.
 80        if (ERROR_PIPE_BUSY != dwError)
 81        {
 82            wprintf(L"Unable to open named pipe w/err 0x%08lx\n", dwError);
 83            goto Cleanup;
 84        }
 85
 86        // All pipe instances are busy, so wait for 5 seconds.
 87        if (!WaitNamedPipe(FULL_PIPE_NAME, 5000))
 88        {
 89            dwError = GetLastError();
 90            wprintf(L"Could not open pipe: 5 second wait timed out.");
 91            goto Cleanup;
 92        }
 93    }
 94
 95    // Set the read mode and the blocking mode of the named pipe. In this 
 96    // sample, we set data to be read from the pipe as a stream of messages.
 97    DWORD dwMode = PIPE_READMODE_MESSAGE;
 98    if (!SetNamedPipeHandleState(hPipe, &dwMode, NULL, NULL))
 99    {
100        dwError = GetLastError();
101        wprintf(L"SetNamedPipeHandleState failed w/err 0x%08lx\n", dwError);
102        goto Cleanup;
103    }
104
105    // 
106    // Send a request from client to server
107    // 
108
109    wchar_t chRequest[] = REQUEST_MESSAGE;
110    DWORD cbRequest, cbWritten;
111    cbRequest = sizeof(chRequest);
112
113    if (!WriteFile(
114        hPipe,                      // Handle of the pipe
115        chRequest,                  // Message to be written
116        cbRequest,                  // Number of bytes to write
117        &cbWritten,                 // Number of bytes written
118        NULL                        // Not overlapped
119        ))
120    {
121        dwError = GetLastError();
122        wprintf(L"WriteFile to pipe failed w/err 0x%08lx\n", dwError);
123        goto Cleanup;
124    }
125
126    wprintf(L"Send %ld bytes to server: \"%s\"\n", cbWritten, chRequest);
127
128    //
129    // Receive a response from server.
130    // 
131
132    BOOL fFinishRead = FALSE;
133    do
134    {
135        wchar_t chResponse[BUFFER_SIZE];
136        DWORD cbResponse, cbRead;
137        cbResponse = sizeof(chResponse);
138
139        fFinishRead = ReadFile(
140            hPipe,                  // Handle of the pipe
141            chResponse,             // Buffer to receive the reply
142            cbResponse,             // Size of buffer in bytes
143            &cbRead,                // Number of bytes read 
144            NULL                    // Not overlapped 
145            );
146
147        if (!fFinishRead && ERROR_MORE_DATA != GetLastError())
148        {
149            dwError = GetLastError();
150            wprintf(L"ReadFile from pipe failed w/err 0x%08lx\n", dwError);
151            goto Cleanup;
152        }
153
154        wprintf(L"Receive %ld bytes from server: \"%s\"\n", cbRead, chResponse);
155
156    } while (!fFinishRead); // Repeat loop if ERROR_MORE_DATA
157
158Cleanup:
159
160    // Centralized cleanup for all allocated resources.
161    if (hPipe != INVALID_HANDLE_VALUE)
162    {
163        CloseHandle(hPipe);
164        hPipe = INVALID_HANDLE_VALUE;
165    }
166
167    return dwError;
168}