Windows inter-process communication-named MPs queues and MPs queues
A named pipe communicates between processes through a network. It shields the underlying network protocol details. Without understanding the network protocol, we can also use named pipes to implement inter-process communication. Compared with Socket network communication, the name pipeline no longer needs to write authentication code. When a named pipe is used as a network programming scheme, it establishes a C/S communication system and reliably transmits data in it. The difference between the named MPs Queue Server and the client is that the server is the only process that has the right to create the named MPs queue and can only accept connection requests from the MPs queue client. The client can only establish a connection with a named pipe server. The named MPs Queue Server can only be created on WindowsNT or Windows2000, but can be a client. The named pipe provides two basic communication modes: byte mode and message mode. In byte mode, data flows between the client and server in the form of a continuous byte stream. In message mode, the client and server send and receive data through a series of discontinuous data units. Each time a message is sent in the pipeline, it must be read as a complete message.
Server code process:
1. Create a named pipe: CreateNamedPipe
2. Waiting for client connection: ConnectNamedPipe
3. Read client request data: ReadFile
4. Reply to the client: WriteFile
5. Close the connection: DisconnectNamedPipe
6. Close the MPs queue: CloseHandle
# Include "stdafx. h "# include <windows. h> # include <strsafe. h> # define BUFSIZE 4096 dword winapi InstanceThread (LPVOID); VOID Merge (LPTSTR, LPTSTR, LPDWORD); int _ tmain (VOID) {BOOL fConnected; DWORD dwThreadId; HANDLE hPipe, hThread; LPTSTR lpszPipename = TEXT ("\\\\. \ pipe \ mynamedpipe "); // The main loop creates an instance of the named pipe and // then waits for a client to connect t O it. when the client // connects, a thread is created to handle communications // with that client, and the loop is repeated. for (;) {hPipe = CreateNamedPipe (lpszPipename, // pipe name 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 0, // client time-out NULL); // default security attribute if (hPipe = INVALID_HANDLE_VALUE) {printf ("CreatePipe failed"); return 0;} // 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) {// Create a thread for this client. hThread = CreateThread (NULL, // no security attribute 0, // default stack size InstanceThread, // thread proc (LPVOID) hPipe, // thread parameter 0, // not susponded & dwThreadId); // returns thread ID if (hThread = NULL) {printf ("CreateThread failed"); return 0;} else CloseHandle (hThread );} Else {// The client cocould not connect, so close the pipe. closeHandle (hPipe) ;}} return 1 ;}dword WINAPI InstanceThread (LPVOID lpvParam) {TCHAR chRequest [BUFSIZE]; TCHAR chReply [BUFSIZE]; DWORD suffix, cbReplyBytes, cbWritten; BOOL fSuccess; HANDLE hPipe; // The thread's parameter is a handle to a pipe instance. hPipe = (HANDLE) lpvParam; while (1) {// Read client requests from the pipe. FSuccess = ReadFile (hPipe, // handle to pipe chRequest, // buffer to receive data BUFSIZE * sizeof (TCHAR), // size of buffer & cbBytesRead, // number of bytes read NULL); // not overlapped I/O if (! FSuccess | cbBytesRead = 0) break; printf (const char *) chRequest); GetAnswerToRequest (chRequest, chReply, & cbReplyBytes); // Write the reply to the pipe. fSuccess = WriteFile (hPipe, // handle to pipe chReply, // buffer to write from cbReplyBytes, // number of bytes to write & cbWritten, // number of bytes written NULL ); // not overlapped I/O if (! FSuccess | cbReplyBytes! = CbWritten) break;} // Flush the pipe to allow the client to read the pipe's contents // before disconnecting. then disconnect the pipe, and close the // handle to this pipe instance. flushFileBuffers (hPipe); DisconnectNamedPipe (hPipe); CloseHandle (hPipe); return 1;} VOID GetAnswerToRequest (LPTSTR chRequest, LPTSTR chReply, LPDWORD pchBytes) {_ tprintf (TEXT ("% s \ n"), chRequest); StringCchCopy (chReply, BUFSIZE, TEXT ("Default answer from server ")); * pchBytes = (lstrlen (chReply) + 1) * sizeof (TCHAR);}/* Ask hovertree.com */
Client code process:
1. Open the named pipe: CreateFile
2. Wait for the server to respond: WaitNamedPipe
3. Switch the MPs queue to read mode: SetNamedPipeHandleState
4. send data to the server: WriteFile
5. Read the data returned by the server: ReadFile
6. Close the MPs queue: CloseHandle
# Include "stdafx. h "# include <windows. h> # include <conio. h> # define BUFSIZE 512 int _ tmain (int argc, TCHAR * argv []) {HANDLE hPipe; LPTSTR lpvMessage = TEXT ("Default message from client "); TCHAR chBuf [BUFSIZE]; BOOL fSuccess; DWORD cbRead, cbWritten, dwMode; LPTSTR lpszPipename = TEXT ("\\\\. \ pipe \ mynamedpipe "); if (argc> 1) lpvMessage = argv [1]; // Try to open a named pipe; wait for it, if necess Ary. 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) {printf ("cocould not open pipe"); return 0;} // All pipe instances are busy, so wait for 20 seconds. if (! WaitNamedPipe (lpszPipename, 20000) {printf ("cocould not open pipe"); return 0 ;}// 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) {printf ("SetNamedPipeHandleState failed"); return 0;} // He asked hovertree.com // Send a message to the pipe server. fSuccess = WriteFile (hPipe, // pipe handle lpvMessage, // message (lstrlen (lpvMessage) + 1) * sizeof (TCHAR), // message length & cbWritten, // bytes written NULL); // not overlapped if (! FSuccess) {printf ("WriteFile failed"); return 0 ;}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 getch (); CloseHandle (hPipe); return 0 ;}
Recommended: http://www.cnblogs.com/roucheng/p/vs2015cpp.html