Windows进程通信(IPC)之邮件槽
邮件槽提供了不可靠的单向数据传输,但是邮件槽支持多播。邮件槽服务器使用CreateMailslot函数来创建一个邮件槽。C热阿特Mailslot接受形如"\\.\\Mailslot\MailslotName"(客户可以指定"\\.\"为本地计算机)的UNC名称作为一个输入的参数。如命名管道一样,邮件槽服务器只能创建它当前所在机器上的邮件槽,并且分配给邮件槽的名称也可以包含子目录。CreateMailslot也接受一个安全描述符,将其用于控制客户对该邮件槽的访问。CreateMailslot返回的句柄是可重叠的(overlapped)这意味着在该剧并上执行的操作,比如发送和接收消息是异步的。
服务器在创建了一个邮件槽之后,它只是简单的在代表该邮件槽的句柄上执行ReadFile函数,以便监听来自客户的消息。
如果客户想要得到一个代表它所在域中符合某个给定名称的所有邮件槽的句柄,那么,它可以按照格式"\\*\Mailslot\MailslotName"来指定该名称;如果客户想要给另一个不同域中某个给定名称的所有油槽广播消息,则它使用的格式是“\\DomainName\Mailslot\MailslotName”。
在得到邮件槽客户端的句柄后,客户端就可以调用WriteFile发送消息了。由于邮件槽的实现方式的原因,只有小于424字节的消息才可以被发送。如果一个消息大于424字节,那么邮件槽的实现代码就使用可靠地通讯机制,那么多播也就不再可能。
下面是一个邮件槽通讯的Demo
Server端:
#include "stdafx.h" #include <Windows.h> #define MAILSLOT_NAME L"\\\\.\\Mailslot\\MailslotName" #define BUFFER_SIZE 0x100 int main() { char BufferData[BUFFER_SIZE] = { 0 }; DWORD BufferLength = 0; HANDLE MailsoltHandle = CreateMailslot(MAILSLOT_NAME, 0, MAILSLOT_WAIT_FOREVER, NULL); if (MailsoltHandle == INVALID_HANDLE_VALUE) { printf("Can't Create a Mailsolt!\r\n"); return 0; } while (true) { BOOL bOk = ReadFile(MailsoltHandle, BufferData, 0x100, &BufferLength, NULL); if (!strcmp(BufferData, "Bye")) { break; } printf("Client: %s\r\n", BufferData); } CloseHandle(MailsoltHandle); return 0; }
Client端:
#include "stdafx.h" #include <Windows.h> #include <iostream> using namespace std; #define MAILSLOT_NAME L"\\\\.\\Mailslot\\MailslotName" #define BUFFER_SIZE 0x100 int main() { char BufferData[BUFFER_SIZE]; DWORD BufferLength = 0; HANDLE MailsoltHandle = CreateFile(MAILSLOT_NAME, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (MailsoltHandle==INVALID_HANDLE_VALUE) { printf("Can't Create File! Please Open The Server!\r\n"); return 0; } while (true) { cout << "Please Input The Word!" <<endl; cin >> BufferData; if (!strcmp(BufferData,"Bye")) { WriteFile(MailsoltHandle, BufferData, BUFFER_SIZE, &BufferLength, NULL); break; } BOOL bOk = WriteFile(MailsoltHandle, BufferData, BUFFER_SIZE, &BufferLength, NULL); if (!bOk) { CloseHandle(MailsoltHandle); } } CloseHandle(MailsoltHandle); return 0; }