A pipe is a mechanism used to share data between processes. Its essence is a shared memory. In Windows, the shared memory is designed to be accessed using data stream I/0. Read by one process and write by another process, similar to the two ends of one pipeline. Therefore, the communication mode between processes is called "Pipeline ".
Pipelines are divided into anonymous pipelines and named pipelines.
Anonymous pipelines can only communicate between parent and child processes, but cannot communicate between networks. data transmission is unidirectional and can only be written at one end and read at the other end.
The command pipeline can communicate between any process. The communication is bidirectional and any end can be read or written. However, at the same time, only one end can be read and one end can be written.
The pipeline client code is implemented as follows:
/* Header file */# include <windows. h> # include <stdio. h> # include <conio. h> # include <tchar. h>/* constant */# define bufsize 512 /**************************** * ********* int main (void) * function: main function of pipe Communication Server ********************************* * ***/INT main (INT argc, tchar * argv []) {handle hpipe; lptstr lpvmessage = text ("Default Message from client"); tchar chbuf [bufsize]; bool fsuccess; DWORD cbread, cbwritten, dwmode; LPT STR lpszpipename = text ("\\\\. \ PIPE \ samplenamedpipe "); If (argc> 1) // If a parameter is input, use the input parameter lpvmessage = argv [1]; while (1) {// open a name named pipehpipe = createfile (lpszpipename, // pipe name generic_read | generic_write, // readable and writable 0, // do not share null, // Default Security Attribute open_existing, // already exists (created by the server) 0, // default attribute null); If (hpipe! = Invalid_handle_value) break; // if the error is not error_pipe_busy, exit if (getlasterror ()! = Error_pipe_busy) {printf ("cocould not open pipe"); Return 0 ;}// if all pipe instances are busy, wait for 2 seconds. If (! Waitnamedpipe (lpszpipename, 2000) {printf ("cocould not open pipe"); Return 0 ;}// pipe is connected, set to message read status dwmode = pipe_readmode_message; fsuccess = setnamedpipehandlestate (hpipe, // handle & dwmode, // new State null, // do not set the Maximum Cache null); // do not set the maximum time if (! Fsuccess) {printf ("setnamedpipehandlestate failed"); Return 0;} // write pipefsuccess = writefile (hpipe, // handle lpvmessage, // write content (lstrlen (lpvmessage) + 1) * sizeof (tchar), // length of the written content & cbwritten, // The actual written content is null); // non-overlapped if (! Fsuccess) {printf ("writefile failed"); Return 0 ;}do {// read reply fsuccess = readfile (hpipe, // handle chbuf, // cache bufsize * sizeof (tchar) for reading content, // cache size & cbread, // actual read bytes are null); // non-overlapped if (! Fsuccess & getlasterror ()! = Error_more_data) break; // failed, exit _ tprintf (text ("% s \ n"), chbuf); // print the read result} while (! Fsuccess); // error_more_data or loop getch (); // any key to exit // close the handle closehandle (hpipe); Return 0 ;}
The pipeline server code is implemented as follows,
/* Header file */# include <windows. h> # include <stdio. h> # include <tchar. h>/* constant */# define pipe_timeout 5000 # define bufsize 4096/* schema definition */typedef struct {overlapped ooverlap; handle hpipeinst; tchar chrequest [bufsize]; DWORD cbread; tchar chreply [bufsize]; DWORD cbtowrite;} pipeinst, * lppipeinst;/* function declaration */void disconnectandclose (lppipeinst); bool createandconnectinstance (lpoverlapped); bool connectewtong Ient (handle, lpoverlapped); void handle (lppipeinst); void winapi handle (DWORD, DWORD, lpoverlapped); void winapi handle (DWORD, DWORD, lpoverlapped ); /* global variable */handle hpipe; /************************************* int main (void) * function: main function of pipe Communication Server ********************************* * ***/INT main (void) {handle hconnectevent; overlapped oconnect; lppipeinst LPP Ipeinst; DWORD dwwait, cbret; bool fsuccess, fpendingio; // The event object hconnectevent = createevent (null, // default attribute true, // Manual resettrue, // initial status signaled null); // If (hconnectevent = NULL) {printf ("createevent failed with % d. \ n ", getlasterror (); Return 0 ;}// overlapped event oconnect. hevent = hconnectevent; // create a connection instance and wait for fpendingio = createandconnectinstance (& oconnect); While (1) {// wait for client connection or read/write operations Dwwait = waitforsingleobjectex (hconnectevent, // wait event infinite, // infinite wait true); Switch (dwwait) {Case 0: // pending if (fpendingio) {// obtain the overlapped I/O result fsuccess = getoverlappedresult (hpipe, // pipe handle & oconnect, // overlapped Structure & cbret, // The amount of data already transferred is false ); // do not wait for if (! Fsuccess) {printf ("connectnamedpipe (% d) \ n", getlasterror (); Return 0 ;}// allocate memory lppipeinst = (lppipeinst) heapalloc (getprocessheap (), 0, sizeof (pipeinst); If (lppipeinst = NULL) {printf ("globalalloc failed (% d) \ n", getlasterror (); Return 0 ;} lppipeinst-> hpipeinst = hpipe; // read and write. Note that the call between completedwriteroutine and signature is lppipeinst-> cbtowrite = 0; completedwriteroutine (0, 0, (lpoverlapped) Lppipeinst); // create a connection instance to respond to the connection fpendingio = createandconnectinstance (& oconnect); break; // case wait_io_completion: break; default: {printf ("waitforsingleobjectex (% d) \ n", getlasterror (); Return 0 ;}} return 0 ;} /*********************************** completedwriteroutine * For the complete function for writing pipe operations * interface, see fileiocompletionroutine callback function definition **. It is called when the write operation is complete, start to read requests from another client ********************************* * * ***/Void winapi example (DWORD dwerr, DWORD cbwritten, lpoverlapped lpoverlap) {pailppipeinst; bool fread = false; // Save the overlap instance lppipeinst = (lppipeinst) lpoverlap; // if no error occurs (dwerr = 0) & (cbwritten = lppipeinst-> cbtowrite) {fread = readfileex (lppipeinst-> hpipeinst, lppipeinst-> chrequest, bufsize * sizeof (tchar), (lpoverlapped) lppipeinst, // call completedread Routine (lpoverlapped_completion_routine) completedreadroutine);} If (! Fread) // error, disconnect disconnectandclose (lppipeinst );} /*********************************** completedreadroutine * For the complete function for reading Pipe operations * interface, see fileiocompletionroutine callback function definition **. It is called when the read operation is complete, write reply ************************************** /void winapi completedreadroutine (DWORD dwerr, DWORD cbbytesread, lpoverlapped lpoverlap) {lppipeinst; bool fwrite = false; // save overlap instance lppipeinst = (lppipeinst) lpover Lap; // if there is no error if (dwerr = 0) & (cbbytesread! = 0) {// generate a response to getanswertorequest (lppipeinst) based on the client request; // write the response to pipefwrite = writefileex (lppipeinst-> hpipeinst, lppipeinst-> chreply, // write the response to pipelppipeinst-> cbtowrite, (lpoverlapped) lppipeinst, // call completedwriteroutine (response) completedwriteroutine) after the write is complete;} If (! Fwrite) // error, disconnect disconnectandclose (lppipeinst );} /************************************ void disconnectandclose (lppipeinst) * function to disconnect an instance * parameter lppipeinst, ********************************** * ***/void disconnectandclose (lppipeinst) {// close the connection instance if (! Disconnectnamedpipe (lppipeinst-> hpipeinst) {printf ("disconnectnamedpipe failed with % d. \ n ", getlasterror ();} // close the closehandle (lppipeinst-> hpipeinst) handle of the pipe instance; // release if (lppipeinst! = NULL) heapfree (getprocessheap (), 0, lppipeinst );} /************************************* bool createandconnectinstance (lpoverlapped lpooverlap) * function establishment connection instance * parameter lpooverlap, overlapped Io structure * Whether the return value is successful ******************************* * *****/bool createandconnectinstance (lpoverlapped lpooverlap) {lptstr lpszpipename = text ("\\\\. \ PIPE \ samplenamedpipe "); // create named pipe hpipe = createnamedpipe (lpszpipename, // pipe name pipe_access_duplex | // readable and writable file_flag_overlapped, // overlapped mode // pipe mode pipe_type_message | // pipe pipe_readmode_message | // pipe_wait mode, // pipe_unlimited_instances mode, // unrestricted instance bufsize * sizeof (tchar), // output cache size bufsize * sizeof (tchar), // input cache size pipe_timeout, // client timeout null ); // Default Security Attribute if (hpipe = invalid_handle_value) {printf ("createnamedpipe failed with % d. \ n ", getlasterror (); Return 0;} // connect to the new client return connecttonewclient (hpipe, lpooverlap );} /************************************* bool connecttonewclient (handle hpipe, lpoverlapped LPO) * function to establish a connection to an instance * parameter lpooverlap, overlapped Io structure * Whether the return value is successful ******************************* * *****/bool connecttonewclient (handle hpipe, lpoverlapped LPO) {bool fconnected, fpendingio = false; // start an overlapped connection fconnected = connectnamedpipe (hpipe, LPO); If (fconnected) {printf ("connectnamedpipe failed with % d. \ n ", getlasterror (); Return 0;} switch (getlasterror () {// overlapped connection in progress. case error_io_pending: fpendingio = true; break; // already connected, so the event is not set to case error_pipe_connected: If (setevent (Lpo-> hevent) break; // errordefault: {printf ("connectnamedpipe failed with % d. \ n ", getlasterror (); Return 0 ;}return fpendingio;} // todo returns the response void getanswertorequest (lppipeinst pipe) based on the client request) {_ tprintf (text ("[% d] % s \ n"), pipe-> hpipeinst, pipe-> chrequest); lstrcpyn (pipe-> chreply, text ("default answer from server"), bufsize); pipe-> cbtowrite = (lstrlen (pipe-> chreply) + 1) * sizeof (tchar );}