进程间通信

进程的地址空间是私有的。出于安全性的目的,如果一个进程不具有特殊的权限,是无法访问另外一个进程的内存空间的,也无法知道内存中保存的数据的意义。但是在一些具体的应用情况下需要多个进行相互配合,有时计算机用户也需要在多个应用程序之间交换数据。
Windows系统下,在进程间通信或共享数据的方式如下。

  • 邮槽( Mailslot)。邮槽是最为简单的进程间数据共享方式,一个进程创建并拥有一个邮槽,其他进程都可以打开这个邮槽并向其发送消息。
  • 管道(Pipe)。实质是一种共享的内存,由一个进程创建,其他进程连接,并可进行双向的通信。
  • 剪贴板( Clipboard)。剪贴板是重要的进程间数据共享方式,所有的进程都可以设置和修改剪贴板,也都可以从剪贴板获取内容。
  • 消息,具体是指WM_COPYDATA消息。消息具有参数wParam和lParam。但是wParam和lParam最多是32位的。而WM_COPYDATA消息的参数不受wParam和lParam数据大小的限制,可以用于在进程间传递数据。
  • 网络。网络可以在不同主机上的不同程序间通信,当然也可以在相同主机上的不同程序间通信。
  • FileMapping.

邮槽

使用邮槽通信的进程分为服务端和客户端。邮槽由服务端创建,在创建时需要指定邮槽名,创建后服务端得到邮槽的句柄。在邮槽创建后,客户端可以通过邮槽名打开邮槽,在获得句柄后可以向邮槽写入消息。
邮槽通信是单向的,只有服务端才能从邮槽中读取消息,客户端只能写入消息。消息是先入先出的。客户端先写入的消息在服务端先被读取。
通过邮槽通信的数据可以是任意格式的,但是一条消息不能大于424字节。
邮槽除了在本机内进行进程间通信外,在主机间也可以通信。但是在主机间进行邮槽通信,数据通过网络传播时使用的是数据报协议(UDP),所以是一种不可靠的通信。通过网络进行邮槽通信时,客户端必须知道服务端的主机名或域名。

实例

server:
/*进程间mailslot通信服务器端
创建了一个名为“\\\\.\\mailslot\\sample_mailslot”的邮槽,然后使用GetMailslotInfo函数读取消息数量。如果没有消息,则等待3s获取信息。循环直至有消息到达,然后一次性读出全部消息。*/
#include <windows.h>
#include <stdio.h>
HANDLE hSlot;
LPTSTR lpszSlotName = TEXT("\\\\.\\mailslot\\sample_mailslot");
void main()
{
DWORD cbMessage, cMessage, cbRead,cAllMessages;
BOOL bResult;
TCHAR lpszBuffer[1000];
TCHAR achID[80];
cbMessage = cMessage = cbRead = 0;
hSlot = CreateMailslot(
lpszSlotName, // mailslot 名
0, // 不限制消息大小
MAILSLOT_WAIT_FOREVER, // 无超时
NULL); if (hSlot == INVALID_HANDLE_VALUE)
{
printf("CreateMailslot failed with %d\n", GetLastError());
return ;
}
else
printf("Mailslot created successfully.\n"); while(1)
{
// 获取mailslot信息
bResult = GetMailslotInfo(hSlot, // mailslot 句柄
(LPDWORD) NULL, // 无最大消息限制
&cbMessage, // 下一条消息的大小
&cMessage, // 消息的数量
(LPDWORD) NULL); // 无时限
if (!bResult)
{
printf("GetMailslotInfo failed with %d.\n", GetLastError());
return ;
}
printf("MAILSLOT_NO_MESSAGE \n");
if (cbMessage == MAILSLOT_NO_MESSAGE)
{
// 没有消息,过一段时间再去读
Sleep(3000);
continue;
}
printf("has MAILSLOT_NO_MESSAGE\n");
cAllMessages = cMessage;
while (cMessage != 0) // 获取全部消息,有可能不只一条
{
// 提示信息
wsprintf(achID, "\nMessage #%d of %d\n", cAllMessages - cMessage + 1, cAllMessages);
// 读取消息
if(!ReadFile(hSlot,lpszBuffer,cbMessage,&cbRead,NULL))
{
printf("ReadFile failed with %d.\n", GetLastError());
return ;
}
lstrcat(lpszBuffer, achID); //连接
printf("Contents of the mailslot: %s\n", lpszBuffer);//显示
bResult = GetMailslotInfo(hSlot,NULL,&cbMessage,&cMessage,NULL); // 计算剩余的消息数,若cMessage=0,则退出子循环
if (!bResult)
{
printf("GetMailslotInfo failed (%d)\n", GetLastError());
return ;
}
}
}
}

client:

/*进程间mailslot通信客户端
客户端向邮槽发送消息需要首先打开邮槽,然后直接使用WriteFile函数写入。打开邮槽使用CreateFile函数。客户端在打开邮槽时需要知道邮槽名。*/
#include <windows.h>
#include <stdio.h>
LPTSTR lpszSlotName = TEXT("\\\\.\\mailslot\\sample_mailslot"); // mailslot名
LPTSTR lpszMessage = TEXT("Test Message for mailslot "); // 通信的内容
void main()
{
DWORD cbWritten;
DWORD cbMessage;
// 打开mailslot
HANDLE hFile = CreateFile(lpszSlotName,
GENERIC_WRITE, // 可写
FILE_SHARE_READ,
(LPSECURITY_ATTRIBUTES) NULL,
OPEN_EXISTING, // 打开一个已经存在的mailslot,应该由服务端已经创建
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("CreateFile failed with %d.\n", GetLastError());
return ;
}
// 向mailslot写入
int num=50;
while(num)
{
Sleep(2000);
num--;
if(!WriteFile(hFile,
lpszMessage,
(DWORD) (lstrlen(lpszMessage)+1),
&cbWritten,
(LPOVERLAPPED) NULL))
{
printf("WriteFile failed with %d.\n", GetLastError());
return ;
}
printf("Slot written to successfully.\n");
}
CloseHandle(hFile); // 结束
}

