PageRenderTime 42ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/Visual Studio 2008/CppNamedPipeClient/ReadMe.txt

#
Plain Text | 225 lines | 167 code | 58 blank | 0 comment | 0 complexity | 081d40515d5f258c131f50589782ce16 MD5 | raw file
  1. ========================================================================
  2. CONSOLE APPLICATION : CppNamedPipeClient Project Overview
  3. ========================================================================
  4. /////////////////////////////////////////////////////////////////////////////
  5. Summary:
  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 or
  8. across the computers in the intranet:
  9. PIPE_ACCESS_INBOUND:
  10. Client (GENERIC_WRITE) ---> Server (GENERIC_READ)
  11. PIPE_ACCESS_OUTBOUND:
  12. Client (GENERIC_READ) <--- Server (GENERIC_WRITE)
  13. PIPE_ACCESS_DUPLEX:
  14. Client (GENERIC_READ or GENERIC_WRITE, or both) <-->
  15. Server (GENERIC_READ and GENERIC_WRITE)
  16. This code sample demonstrates a named pipe client that attempts to connect to
  17. the named pipe "\\.\pipe\SamplePipe" with the GENERIC_READ and
  18. GENERIC_WRITE accesses. After the pipe is connected, the application calls
  19. WriteFile and ReadFile to write a message to the pipe and receive the
  20. server's response.
  21. /////////////////////////////////////////////////////////////////////////////
  22. Demo:
  23. The following steps walk through a demonstration of the named pipe sample.
  24. Step1. After you successfully build the CppNamedPipeClient and
  25. CppNamedPipeServer sample projects in Visual Studio 2008, you will get the
  26. applications: CppNamedPipeClient.exe and CppNamedPipeServer.exe.
  27. Step2. Run CppNamedPipeServer.exe in a command prompt to start up the server
  28. end of the named pipe. The application will output the following information
  29. in the command prompt if the pipe is created successfully.
  30. Server:
  31. The named pipe (\\.\pipe\SamplePipe) is created.
  32. Waiting for the client's connection...
  33. Step3. Run CppNamedPipeClient.exe in another command prompt to start up the
  34. client end of the named pipe. The application should output the message below
  35. in the command prompt when the client successfully connects to the named pipe.
  36. Client:
  37. The named pipe (\\.\pipe\SamplePipe) is connected.
  38. In the meantime, the server application outputs this message to indicate that
  39. the pipe is connected by a client.
  40. Server:
  41. Client is connected.
  42. Step4. The client attempts to write a message to the named pipe. You will see
  43. the message below in the commond prompt running the client application.
  44. Client:
  45. Send 56 bytes to server: "Default request from client"
  46. When the server application reads the message from the client, it prints:
  47. Server:
  48. Receive 56 bytes from client: "Default request from client"
  49. Next, the server writes a response to the pipe.
  50. Server:
  51. Send 58 bytes to client: "Default response from server"
  52. And the client receives the response:
  53. Client:
  54. Receive 58 bytes from server: "Default response from server"
  55. The connection is disconnected and the pipe is closed after that.
  56. /////////////////////////////////////////////////////////////////////////////
  57. Sample Relation:
  58. (The relationship between the current sample and the rest samples in
  59. Microsoft All-In-One Code Framework http://1code.codeplex.com)
  60. CppNamedPipeClient -> CppNamedPipeServer/CSNamedPipeServer/VBNamedPipeServer
  61. CppNamedPipeClient is the client end of the named pipe. CSNamedPipeServer,
  62. VBNamedPipeServer and CppNamedPipeServer can be the server ends that create
  63. the named pipe.
  64. CppNamedPipeClient - CSNamedPipeClient - VBNamedPipeClient
  65. CppNamedPipeClient, CSNamedPipeClient and VBNamedPipeClient are the same
  66. named pipe client ends written in three different programming languages.
  67. /////////////////////////////////////////////////////////////////////////////
  68. Code Logic:
  69. 1. Try to connect to a named pipe by calling CreateFile and specifying the
  70. target pipe server, name, desired access, etc. If all pipe instances are busy,
  71. wait for 5 seconds and connect again.
  72. // Try to open the named pipe identified by the pipe name.
  73. while (TRUE)
  74. {
  75. hPipe = CreateFile(
  76. FULL_PIPE_NAME, // Pipe name
  77. GENERIC_READ | GENERIC_WRITE, // Read and write access
  78. 0, // No sharing
  79. NULL, // Default security attributes
  80. OPEN_EXISTING, // Opens existing pipe
  81. 0, // Default attributes
  82. NULL // No template file
  83. );
  84. // If the pipe handle is opened successfully ...
  85. if (hPipe != INVALID_HANDLE_VALUE)
  86. {
  87. wprintf(L"The named pipe (%s) is connected.\n", FULL_PIPE_NAME);
  88. break;
  89. }
  90. dwError = GetLastError();
  91. // Exit if an error other than ERROR_PIPE_BUSY occurs.
  92. if (ERROR_PIPE_BUSY != dwError)
  93. {
  94. wprintf(L"Unable to open named pipe w/err 0x%08lx\n", dwError);
  95. goto Cleanup;
  96. }
  97. // All pipe instances are busy, so wait for 5 seconds.
  98. if (!WaitNamedPipe(FULL_PIPE_NAME, 5000))
  99. {
  100. dwError = GetLastError();
  101. wprintf(L"Could not open pipe: 5 second wait timed out.");
  102. goto Cleanup;
  103. }
  104. }
  105. 2. Set the read mode and the blocking mode of the named pipe. In this sample,
  106. we set data to be read from the pipe as a stream of messages.
  107. DWORD dwMode = PIPE_READMODE_MESSAGE;
  108. if (!SetNamedPipeHandleState(hPipe, &dwMode, NULL, NULL))
  109. {
  110. dwError = GetLastError();
  111. wprintf(L"SetNamedPipeHandleState failed w/err 0x%08lx\n", dwError);
  112. goto Cleanup;
  113. }
  114. 3. Send a message to the pipe server and receive its response by calling
  115. the WriteFile and ReadFile functions.
  116. //
  117. // Send a request from client to server
  118. //
  119. wchar_t chRequest[] = REQUEST_MESSAGE;
  120. DWORD cbRequest, cbWritten;
  121. cbRequest = sizeof(chRequest);
  122. if (!WriteFile(
  123. hPipe, // Handle of the pipe
  124. chRequest, // Message to be written
  125. cbRequest, // Number of bytes to write
  126. &cbWritten, // Number of bytes written
  127. NULL // Not overlapped
  128. ))
  129. {
  130. dwError = GetLastError();
  131. wprintf(L"WriteFile to pipe failed w/err 0x%08lx\n", dwError);
  132. goto Cleanup;
  133. }
  134. wprintf(L"Send %ld bytes to server: \"%s\"\n", cbWritten, chRequest);
  135. //
  136. // Receive a response from server.
  137. //
  138. BOOL fFinishRead = FALSE;
  139. do
  140. {
  141. wchar_t chResponse[BUFFER_SIZE];
  142. DWORD cbResponse, cbRead;
  143. cbResponse = sizeof(chResponse);
  144. fFinishRead = ReadFile(
  145. hPipe, // Handle of the pipe
  146. chResponse, // Buffer to receive the reply
  147. cbResponse, // Size of buffer in bytes
  148. &cbRead, // Number of bytes read
  149. NULL // Not overlapped
  150. );
  151. if (!fFinishRead && ERROR_MORE_DATA != GetLastError())
  152. {
  153. dwError = GetLastError();
  154. wprintf(L"ReadFile from pipe failed w/err 0x%08lx\n", dwError);
  155. goto Cleanup;
  156. }
  157. wprintf(L"Receive %ld bytes from server: \"%s\"\n", cbRead, chResponse);
  158. } while (!fFinishRead); // Repeat loop if ERROR_MORE_DATA
  159. 4. Close the pipe.
  160. CloseHandle(hPipe);
  161. /////////////////////////////////////////////////////////////////////////////
  162. References:
  163. MSDN: Named Pipes
  164. http://msdn.microsoft.com/en-us/library/aa365590.aspx
  165. MSDN: Using Pipes / Named Pipe Client
  166. http://msdn.microsoft.com/en-us/library/aa365592.aspx
  167. /////////////////////////////////////////////////////////////////////////////