MailSlot is one way IPC mechanism is present in window, where server takes a passive role in receiving message from the client. This means that the client can only write and server can only read, vice versa is not possible, rather I never tried it.
According to
MSDN
“
A mailslot is a mechanism for one-way interprocess communications (IPC). Applications can store messages in a mailslot. The owner of the mailslot can retrieve messages that are stored there. These messages are typically sent over a network to either a specified computer or to all computers in a specified domain. A domain is a group of workstations and servers that share a group name.”
Only disadvantage I feel about this mechanism is that the limit of maximum message size is 424 bytes and instead of using reliable TCP service, it relies more on datagram packets. So keep both points in your mind while designing or using MailSlot in your application.
Through
Wikipedia article[
^] about MailSlot, I came to know NET SEND service, is created on MailSlots only, however I couldn’t find any official or unofficial link from Microsoft on the same.
So writing application based on
MailSlot, you have to utilize service of these APIS (Description is copied word by word from
MSDN):
- CreateMailSlot[^]: Creates a mailslot with the specified name.
- GetMailslotInfo[^]: Retrieves information about the specified mailslot.
- SetMailslotInfo[^]: Sets the time-out value used by the specified mailslot for a read operation.
- ReadFile: Above three and this function is used by server mailslot to create and read message in its mailslot queue.
- CreateFile: This function is utilized by the client to open existing MailSlot.
- WriteFile: This function is utilized by the client to write message for server mailslot, if
CreateFile
call is successful.
Now to create Server Mail Slot:
m_hServerMailSlot =
::CreateMailslot(m_szSlotName, 0, 0,
NULL );
if(m_hServerMailSlot == INVALID_HANDLE_VALUE)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,
0,
NULL
);
::MessageBox( NULL, (LPCTSTR)lpMsgBuf, L"Error", MB_OK | MB_ICONINFORMATION );
LocalFree( lpMsgBuf );
return;
}
MessageBox(L"Creation of Server MailSlot is successfull!!");
To Create Client MailSlot, which opens Server MailSlot
m_hClientMailSlot =
CreateFile(m_szSlotName,
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
if(m_hClientMailSlot == INVALID_HANDLE_VALUE)
{
MessageBox(L"unable to create client mail Slot");
return;
}
The communication between server and the client. The pseudo algorithm would be:
From Client Side:
- Open existing server mailslot using
CreateFile
API. - If successful, write to mailslot, using
WriteFile
API.
Code (includes client creation again)
m_hClientMailSlot =
CreateFile(m_szSlotName,
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
if(m_hClientMailSlot == INVALID_HANDLE_VALUE)
{
MessageBox(L"unable to create client mail Slot");
return;
}
TCHAR szData[MAX_PATH];
m_ctlEditWrite.GetWindowTextW(szData,MAX_PATH);
DWORD bytesWritten =0;
BOOL bFlag = WriteFile(m_hClientMailSlot,
szData,
_tcslen(szData) *sizeof(TCHAR),
&bytesWritten,
NULL);
CloseHandle(m_hClientMailSlot);
From Server Side
- Call GetMailslotInfo to retrieve number of message and message length.
- If
messageCount
is more than 0
(zero), call ReadFile
API to read message from MailSlot Queue.
Code
DWORD lpdNextMsgSize=0,lpdMessageCount=0,bytesRead=0;
BOOL bFlag = GetMailslotInfo(m_hServerMailSlot,
(LPDWORD)NULL, &lpdNextMsgSize,
&lpdMessageCount,
(LPDWORD) NULL);
if(bFlag == false) return;
if(lpdNextMsgSize == MAILSLOT_NO_MESSAGE) return;
TCHAR *szBuffer = new TCHAR[lpdNextMsgSize +1];
memset(szBuffer,0,(lpdNextMsgSize +1) * sizeof(TCHAR));
ReadFile(m_hServerMailSlot,szBuffer,lpdNextMsgSize,&bytesRead,NULL);
szBuffer[bytesRead]= '\0';
MessageBox(szBuffer);
delete [] szBuffer;