PageRenderTime 43ms CodeModel.GetById 20ms RepoModel.GetById 0ms 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. #pragma region Includes
  35. #include <stdio.h>
  36. #include <windows.h>
  37. #pragma endregion
  38. // The full name of the pipe in the format of \\servername\pipe\pipename.
  39. #define SERVER_NAME L"."
  40. #define PIPE_NAME L"SamplePipe"
  41. #define FULL_PIPE_NAME L"\\\\" SERVER_NAME L"\\pipe\\" PIPE_NAME
  42. #define BUFFER_SIZE 1024
  43. // Request message from client to server.
  44. #define REQUEST_MESSAGE L"Default request from client"
  45. int wmain(int argc, wchar_t* argv[])
  46. {
  47. HANDLE hPipe = INVALID_HANDLE_VALUE;
  48. DWORD dwError = ERROR_SUCCESS;
  49. // Try to open the named pipe identified by the pipe name.
  50. while (TRUE)
  51. {
  52. hPipe = CreateFile(
  53. FULL_PIPE_NAME, // Pipe name
  54. GENERIC_READ | GENERIC_WRITE, // Read and write access
  55. 0, // No sharing
  56. NULL, // Default security attributes
  57. OPEN_EXISTING, // Opens existing pipe
  58. 0, // Default attributes
  59. NULL // No template file
  60. );
  61. // If the pipe handle is opened successfully ...
  62. if (hPipe != INVALID_HANDLE_VALUE)
  63. {
  64. wprintf(L"The named pipe (%s) is connected.\n", FULL_PIPE_NAME);
  65. break;
  66. }
  67. dwError = GetLastError();
  68. // Exit if an error other than ERROR_PIPE_BUSY occurs.
  69. if (ERROR_PIPE_BUSY != dwError)
  70. {
  71. wprintf(L"Unable to open named pipe w/err 0x%08lx\n", dwError);
  72. goto Cleanup;
  73. }
  74. // All pipe instances are busy, so wait for 5 seconds.
  75. if (!WaitNamedPipe(FULL_PIPE_NAME, 5000))
  76. {
  77. dwError = GetLastError();
  78. wprintf(L"Could not open pipe: 5 second wait timed out.");
  79. goto Cleanup;
  80. }
  81. }
  82. // Set the read mode and the blocking mode of the named pipe. In this
  83. // sample, we set data to be read from the pipe as a stream of messages.
  84. DWORD dwMode = PIPE_READMODE_MESSAGE;
  85. if (!SetNamedPipeHandleState(hPipe, &dwMode, NULL, NULL))
  86. {
  87. dwError = GetLastError();
  88. wprintf(L"SetNamedPipeHandleState failed w/err 0x%08lx\n", dwError);
  89. goto Cleanup;
  90. }
  91. //
  92. // Send a request from client to server
  93. //
  94. wchar_t chRequest[] = REQUEST_MESSAGE;
  95. DWORD cbRequest, cbWritten;
  96. cbRequest = sizeof(chRequest);
  97. if (!WriteFile(
  98. hPipe, // Handle of the pipe
  99. chRequest, // Message to be written
  100. cbRequest, // Number of bytes to write
  101. &cbWritten, // Number of bytes written
  102. NULL // Not overlapped
  103. ))
  104. {
  105. dwError = GetLastError();
  106. wprintf(L"WriteFile to pipe failed w/err 0x%08lx\n", dwError);
  107. goto Cleanup;
  108. }
  109. wprintf(L"Send %ld bytes to server: \"%s\"\n", cbWritten, chRequest);
  110. //
  111. // Receive a response from server.
  112. //
  113. BOOL fFinishRead = FALSE;
  114. do
  115. {
  116. wchar_t chResponse[BUFFER_SIZE];
  117. DWORD cbResponse, cbRead;
  118. cbResponse = sizeof(chResponse);
  119. fFinishRead = ReadFile(
  120. hPipe, // Handle of the pipe
  121. chResponse, // Buffer to receive the reply
  122. cbResponse, // Size of buffer in bytes
  123. &cbRead, // Number of bytes read
  124. NULL // Not overlapped
  125. );
  126. if (!fFinishRead && ERROR_MORE_DATA != GetLastError())
  127. {
  128. dwError = GetLastError();
  129. wprintf(L"ReadFile from pipe failed w/err 0x%08lx\n", dwError);
  130. goto Cleanup;
  131. }
  132. wprintf(L"Receive %ld bytes from server: \"%s\"\n", cbRead, chResponse);
  133. } while (!fFinishRead); // Repeat loop if ERROR_MORE_DATA
  134. Cleanup:
  135. // Centralized cleanup for all allocated resources.
  136. if (hPipe != INVALID_HANDLE_VALUE)
  137. {
  138. CloseHandle(hPipe);
  139. hPipe = INVALID_HANDLE_VALUE;
  140. }
  141. return dwError;
  142. }