邮槽 - 维基百科,自由的百科全书

邮槽MailSlot)是Windows操作系统提供的一种单向进程间通信机制,可用于单机或者网络上的多机分布式环境。[1]

对于相对简短的低频率信息发送,使用邮槽通常比命名管道Unix域套接字更简单。如低频率的状态改变消息、作为对等点发现协议(peer-discovery protocol)的一部分。 邮槽机制允许短报文广播给域上的计算机中所有监听的进程。

特性

[编辑]

邮槽是一种服务器-客户接口。服务器创建邮槽,客户可以向命名的邮槽写入内容。只有服务器可以读取邮槽,因此邮槽是一种单向进程间通信机制。邮槽不提供报文已收到的确认,因此是不可靠通信。

邮槽基于RPC协议,可以在同一个网络域上跨计算机使用。

应用

[编辑]

Windows信使服务英语Windows Messenger service是邮槽的最知名的应用。信使服务是一个邮槽服务器,等待报文到达后,就弹窗显示在屏幕上。

邮槽的应用举例:

实现

[编辑]

邮槽命名

[编辑]

邮槽的名字,从形式上看类似于文件名。格式为\\ComputerName\mailslot\[path]name 本地邮槽名字中的ComputerName使用 . 来代替,即\\.\MailSlot\路径\文件名。如果向当前发送计算机所在工作组或域群发,可以使用 * 作为ComputerName。如果向指定工作组或域群发,应使用工作组或域名作为ComputerName

本机的Windows的信使服务使用的邮槽名字是\\.\MailSlot\ messngr

邮槽报文内容

[编辑]

邮槽报文内容包含:接收日期、发送人、接收人、具体内容。发送人、接收人、具体内容三项内容之间使用字节值0间隔。

创建邮槽

[编辑]

使用CreateMailslot

写入报文到邮槽

[编辑]

类似于写入普通文件,使用CreateFile打开邮槽,使用WriteFile将内容写入。

也可以使用NetMessageBufferSend直接发送。

读取邮槽报文

[编辑]

使用GetMailSlotInfo来判断邮槽内是否有内容。发现有内容的时候,可以使用ReadFile读取。如果ReadFile

在使用MAILSLOT_WAIT_FOREVER标志的邮槽上等待消息到来,这时邮槽突然中止运行,那么这个应用会被永远“挂起”直至重启Windows系统。为此,读邮槽的进程可以使用一个单独线程执行读挂起操作;主线程要结束进程时给一个全局标志位置位,并给邮槽写入一条消息以唤醒读邮槽线程。

SetMailslotInfo设置读取邮槽的超时值

例子

[编辑]
//邮槽服务器,负责创建邮槽,读取邮槽 #include <windows.h> #include <stdio.h> int main() {  HANDLE Mailslot;  char buffer[256];  DWORD NumberOfBytesRead;  //Create the mailslot  Mailslot = CreateMailslot("////.//Mailslot//Myslot",  //指定邮槽的名字   0,                  //可写入邮槽的消息的最大字节长度;为0表示接收任意长度消息   MAILSLOT_WAIT_FOREVER, //等待或不等待,单位毫秒,MAILSLOT_WAIT_FOREVER无限期等待,0立即返回    NULL);               //访问控制权限,一般为NULL  if (INVALID_HANDLE_VALUE == Mailslot)  {   printf("Failed to create a mailslot %d/n", GetLastError());   return -1;  }  //Read data from the mailslot forever!  while (0 != ReadFile(Mailslot, buffer, 256, &NumberOfBytesRead, NULL))  {   printf("%.*s/n",NumberOfBytesRead,buffer);  }  CloseHandle(Mailslot);  return 0; } 
//邮槽客户端,用于发送数据到邮槽服务器 #include <windows.h> #include <stdio.h> int main(int argc, char *argv[]) {     HANDLE Mailslot;     DWORD BytesWritten;     CHAR ServerName[256];     //从命令行接受要发送数据到的服务器名     if (argc < 2)     {         printf("Usage: client <server name>/n");         return -1;     }     sprintf(ServerName, "////%s//Mailslot//Myslot",argv[1]);     Mailslot = CreateFile(ServerName, //邮槽名字         GENERIC_WRITE,      //必须为GENERIC_WRITE,因为客户端只能向邮槽写入数据         FILE_SHARE_READ,   /必须为FILE_SHARE_READ,因为邮槽服务器需要做打开和读操作         NULL,          OPEN_EXISTING,     //邮槽在本地且还没有创建邮槽则当前调用失败;邮槽在远程,该参数无意义         FILE_ATTRIBUTE_NORMAL,         NULL);     if (INVALID_HANDLE_VALUE == Mailslot)     {         printf("WriteFile failed with error %d/n",GetLastError());         return -1;     }     if(0 == WriteFile(Mailslot, "This is a test", 14, &BytesWritten,NULL))     {         printf("WriteFile failed with error %d/n", GetLastError());         return -1;     }     printf("Wrote %d byteds/n", BytesWritten);     CloseHandle(Mailslot);     return 0; } 

参见

[编辑]

参考文献

[编辑]
  1. ^ MSDN: Mailslot Guide. [2017-09-03]. (原始内容存档于2017-09-03). 

外部链接

[编辑]