结果:

[Win]进程间通信——邮槽Mailslot的更多相关文章

  1. 【IPC进程间通讯之中的一个】邮槽MailSlot

    IPC进程间通信+邮槽MailSlot                IPC(Inter-Process Communication.进程间通信).        现代计算机採用虚拟内存机制,为进程提 ...

  2. windows 邮槽mailslot 在服务程序内建立后客户端无权限访问(GetLastError() == 5)的问题

    邮槽创建在服务程序内,可以创建成功, 但外部客户端连接时 m_hMailslot = CreateFile("\\\\.\\mailslot\\zdpMailslot",GENER ...

  3. c++下使用邮槽实现进程间通信

    Windows API提供了邮槽和命名管道两种机制来实现进程间通信,在这里使用C++实现邮槽. 邮槽是Windows提供的一种进程间单向通信的机制,进程中的一方只能读取(或写入)数据,而另一方只能写入 ...

  4. Windows网络编程笔记3 ---- 邮槽和命名管道

    邮槽和命名管道的使用方法也很简单,只需几个有限的函数就可以实现双方的通信. 第三.邮槽 邮槽----进程间通信机制. 通过邮槽客户进程可以将消息通过广播给一个或多个服务进程.这是一个单向通信机制,缺点 ...

  5. [C++] socket -7 [邮槽]

    ::利用邮槽实现windons进程通信 ::一般情况下CreateMailslot()常被使用在进程通信的服务器上,在客户端则是用函数CreateFile()打开指定的邮槽之后进行相关的操作. ::将 ...

  6. window API一天一练之邮槽

    邮槽通信的进程分为服务端和客户端.服务端创建邮槽,客户端通过邮槽名打开邮槽,获得句柄后可以向邮槽写数据. 邮槽通信是单向通信,只能由客户端向服务端发送数据.下面来看看有关邮槽的几个API HANDLE ...

  7. 邮槽 匿名管道 命名管道 剪贴板 进程通讯 转自http://www.cnblogs.com/kzloser/archive/2012/11/04/2753367.html#

    邮槽 通信流程: 服务器 客户端 注意: 邮槽是基于广播通信体系设计出来的,它采用无连接的不可靠的数据传输 邮槽可以实现一对多的单向通信,我们可以利用这个特点编写一个网络会议通知系统,而且实现这一的系 ...

  8. 【转】Windows 邮件槽(MailSlot)

    Windows 邮件槽(MailSlot) 来自<Windows网络编程第二版 中文版> 优点:通过网络,将一条消息广播给一台或多台计算机.   缺点:只允许从客户机到服务器,建立一种不可 ...

  9. C++进程间通信

    # C++进程间通信 # 进程间通讯的四种方式:剪贴板.匿名管道.命名管道和邮槽 ## 剪切板 ## //设置剪切板内容 CString str; this->GetDlgItemText(ID ...

随机推荐

  1. redis(一)简介

    啥也不说百度各种简介 推荐一个博客灰常详细的介绍  nosqlfan  接下来发布redis+USE_TCMALLOC 的安装配置,博客好多坑,找一篇好文真心难啊.  redis+keepalived ...

  2. 插件化—配置xml的辅助测试

    1.xml文件,xml文件在res/xml目录下 <?xml version="1.0" encoding="utf-8"?> <infos& ...

  3. android 应用静默自启动的解决方法

    一个apk完全的自动静默启动目前不能实现,所以就用到了Activity的一个方法activity.moveTaskToBack(boolean),这个方法就是可以退出应用到后台而不是finish()退 ...

  4. ListBox控件

    主要介绍:自定义数据.绑定数据库数据 前台代码: <div> <asp:ListBox ID=" Width ="100px"> <asp: ...

  5. 演练5-6:Contoso大学校园管理系统6

    在上一次的教程中,我们处理了关联数据问题.这个教程演示如何处理并发问题.你将使用Department实体创建一个页面,这个页面在支持编辑和删除的同时,还可以处理并发错误.下面的截图演示了Index页面 ...

  6. 在Delphi中开发使用多显示器的应用程序(MonitorCount和DefaultMonitor)

    Windows可以将多个显示器映射为虚拟桌面,使我们可以利用这一点设计出方便工作的应用程序.例如PowerPoint就充分发挥了双显示器的优势(大多数的笔记本电脑都支持),它可以在一个显示器上播放幻灯 ...

  7. Ruby on Rails: 使用devise+cancan+rolify建立完整的权限管理系

    devise.cancan和rolify这三个组件结合,可以建立完整而强大的用户权限模型. devise介绍,负责用户注册.登录.退出.找回密码等操作.细节参考devise on github can ...

  8. 通过 HTTPS 和 SSL 确保 Windows Azure 网站 (WAWS) 安全

    编辑人员注释:本文章由 Windows Azure 网站团队的项目经理 Erez Benari 撰写. 随着身份盗窃和各种形式的网络犯罪迅速增多,使用安全套接字层 (SSL) 对网站进行保护变得越来越 ...

  9. Django的url解析

    Django中采用正则表达式来匹配所请求的url,这个叫做URLconf,作为MVC中的C(控制器), 这样再调用相应的试图,达到控制器控制试图的显示的效果. 看一下Django的url解析过程 第一 ...

  10. ios qq 分享 失败

    1. TencentOAuth 是需要调用,但QQ代码共享是没有解释.共享代码如下面: TencentOAuth *auth = [[TencentOAuth alloc] initWithAppId ...