进程间通讯总结 (3)

来源:互联网 发布:期货交易软件有哪些 编辑:程序博客网 时间:2024/05/30 23:14

Using a Mailslot for IPC

Mailslots provide one-way communication. Any process that creates a mailslot is amailslot server. Other processes, calledmailslot clients, send messages to the mailslot server by writing a message to its mailslot. Incoming messages are always appended to the mailslot. The mailslot saves the messages until the mailslot server has read them. A process can be both a mailslot server and a mailslot client, so two-way communication is possible using multiple mailslots.

A mailslot client can send a message to a mailslot on its local computer, to a mailslot on another computer, or to all mailslots with the same name on all computers in a specified network domain. Messages broadcast to all mailslots on a domain can be no longer than 400 bytes, whereas messages sent to a single mailslot are limited only by the maximum message size specified by the mailslot server when it created the mailslot.

Key Point:  Mailslots offer an easy way for applications to send and receive short messages. They also provide the ability to broadcast messages across all computers in a network domain.

本质上来说:A mailslot is a pseudo file that resides in memory, and you use standard file functions to access it. The data in a mailslot message can be in any form, but cannot be larger than 424 bytes when sent between computers. Unlike disk files, mailslots are temporary. When all handles to a mailslot are closed, the mailslot and all the data it contains are deleted.

A mailslot server is a process that creates and owns a mailslot. When the server creates a mailslot, it receives a mailslot handle.

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.

邮件槽是围绕Windows文件系统接口设计出来的。客户机和服务器应用需要使用标准的Win32文件系统I/O函数,如ReadFile和WriteFile等,以便在邮件槽上收发数据,同时利用Win32文件系统的命名规则。

邮件槽标识遵守下述命名规则

//server/Mailslot/[path]name

第一部分 //server 对应服务器名,在其上创建邮件槽并在上面运行服务器程序。取值可以是小数点(.),一个星号(*),一个域名或者一个真正的服务器名字。所谓“域,是一系列工作站和服务器的组合,它们共用一个相同的组名。

第二部分 /Mailslot 是固定的字符串。

第三部分 /[path]name,其中“path”代表路径,可指多级目录。

下面都是合法的名字:

//Oreo/Mailslot/Mymailslot

//Testserver/Mailslot/Cooldirectory/Funtest/Anothermailslot

//./Mailslot/Easymailslot

//*/Mailslot/Myslot

服务器:

1、用CreateMailslot API函数 (指定邮件槽名称) 创建一个邮件槽并获得句柄。

2、调用ReadFile API函数,使用已有的邮件槽句柄从任何客户机接收数据。

3、用CloseHandle函数关闭邮件槽句柄。

客户机

1、使用CreateFile,针对想要向其传送数据的邮件槽(指定同一邮件槽名称为文件名),打开指向它的一个引用句柄。

2、调用WriteFile,向邮件槽写入数据。

3、完成数据写入后,用CloseHandle关闭打开的邮件槽句柄。

Code Sample:

Server Side

