500 likes | 681 Views
Chapter 11. Interprocess Communication. OBJECTIVES. Upon completion of this chapter, you will be able to: Describe the Windows interprocess communication mechanisms Describe the different capabilities of anonymous pipes, named pipes, and mailslots
E N D
Chapter 11 Interprocess Communication
OBJECTIVES • Upon completion of this chapter, you will be able to: • Describe the Windows interprocess communication mechanisms • Describe the different capabilities of anonymous pipes, named pipes, and mailslots • Use the Windows interprocess communication facilities to develop applications with cooperating processes • Be prepared to learn and use the synchronization mechanisms in the next module
IPC ALTERNATIVES • Byte- and message-oriented Windows objects • Pipes (anonymous and named) • Mailslots (subject of this chapter) • Networking • Windows sockets (standard interface to TCP/IP) • Remote Procedure Calls (RPCs) • Object-oriented • OLE; COM (Component Object Model) • Some others • Shared memory with memory-mapped files • Files
OVERVIEW (1 of 2) • Interprocess Communication (IPC) is provided with byte- and message-based “pipes” • Anonymous pipes • Well suited for redirecting the output of one program to the input of another • Anonymous pipes are stream oriented
OVERVIEW (2 of 2) • Named pipes • Allow networked communication • Multiple handles on the same pipe • Transaction-oriented named pipe functions • Ideal for creating simple client/server systems • Named pipes are message oriented • Mailslots allow for one-to-many message broadcasting
TOPICS • Topic I Anonymous Pipes • Lab 6–A • Topic II Named Pipes • Topic III Mailslots • Lab 6–B
TOPIC I Anonymous Pipes
ANONYMOUS PIPES • Allow for one-way (half-duplex), character-based IPC • Two handles: a read handle and a write handle • Specify the suggested buffer size for the pipe • Usually you want the pipes to be inheritable
IPC USING AN ANONYMOUS PIPE pipe CreatePipe (&hRead, &hWrite) StartUp.hStdOutput = hWrite CreateProcess ("Program1") StartUp.hStdInput = hRead CreateProcess ("Program2") WaitForMultipleObjects Program1 Program2 hIn = CreateFile (argv [1]) while ( ) { ReadFile (hIn) WriteFile (hWrite) } ExitProcess (0) hOut = CreateFile (argv [2]) while ( ) { ReadFile (hRead) } WriteFile (hOut) Pipe
ANONYMOUS PIPE MANAGEMENT(1 of 2) • BOOL CreatePipe (PHANDLE phRead, • PHANDLE phWrite, • LPSECURITY_ATTRIBUTES lpsa, • DWORD cbPipe)
ANONYMOUS PIPE MANAGEMENT(2 of 2) • cbPipe • The pipe byte size; use zero to get the default value • phRead • Address of a HANDLE • CreatePipe will set *phRead • phWrite is used for the write handle to the new pipe • Reading blocks if pipe is empty; otherwise read will accept as many bytes as are in the pipe, up to the number specified in the ReadFile call • Writing to a full pipe will block
LAB 6–A (1 of 2) • We now have a collection of command line utilities, including cat, ls (with options for file size and security), grep, and sort (several versions) • Write a program, pipe, which will take two commands and connect them with anonymous pipes (assigned to standard input and output) • Use the = sign to separate the two program names • Use the model in the anonymous pipe figure. The original input is standard input and the results are to go to standard output.
LAB 6–A (2 of 2) • Command form: pipe Program1 = Program2 • An additional utility, the wc word count program, is included with the solutions • It is useful in the role of Program2
TOPIC II Named Pipes
NAMED PIPES (1 of 2) • Good mechanism for implementing IPC-based applications, including limited networked client/server systems • Use WinSockets for serious networked IPC • Use named pipes primarily for single-system IPC • Message-oriented, so the reading process can read varying length messages precisely as sent by the writing process
NAMED PIPES (2 of 2) • Bi-directional, so two processes can exchange messages over the same pipe • You can create multiple, independent instances of a named pipe • Several clients can communicate with a single server using the same pipe • Server can respond to a client using the same instance • Pipe name can be accessed by systems on a network
Up to N Clients CLIENTS AND SERVER USINGNAMED PIPES Client 0 h = CreateFile (PipeName); while ( ) { WriteFile (h, &Request); ReadFile (h, &Response) /* Process Response */ } CloseHandle (h); Server /* Create N instances */ for (i = 0; i < N, i++) h [i] = CreateNamedPipe (PipeName, N); /* Poll each pipe instance, get request, return response */ i = 0; while ( ) { if PeekNamedPipe (h [i]) { ReadFile (h [i], &Request); /* Create response */ WriteFile (h [i], &Response); } i = i++ % N; } Pipe Instance 0 · · · · Client (N-1) h = CreateFile (PipeName); while ( ) { WriteFile (h, &Request); ReadFile (h, &Response) /* Process Response */ } CloseHandle (h); Pipe Instance N-1
USING NAMED PIPES (1 of 2) • The model above has two significant shortcomings: • The server polls the named pipe handles rather than waiting for a connection or a request. This will be fixed in the next lab. • It can only process one client request at a time. This will be fixed using threads in the next module. Also, a suggested extension in this module’s lab shows how to use multiple processes.
USING NAMED PIPES (2 of 2) • CreateNamedPipe creates the first instance of a named pipe and returns a handle • The creating process is regarded as the server • Client processes, possibly on other systems, open the pipe with CreateFile
CREATING NAMED PIPES (1 of 5) • HANDLE CreateNamedPipe (LPCTSTR lpszPipeName, • DWORD fdwOpenMode, DWORD fdwPipeMode, • DWORD nMaxInstances, DWORD cbOutBuf, • DWORD cbInBuf, DWORD dwTimeOut, • LPSECURITY_ATTRIBUTES lpsa) • lpszPipeName indicates the pipe name • Must be of the form \\.\pipe\[path]pipename • You cannot create a pipe on a remote machine
CREATING NAMED PIPES (2 of 5) • fdwOpenMode specifies one of: • PIPE_ACCESS_DUPLEX • Equivalent to GENERIC_READ | GENERIC_WRITE • PIPE_ACCESS_INBOUND — Data flow is from the client to the server only • Equivalent to GENERIC_READ • PIPE_ACCESS_OUTBOUND • The mode can also specify FILE_FLAG_WRITE_THROUGH (not used with message pipes) and FILE_FLAG_OVERLAPPED
CREATING NAMED PIPES (3 of 5) • fdwPipeMode has three mutually exclusive flag pairs indicating whether writing is message- or byte-oriented, whether reading is by messages or blocks, and whether read operations block • PIPE_TYPE_BYTE and PIPE_TYPE_MESSAGE • Mutually exclusive • Writing stream of bytes or messages • Use the same type value for all pipe instances
CREATING NAMED PIPES (4 of 5) • PIPE_READMODE_BYTE and PIPE_READMODE_MESSAGE • Reading stream of bytes or messages • PIPE_READMODE_MESSAGE requires PIPE_TYPE_MESSAGE • PIPE_WAIT and PIPE_NOWAIT determine whether ReadFile will block • Use PIPE_WAIT as there are better ways to achieve asynchronous I/O
CREATING NAMED PIPES (5 of 5) • nMaxInstances — the number of pipe instances and, therefore, the number of simultaneous clients • Specify this same value for every CreateNamedPipe call for a given pipe • PIPE_UNLIMITED_INSTANCES allows the OS to base the number on available system resources • cbOutBuf and cbInBuf advise the OS on the required size of input and output buffers • dwTimeOut — default time-out period (in milliseconds) for the WaitNamedPipe function • lpsa is as in all the other “Create” functions
POLLING • BOOL PeekNamedPipe (HANDLE hPipe, • LPVOID lpvBuffer, DWORD cbBuffer, • LPDWORD lpcbRead, LPDWORD lpcbAvail, • LPDWORD lpcbMessage) • Nondestructively reads any bytes or messages in the pipe • Does not block • Returns immediately • Test *lpcbAvail to determine whether there is data in the pipe
NAMED PIPE CLIENT CONNECTIONS • A client can “connect” to a named pipe using CreateFile with the named pipe name • In many cases, the client and server are on the same machine, and the name would be of the form: \\.\pipe\[path]pipename • If the server is on a different machine, the name would be: \\servername\pipe\[path]pipename • Using the name “.” when the server is local, rather than the local machine name (this is faster)
NAMED PIPE STATUS FUNCTIONS(1 of 2) • Two functions are provided to interrogate pipe status information • GetNamedPipeHandleState returns information, given an open handle, on whether the pipe is in blocking or non-blocking mode, whether it is message- or byte-oriented, the number of pipe instances, and so on • SetNamedPipeHandleState allows you to set the same state attributes
NAMED PIPE STATUS FUNCTIONS(2 of 2) • Another function is provided to set state information • GetNamedPipeInfo determines whether the handle is for a client or server instance, buffer sizes, and so on
NAMED PIPE CONVENIENCE FUNCTIONS (1 of 7) • Given a “long-lived” connection, you can combine the WriteFile, ReadFile client sequence • There are also performance advantages as a connection is not required
NAMED PIPE CONVENIENCE FUNCTIONS (2 of 7) • BOOL TransactNamedPipe (HANDLE hNamedPipe, • LPVOID lpvWriteBuf, DWORD cbWriteBuf, • LPVOID lpvReadBuf, DWORD cbReadBuf, • LPDWORD lpcbRead, LPOVERLAPPED lpa) • Both output and input buffers are specified • *lpcbRead — The message length
NAMED PIPE CONVENIENCE FUNCTIONS (3 of 7) • BOOL CallNamedPipe (LPCTSTR lpszPipeName, • LPVOID lpvWriteBuf, DWORD cbWriteBuf, • LPVOID lpvReadBuf, DWORD cbReadBuf, • LPDWORD lpcbRead, DWORD dwTimeOut)
NAMED PIPE CONVENIENCE FUNCTIONS (4 of 7) • Synchronous: Create/Write/Read/Close client “short-lived” connection • Minimizes instance use but increases connection overhead • Specifies time-out period for the connection, in milliseconds or one of: • NMPWAIT_NOWAIT • NMPWAIT_WAIT_FOREVER • NMPWAIT_USE_DEFAULT_WAIT
NAMED PIPE CONVENIENCE FUNCTIONS (5 of 7) • BOOL WaitNamedPipe • (LPCTSTR lpszPipeName, • DWORD dwTimeOut) • The client can wait for an instance of the named pipe to become available
NAMED PIPE CONVENIENCE FUNCTIONS (6 of 7) • BOOL ConnectNamedPipe • (HANDLE hNamedPipe, • LPOVERLAPPED lpo) • BOOL DisconnectNamedPipe • (HANDLE hNamedPipe) • With lpo set to NULL, ConnectNamedPipe will return as soon as the server has a connection from a client
NAMED PIPE CONVENIENCE FUNCTIONS (7 of 7) • Normal return value is TRUE • Return value is FALSE if the client connected between the server’s CreateNamedPipe call and the ConnectNamedPipe call • In this case, GetLastError returns ERROR_PIPE_CONNECTED • Perform ReadFile, WriteFile operations between connect and disconnect
NAMED PIPE SECURITY • The important security rights for named pipes are: • GENERIC_READ • GENERIC_WRITE • SYNCHRONIZE (allowing a thread to wait on the pipe) • You normally get the appropriate rights depending on the access (duplex, inbound, outbound) • All three require SYNCHRONIZE
CLIENT-SERVER NAMED PIPES USING A SHORT-LIVED CONNECTION Client Server CreateNamedPipe ConnectNamedPipe WaitNamedPipe CreateFile WriteFile ReadFile WriteFile DisconnectNamedPipe ReadFile CloseHandle
TOPIC III Mailslots
MAILSLOTS (1 of 3) • Have names, so unrelated processes can use them for communication • Broadcast mechanisms which behave differently from named pipes • One-directional • Can have multiple readers and writers but often used in one-to-many configurations • A writer (“client”) does not know whether readers (“servers”) actually received a message
MAILSLOTS (2 of 3) • Can be located over a network domain • Message lengths are limited • Each mailslot server (don’t confuse with the application or named pipe server) creates a mailslot handle with CreateMailslot • The server waits to receive a mailslot message with a ReadFile call • A write-only client should open the mailslot with CreateFile and write messages with WriteFile
MAILSLOTS (3 of 3) • The open will fail (name not found) if there are no waiting readers • A client’s message can be read by all servers • They all receive the same message • The client, in performing the CreateFile, can use the form \\*\mailslot\mailslotname to connect to all mailslots with the name
USING A MAILSLOT This Message is Sent Periodically Mailslot Servers Application Client 0 Mailslot Client Application Server hMS = CreateMailslot ("\\.\mailslot\status"); ReadFile (hMS, &ServerStatus) /* Connect to this Server */ while (...) { Sleep (...); hMS = CreateFile ("\\*\mailslot\status"); · · · WriteFile (hMS, &StatusInformation) } · · · Application Client N hMS = CreateMailslot ("\\.\mailslot\status"); ReadFile (hMS, &ServerStatus) /* Connect to this Server */
USING MAILSLOTS (1 of 2) • One scenario: An application server, such as a database server, acting as a mailslot client, periodically broadcasts its name, named pipe name, and status information • Any application client that wants to find a server can receive this name by being a mailslot server • Note how the “client” and “server” terms are used • An application server can periodically broadcast its status (utilization, database size, etc.) to the application clients
USING MAILSLOTS (2 of 2) • As shown, there is a single mailslot client (writer) and multiple readers (servers) • With multiple application servers, you would have multiple mailslot readers and writers • A bulletin board service might have a single mailslot reader and multiple writers • Alternative: The application client also acts as the MS client and broadcasts a pipe name to mailslot (and application) servers
CREATING AND OPENING A MAILSLOT (1 of 3) • HANDLE CreateMailslot (LPCTSTR lpszName, • DWORD cbMaxMsg, DWORD dwReadTimeout, • LPSECURITY_ATTRIBUTES lpsa) • lpszName — Points to a mailslot name of the form: \\.\mailslot\[path]name • cbMaxMsg • Maximum size (in bytes) for messages a client can write • 0 means no limit
CREATING AND OPENING A MAILSLOT (2 of 3) • dwReadTimeout — Number of milliseconds a read operation will wait • 0 causes an immediate return • MAILSLOT_WAIT_FOREVER is an infinite wait (no timeout) • The client must specify the FILE_SHARE_READ flag • Functions GetMailslotInfo and SetMailslotInfo are similar to their named pipe counterparts
CREATING AND OPENING A MAILSLOT (3 of 3) • The client (writer), when opening a mailslot with CreateFile, uses the following name forms: • \\.\mailslot\[path]name • To retrieve a handle for a local mailslot • \\computername\mailslot\[path]name • To retrieve a handle for a mailslot on a specified machine • \\domainname\mailslot\[path]name • To return a handle representing all mailslots on machines in the domain • \\*\mailslot\[path]name • To return a handle representing mailslots on machines in the system’s primary domain
LAB 6–B (1 of 2) • Use named pipes to connect clients (the client program) to a “command line server” • The clients take a command line and send it to a known server for execution • The server returns the results to the client over the named pipe • Design your named pipe model carefully; there are several alternatives
LAB 6–B (2 of 2) • The solution consists of several components: • Client.c is built with locsrver.c • Run Client.exe in its own window • Server.c is built as Server.exe and runs in its own window or is controlled with the job management commands. Place the commands to be executed in the same directory as Server.exe. • Server.exe runs SrvrBcst.exe as a process that broadcasts the pipe name over a mailslot • Use SrvrBcst.c to build this executable • The header file, ClntSrvr.h, contains definitions used in the various programs