![]() |
General Programming »
Threads, Processes & IPC »
Inter-Process Communication
Intermediate
IPCWorkshopBy Venkat RamanThis article describes a data transfer over various IPC mechansisms |
VC6Win2K, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||


The main objective of this application was to learn about the various
Inter Process Communication methods and how it can be used for data transfer. This
application also helps us to decide which of the available IPC methods is
best to use. For a description of these IPC mechanisms I have taken a structure
pointer named EmployeeData whose pointer is passed from the client to the
server. For simplicity this demo application describes one way inter-process communication
(ie) from the client to the server. The server will just
listen to its clients. Here I have described 5 types of IPCs.
| 1 | Clipboard | Local Mc |
| 2 | File Mapping | Local Mc |
| 3 | Mailslots | Local Mc\Intranet |
| 4 | Named Pipes | Local Mc\Intranet |
| 5 | Sockets | Local Mc\Intranet\Internet |
For detailed Information about the Inter Process Communication, you should read MSDN Library\Platform SDK Documentation\Base Services\InterProcess Communications
The clipboard is a set of functions and messages that enable applications to transfer data. Because all applications have access to the clipboard, data can be easily transferred between applications or within an application.
To Write in the Clipboard
OpenClipboard
SetClipboardData
CloseClipboard.
To Read from the Clipbaord
OpenClipboard
SDK functions are available for the above operations. CClipboard is a class
that provides developers with a simple way to implement the clipboard functions.
Write the data in the clipboard as easy as shown below.
CClipboard m_objClipboard;
m_objClipboard.Open();
m_objClipboard.Write( (char*)data, size );
Read the data from the clipboard as shown below.
CClipboard m_objClipboard; m_objClipboard.Open(); m_objClipboard.Read( data, size);
Many standard clipboard formats are available. If you want to support more applications to work on the clipboard at the same time, then register a new clipboard format. (Optional)
m_objClipboard.Register("New format") // any nameIn this demo application, the client notifies the server by posting message with handle
HWND_BROADCAST.
File mapping is an efficient way for two or more processes on the same computer to share data. Here i have not described about the synchronization of the process. In order to access the file's contents, the processes uses virtual address space called file view. Processes read from and write to the file view using pointers, just as they would with dynamically allocated memory.
To write in the file
MapViewOfFile)
To Read from the File
MapViewOfFile)
CFileMapping is a class which encapsulates the file mapping functions provided by the SDK.
Using the above class sharing the data between two or more processes can be easily done.
Write the data in the shared file as shown below.
CFileMapping m_objFilemapping; m_objFilemapping.Initialize( "ANY FILE NAME", size/* size of the filemap*/); m_objFilemapping.Write( (char*) data);
If the name of the filemap is known then we can read the data from any other process as shown below.
CFileMapping m_objFilemapping; m_objFilemapping.Initialize( "ANY FILE NAME", size); m_objFilemapping.Read( data );
Notify the server using HWND_BROADCAST handle. we have successfully transferred the
pointer between two processes on the same local machine. we get curious of how
to pass this pointer in the Intranet if this two processes resides on different computers.
Next section is Named Pipes and Mailslots.
To write in the Mailslot
To Read from the Mailslot
CMailslot is a class that can be used to create both mail slot server as well as mail slot client. | Mailslot Server | Mailslot Client |
CMailslot m_objMailslot; | CMailslot m_objMailslot; |
m_objMailslot.Initialize( | m_objMailslot.Initialize( |
m_objMailslot.Listen(messageId, lparam); | |
m_objMailslot.Write(data) | |
| fired to messageId | |
m_objMailslot.Read(data); |
Internal Details :- A mailslot server is a process that creates and owns a mailslot. When the server creates a mailslot it receives a mailslot handle.
m_strMailslot.Format("\\\\.\\mailslot\\%s", pMailslotName); m_hInputslot = CreateMailslot( m_strMailslot, // mailslot name 0, // message can be of any size MAILSLOT_WAIT_FOREVER, // waits forever for a message NULL // It cannot be inherited );
The mailslot server can read messages in the mailslot at any time. For the automatic response of the server
you can use Listen(messageId, lparam). Here the messageId is the
RegisterWindowMessage identity. In the listen function, a worker thread is created
to continuously check for messages in the mailslot.
If any messages found, it fires to the messageId for the read operation.
The total messages will be reduced only at the end of read operation. Hence in this function
SendMessageTimeOut is used in order to decrement the message count.
Let us check the total messages in the mailslot.
while(1) { GetMailslotInfo( This->GetInputslot(), NULL, &message, &noofMessages, NULL ); if( noofMessages > 0) { // The total messages will be reduced only at the end of read operation // Hence don't use post message operation. LRESULT returnVal = ::SendMessageTimeout(HWND_BROADCAST, This->GetTransferMessage(), NULL, This->GetLparam(), SMTO_BLOCK, MESSAGETIMEOUT, NULL); if( returnVal == 0) TRACE("Unable to send message. Error is %d", GetLastError()); } }
Read the mailslot message using the created mailslot handle.
while( noofMessages != 0) { ReadFile( m_hInputslot, buffer, size, &dataRead, NULL); GetMailslotInfo( m_hInputslot, // mailslot handle 0, // message can be of any size &message, // size of next message &noofMessages, // number of messages NULL // read time-out interval ); }
A mailslot client is a process that writes a message to a mailslot. Any process that has the
name of a mailslot can put a message there. New messages follow any existing messages in the mailslot.
The client opens the mailslot using CreateFile.
m_strMailslot.Format("\\\\*\\mailslot\\%s", pMailslotName); m_hOutputslot = CreateFile( m_strMailslot, // file name GENERIC_WRITE, // Only Write Permission 0, // cannot be shared NULL, // SD OPEN_EXISTING, // Opens the file. fails if // file doesn't exist FILE_ATTRIBUTE_NORMAL, // file attributes NULL // handle to template file );
Write the data in the mailslot is as simple as shown below.
DWORD sizeWritten; WriteFile( m_hOutputslot, pData, m_nSize, &sizeWritten, NULL); if( sizeWritten == 0 ) TRACE(" Unable to write to the Mail slot. Error is %d", GetLastError() );
A named pipe is a named, one-way or duplex pipe for communication between the pipe server and one or more pipe clients. Named pipes are like telephone calls: you talk only to one party, but you know that the message is being received.
To Write in the pipe.
To read from the pipe
CNamedPipe is a simple class used to support named pipe operations.
| Named Pipe Server | Named Pipe Client |
CNamedPipe m_objNamedPipe; | CNamedPipe m_objNamedPipe; |
m_objNamedPipe.Initialize( |
m_objNamedPipe.Initialize( |
m_objNamedPipe.Listen(messageId, lparam); | |
m_objNamedPipe.Write(data) | |
fired to messageId | |
m_objNamedPipe.Read(data); |
Call the Initialize function of the CNamedPipe to create named pipe server and named pipe client.
A named pipe server, refers to a process that creates a named pipe.
m_strPipeName.Format("\\\\.\\pipe\\%s", pPipeName); m_hInputPipeHandle = CreateNamedPipe( m_strPipeName, // pipe name PIPE_ACCESS_INBOUND, // client to the server PIPE_WAIT, // Blocking mode is enabled 1, // support given to only one client 0, // output buffer size 0, // input buffer size PIPE_TIMEOUT, // time-out interval NULL // Security Attributes );
If the security attribute is NULL, then the transfer of data will be available to only Local machine. Inorder to support across the network, set the security attribute.
SECURITY_ATTRIBUTES saPipe;
saPipe.lpSecurityDescriptor = (PSECURITY_DESCRIPTOR) malloc
(SECURITY_DESCRIPTOR_MIN_LENGTH);
InitializeSecurityDescriptor(saPipe.lpSecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION);
// Access Control list is asiigned as NULL inorder to allow all access to
// the object.
SetSecurityDescriptorDacl(saPipe.lpSecurityDescriptor, TRUE, (PACL) NULL,FALSE);
saPipe.nLength = sizeof(saPipe);
saPipe.bInheritHandle = TRUE;
This created pipe will listen continuously for the client to write data. Inorder to satisfy this condition a worker thread is created. In the mailslot the infinite thread is an optional, we can give an external control to read from the mailslot. Since the pipe is created in the blocking mode, this infinite thread is necessary. Otherwise the client will get hanged while writing data. This thread named as Listenerproc will continuously read the file. If the data is read then it will notify to the messageId.
UINT ListenerProc( LPVOID pNamedPipe )
{
CNamedPipe* This = (CNamedPipe*)pNamedPipe;
if( This == NULL )
return 0;
int size = This->GetSize();
// assign the size of the data to be read.
ASSERT( size != 0 );
ASSERT( This->GetTransferMessage() != NULL);
char* buff = new char[size];
DWORD dataRead;
while(1) {
BOOL isRead = ReadFile( This->GetInputPipeHandle(),
buff, size, &dataRead, NULL);
if( dataRead > 0) {
// acts as a post thread message
// since this is internal to the process, it can also
// work on the network satisfying the named pipe advantage.
::PostMessage( HWND_BROADCAST,
This->GetTransferMessage(), (WPARAM)buff, This->GetLparam());
}
}
return 1;
}
A named pipe client, opens the named pipe handle using CreateFile. With the help of the handle the client writes the data to the server. This procedure is same as in the mailslot. please refer above.
| Server Socket | Client Socket |
| Construct a socket | Construct a socket |
| Create the socket | Create the socket |
| Start listening | |
| <--- Connect | |
| Accept the client | |
| <--- Send Data | |
| Receive data. |
CDerivedSocket is a class derived from the MFC class CSocket.
This class only describes the data transfer from the client to the server.
Version 1.0
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 29 Jan 2003 Editor: Chris Maunder |
Copyright 2003 by Venkat Raman Everything else Copyright © CodeProject, 1999-2009 Web15 | Advertise on the Code Project |