#include <windows.h>#include <tchar.h>#include <stdio.h>#include <strsafe.h>HANDLE hSlot;LPTSTR SlotName = TEXT("\\\\.\\mailslot\\sample_mailslot");BOOL WINAPI MakeSlot(LPTSTR lpszSlotName){hSlot = CreateMailslot(lpszSlotName,0,                             // no maximum message size MAILSLOT_WAIT_FOREVER,         // no time-out for operations (LPSECURITY_ATTRIBUTES)NULL);  // default securityif (hSlot == INVALID_HANDLE_VALUE){printf("CreateMailslot failed with %d\n", GetLastError());return FALSE;}else printf("Mailslot created successfully.\n");return TRUE;}BOOL WriteSlot(HANDLE hSlot, LPTSTR lpszMessage){BOOL fResult;DWORD cbWritten;DWORD nNumberOfBytesToWrite = (DWORD)(lstrlen(lpszMessage) + 1)*sizeof(TCHAR);fResult = WriteFile(hSlot,lpszMessage,nNumberOfBytesToWrite,&cbWritten,(LPOVERLAPPED)NULL);if (!fResult){printf("WriteFile failed with %d.\n", GetLastError());return FALSE;}printf("Slot written to successfully.\n");return TRUE;}BOOL ReadSlot(){DWORD cbMessage, cMessage, cbRead;BOOL fResult;LPTSTR lpszBuffer;TCHAR achID[80];DWORD cAllMessages;HANDLE hEvent;OVERLAPPED ov;cbMessage = cMessage = cbRead = 0;hEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("ExampleSlot"));if (NULL == hEvent)return FALSE;ov.Offset = 0;ov.OffsetHigh = 0;ov.hEvent = hEvent;fResult = GetMailslotInfo(hSlot,   // mailslot handle (LPDWORD)NULL,                 // no maximum message size &cbMessage,                    // size of next message &cMessage,                     // number of messages (LPDWORD)NULL);                // no read time-out if (!fResult){printf("GetMailslotInfo failed with %d.\n", GetLastError());return FALSE;}if (cbMessage == MAILSLOT_NO_MESSAGE){printf("Waiting for a message...\n");return TRUE;}cAllMessages = cMessage;while (cMessage != 0)  // retrieve all messages{// Create a message-number string. StringCchPrintf((LPTSTR)achID,80,TEXT("\nMessage #%d of %d\n"),cAllMessages - cMessage + 1,cAllMessages);// Allocate memory for the message. lpszBuffer = (LPTSTR)GlobalAlloc(GPTR,lstrlen((LPTSTR)achID)*sizeof(TCHAR)+cbMessage);if (NULL == lpszBuffer)return FALSE;lpszBuffer[0] = '\0';fResult = ReadFile(hSlot,lpszBuffer,cbMessage,&cbRead,&ov);if (!fResult){printf("ReadFile failed with %d.\n", GetLastError());GlobalFree((HGLOBAL)lpszBuffer);return FALSE;}// Concatenate the message and the message-number string. StringCbCat(lpszBuffer,lstrlen((LPTSTR)achID)*sizeof(TCHAR)+cbMessage,(LPTSTR)achID);// Display the message. _tprintf(TEXT("Contents of the mailslot: %s\n"), lpszBuffer);GlobalFree((HGLOBAL)lpszBuffer);fResult = GetMailslotInfo(hSlot,  // mailslot handle (LPDWORD)NULL,               // no maximum message size &cbMessage,                   // size of next message &cMessage,                    // number of messages (LPDWORD)NULL);              // no read time-out if (!fResult){printf("GetMailslotInfo failed (%d)\n", GetLastError());return FALSE;}}CloseHandle(hEvent);return TRUE;}int _tmain(int argc, _TCHAR* argv[]){MakeSlot(SlotName);Sleep(5000);while (TRUE){ReadSlot();Sleep(3000);}CloseHandle(hSlot);return 0;}

Client Side

#include <windows.h>#include <stdio.h>LPTSTR SlotName = TEXT("\\\\.\\mailslot\\sample_mailslot");BOOL WriteSlot(HANDLE hSlot, LPTSTR lpszMessage){BOOL fResult;DWORD cbWritten;fResult = WriteFile(hSlot,lpszMessage,(DWORD)(lstrlen(lpszMessage) + 1)*sizeof(TCHAR),&cbWritten,(LPOVERLAPPED)NULL);if (!fResult){printf("WriteFile failed with %d.\n", GetLastError());return FALSE;}printf("Slot written to successfully.\n");return TRUE;}int main(){HANDLE hFile;hFile = CreateFile(SlotName,GENERIC_WRITE,FILE_SHARE_READ,(LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,(HANDLE)NULL);if (hFile == INVALID_HANDLE_VALUE){printf("CreateFile failed with %d.\n", GetLastError());return FALSE;}WriteSlot(hFile, TEXT("Message one for mailslot."));WriteSlot(hFile, TEXT("Message two for mailslot."));Sleep(5000);WriteSlot(hFile, TEXT("Message three for mailslot."));CloseHandle(hFile);return TRUE;}


Output in server side:

Mailslot created successfully.
Contents of the mailslot: Message one for mailslot.
Message #1 of 2

Contents of the mailslot: Message two for mailslot.
Message #2 of 2

Contents of the mailslot: Message three for mailslot.
Message #1 of 1

Waiting for a message...
Waiting for a message...


参考:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa365794(v=vs.85).aspx


0 0
原创粉丝点击