进程间通讯总结 (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:
Contents of the mailslot: Message one for mailslot.
Message #1 of 2
Message #2 of 2
Message #1 of 1
Waiting for a message...
参考:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365794(v=vs.85).aspx
- 进程间通讯总结 (3)
- 进程间通讯总结
- 进程间通讯:总结
- 进程间通讯方法总结
- 进程间通讯方法总结
- 进程间通讯方法总结
- 进程间通讯方法总结
- 进程间通讯的总结
- 进程间通讯方式总结
- 进程间通讯总结 (1)
- 进程间通讯总结 (2)
- 进程间通讯总结 (4)
- 进程间通讯总结 (5)
- 进程间通讯总结 (6)
- 进程间通讯方式总结
- 进程间通讯方法总结(转)
- 进程间通讯方法总结参考(转)
- Android 进程间通讯Binder异常总结
- Oracle学习笔记(一)——Oracle介绍及安装
- 中介者模式及MVP、MVVM上的体现
- jvm(6)-Class字节码文件结构总结
- 使用Go语言工作400天后的感受
- Android 第八天_重置版_服务service
- 进程间通讯总结 (3)
- C++实现的委托机制
- JS进阶书籍
- Android 第八天_重置版_服务_注意事项
- 文本分类——KNN算法
- html-progress meter
- java 观察者模式
- Java中List与数组互相转化
- angularjs 表单验证