进程间通讯-邮槽
邮槽是Windows系统提供的一种单向通信的机制。即进程中的一方只能写入或读取数据,而另一方则只能读取或写入数据。通过邮槽,用户可以实现一对多或跨网络的进程之间的通讯。但是,邮槽能传输的数据非常小,一般在400KB左右。如果用户操作的数据过大,可能会导致邮槽不能正常工作。
优缺点:
邮槽最大的一个缺点便是只允许从客户机到服务器,建立一种不可靠的单向数据通信。
邮槽最大的一个优点在于,它们使客户机应用能够非常容易地将广播消息发送给一个或多个服务器应用。
1.创建邮槽(服务端)
调用CreateMailslot()函数,函数原型:
HANDLE CreateMailslot(
LPCTSTR lpName,
DWORD nMaxMessageSize,
DWORD lReadTimeout,
LPSECURITY_ATTRIBUTES lpSecurityAttributes
);
该函数的作用是创建邮槽并返回该邮槽的句柄。如果该函数调用成功,将返回创建邮槽的句柄。否则,函数将返回INVALID_HANDLE_VALUE,表示创建邮槽失败。其中,
- 参数lpName表示邮槽的名称。邮槽名称格式为“\\.\mailslot\name”。其中,name表示邮槽的名称。在VC开发环境中应将其值指定为“\\\\.\\mailslot\\name”。如果用户是在不同主机上运行,则需要将字符“.”改为对方主机名称。
- 参数nMaxMessageSize指定将通过邮槽发送或接收的消息大小的最大值。一般设置为0表示消息的大小为任意值。
- 参数lReadTimeout表示程序读取操作的超时时间。如果该参数为0,则当邮槽中没有任何消息时,该函数将立即返回。如果该参数值为MAILSLOT_WAIT_FOREVER,则表示该函数将等待,直到邮槽中有消息,函数才返回。
- 参数lpSecurityAttributes是指向结构体SECURITY_ATTRIBUTES的指针,表示邮槽的安全属性。一般情况下,用户将该参数值指定为NULL,表示邮槽使用默认的安全属性。
2.打开邮槽(客户端)
调用CreateFile()函数,函数原型:
HANDLE CreateFile(
LPCTSTR lpFileName, //同邮槽的lpName
DWORD dwDesiredAccess, //必须用GENERIC_WRITE
DWORD dwShareMode, //必须为FILE_SHARE_READ
LPSECURITY_ATTRIBUTES lpSecurityAttributes, //一般设置为NULL
DWORD dwCreationDisposition, //标志一般设为OPEN_EXISTING
DWORD dwFlagsAndAttributes, //应定义成FILE_ATTRIBUTE_NORMAL
HANDLE hTemplateFile //与第2个参数有关,邮槽置空NULL
);
该函数的作用是打开一个文件并返回该文件的句柄。
例子:
HANDLE mail;
mail=CreateFile("\\\\.\\mailslot\\mysolt", GENERIC_WRITE, FILE_SHARE_READ,
NULL ,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
3.操作邮槽
用户操作邮槽与操作文件一样,都是通过调用函数ReadFile()和WriteFile()进行读写操作。在邮槽中,服务端一般用ReadFile(),客户端一般用WriteFile()进行读写操作。
4.关闭邮槽
用户在程序中使用完邮槽之后,必须调用函数CloseHandle()将创建的邮槽关闭。
函数原型:
BOOL CloseHandle(
HANDLE hObject //填要关闭的句柄
);
5.邮槽服务端实例
#include <windows.h>
#include <stdio.h>
int main()
{
HANDLE mail;
mail=CreateMailslot("\\\\.\\mailslot\\mysolt", 0, MAILSLOT_WAIT_FOREVER, NULL);
if (mail==INVALID_HANDLE_VALUE){
printf("创建邮槽失败!\r\n");
CloseHandle(mail);
}
else{
printf("创建邮槽成功,正在读取数据……!\r\n");
char text[200];
DWORD readtext;
if (ReadFile(mail, text, 200, &readtext, NULL)){
printf(text);
}
else{
printf("\r\n读取数据失败\r\n");
}
CloseHandle(mail);
Sleep(1000);
return 0;
}
}
6.邮槽客户端实例
#include <windows.h>
#include <stdio.h>
int main()
{
HANDLE mail;
char text[]="您好,this is a message";
DWORD writetext;
mail=CreateFile("\\\\.\\mailslot\\mysolt", GENERIC_WRITE, FILE_SHARE_READ, NULL ,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == mail){
printf("打开邮槽失败!\r\n");
}
else{
if (WriteFile(mail, text, sizeof(text), &writetext, NULL)){
Sleep(1000);
printf("数据写入成功\r\n");
}
else{
printf("数据写入失败\r\n");
}
}
CloseHandle(mail);
Sleep(1000);
return 0;
}