基于MailSlot邮槽的进程间通信实例
2008年11月6日星期四
实现进程间通信的方式有很多中,其中一种是使用邮槽来进行通信。这里编写了一个服务器----客户端程序来演示使用方法。
1、 服务器端创建邮槽MailSlot对象
2、 客户端打开MailSlot对象,并写入消息
3、 服务器端先获取MailSlot信息,然后读取消息
程序运行图如下:
程序代码如下:
服务器端:
BOOL FAR PASCAL MakeSlot()
{
// 邮槽名称都定义在//./mailslot//目录下
LPSTR lpszSlotName = ".//mailslot//sample_mailslot";
// 邮槽句柄hSlot1是个全局变量
hSlot1 = ::CreateMailslot(lpszSlotName, // 邮槽名称
0, // 对接受消息没有最大限制
MAILSLOT_WAIT_FOREVER, // 没有最大读延迟时间
(LPSECURITY_ATTRIBUTES)NULL); // 无安全属性
if (hSlot1 == INVALID_HANDLE_VALUE)
{
OutputDebugString("创建邮槽失败!");
return FALSE;
}
return TRUE;
}
BOOL FAR PASCAL ReadSlot()
{
DWORD cbMessage,cMessage,cbRead;
BOOL fResult;
LPSTR lpszBuffer;
cbMessage = cMessage = cbRead = 0;
// 服务器循环
printf("等待接受消息.../n");
int n = 1;
while(n < 1000)
{
fResult = ::GetMailslotInfo(hSlot1,
(LPDWORD)NULL,
&cbMessage,
&cMessage,
(LPDWORD)NULL);
if (cbMessage == MAILSLOT_NO_MESSAGE)
{
OutputDebugString("邮槽内没有信息!");
continue;
}
// 为消息分配内存
lpszBuffer = (LPSTR)GlobalAlloc(GPTR,cbMessage);
lpszBuffer[0] = '/0';
fResult = ::ReadFile(hSlot1,lpszBuffer,cbMessage,&cbRead,(LPOVERLAPPED)NULL);
printf("%s/n",lpszBuffer);
GlobalFree((HGLOBAL)lpszBuffer);
n++;
}
return fResult;
}
void EndMailSlot()
{
::CloseHandle(hSlot1);
}
客户端:
BOOL CMailSlotClientDlg::OnInitDialog()
{
……
// TODO: 在此添加额外的初始化代码
m_hFile = ::CreateFile(".//mailslot//sample_mailslot",
GENERIC_WRITE,
FILE_SHARE_READ,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
(HANDLE)NULL);
if (m_hFile == INVALID_HANDLE_VALUE)
{
MessageBox("创建客户端邮槽句柄失败!");
return FALSE;
}
return TRUE;
}
void CMailSlotClientDlg::OnBnClickedSend()
{
// TODO: 在此添加控件通知处理程序代码
LPSTR lpszMessage = new char[MAX_PATH];
GetDlgItemText(IDC_TEXT,lpszMessage,MAX_PATH);
BOOL fResult;
DWORD cbWritten;
fResult = ::WriteFile(m_hFile,
lpszMessage,
(DWORD)lstrlen(lpszMessage) + 1,
&cbWritten,
(LPOVERLAPPED)NULL);
if (!fResult)
{
MessageBox("发送消息错误!");
}
delete [] lpszMessage;
SetDlgItemText(IDC_TEXT,"");
GetDlgItem(IDC_TEXT)->SetFocus();
}
BOOL CMailSlotClientDlg::DestroyWindow()
{
// TODO: 在此添加专用代码和/或调用基类
::CloseHandle(m_hFile);
return CDialog::DestroyWindow();
}