20、Windows API 进程间通信,邮槽(Mailslot)

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

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

Windows系统下,在进程间通信或共享数据的方式如下。

◇邮槽(Mailslot)

    邮槽是最为简单的进程间数据共享方式,一个进程创建并拥有一个邮槽,其他进程都可以打开这个邮槽并向其发送消息。

◇管道(Pipe)

实质是一种共享的内存,由一个进程创建,其他进程连接,并可进行双向的通信。

◇剪贴板(Clipboard)

    剪贴板是重要的进程间数据共享方式,所有的进程都可以设置和修改剪贴板,也都可以从剪贴板获取内容。

◇消息,具体是指WM_COPYDATA消息。

消息具有参数wParamlParam。但是wParamlParam最多是32位的。而WM_COPYDATA消息的参数不受wParamlParam数据大小的限制,可以用于在进程间传递数据。

◇网络。

    网络可以在不同主机上的不同程序间通信,当然也可以在相同主机上的不同程序间通信。

FileMapping[2]

一、邮槽(MailSlot)

    使用邮槽通信的进程分为服务端和客户端。邮槽由服务端创建,在创建时需要指定邮槽名,创建后服务端得到邮槽的句柄。在邮槽创建后,客户端可以通过邮槽名打开邮槽,在获得句柄后可以向邮槽写入消息。

    邮槽通信是单向的,只有服务端才能从邮槽中读取消息,客户端只能写入消息。消息是先入先出的。客户端先写入的消息在服务端先被读取。

通过邮槽通信的数据可以是任意格式的,但是一条消息不能大于424字节。邮槽除了在本机内进行进程间通信外,在主机间也可以通信。但是在主机间进行邮槽通信,数据通过网络传播时使用的是数据报协议(UDP),所以是一种不可靠的通信。通过网络进行邮槽通信时,客户端必须知道服务端的主机名或域名。

MailSlot的详细介绍,可以参见[3],[4]也作了一些介绍。

邮槽通信服务端程序

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif 通过mailslot进程间通信-服务端
 
   
通过mailslot进程间通信
**************************************/
/* 头文件 */
#include
< windows.h >
#include
< stdio.h >
/* 全局变量 */
HANDLE hSlot;
LPTSTR lpszSlotName
= TEXT( " \\\\.\\mailslot\\sample_mailslot " );
LPTSTR Message
= TEXT( " Message for mailslot in primary domain. " );

/* ************************************
* void main()
* 功能 进程间mailslot通信客户端
*************************************
*/
void main()
{
DWORD cbMessage, cMessage, cbRead;
BOOL fResult;
LPTSTR lpszBuffer;
TCHAR achID[
80 ];
DWORD cAllMessages;
HANDLE hEvent;
OVERLAPPED ov;

cbMessage
= cMessage = cbRead = 0 ;

hSlot
= CreateMailslot(
lpszSlotName,
// mailslot 名
0 , // 不限制消息大小
MAILSLOT_WAIT_FOREVER, // 无超时
(LPSECURITY_ATTRIBUTES) NULL);

if (hSlot == INVALID_HANDLE_VALUE)
{
printf(
" CreateMailslot failed with %d\n " , GetLastError());
return ;
}
else printf( " Mailslot created successfully.\n " );

while ( 1 )
{
// 获取mailslot信息
fResult = GetMailslotInfo(hSlot, // mailslot 句柄
(LPDWORD) NULL, // 无最大消息限制
& cbMessage, // 下一条消息的大小
& cMessage, // 消息的数量
(LPDWORD) NULL); // 无时限

if ( ! fResult)
{
printf(
" GetMailslotInfo failed with %d.\n " , GetLastError());
return ;
}

if (cbMessage == MAILSLOT_NO_MESSAGE)
{
// 没有消息,过一段时间再去读
Sleep( 20000 );
continue ;
}

cAllMessages
= cMessage;

while (cMessage != 0 ) // 获取全部消息,有可能不只一条
{
// 提示信息
wsprintf((LPTSTR) achID,
" \nMessage #%d of %d\n " ,
cAllMessages
- cMessage + 1 ,
cAllMessages);

// 分配空间
lpszBuffer = (LPTSTR) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
lstrlen((LPTSTR) achID)
* sizeof (TCHAR) + cbMessage);
if ( NULL == lpszBuffer )
{
return ;
}
// 读取消息
fResult = ReadFile(hSlot, // mailslot句柄
lpszBuffer, // 缓存
cbMessage, // 消息的长度
& cbRead, // 实际读取的长度
NULL);

if ( ! fResult)
{
printf(
" ReadFile failed with %d.\n " , GetLastError());
GlobalFree((HGLOBAL) lpszBuffer);
return ;
}

// 处理信息,显示
lstrcat(lpszBuffer, (LPTSTR) achID);
printf(
" Contents of the mailslot: %s\n " , lpszBuffer);

HeapFree(GetProcessHeap(),
0 ,lpszBuffer);
// 计算剩余的消息数
fResult = GetMailslotInfo(hSlot,
(LPDWORD) NULL,
& cbMessage,
& cMessage,
(LPDWORD) NULL);

if ( ! fResult)
{
printf(
" GetMailslotInfo failed (%d)\n " , GetLastError());
return ;
}
}
}
return ;
}

邮槽通信客户端程序

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif 通过mailslot进程间通信-客户端
 
   
通过mailslot进程间通信
**************************************/
/* 头文件 */
#include
< windows.h >
#include
< stdio.h >
/* 全局变量 */
HANDLE hSlot;
LPTSTR lpszSlotName
= TEXT( " \\\\.\\mailslot\\sample_mailslot " ); // mailslot名
LPTSTR lpszMessage = TEXT( " Test Message for mailslot " ); // 通信的内容

/* ************************************
* void main()
* 功能 进程间mailslot通信客户端
*************************************
*/
void main()
{
BOOL fResult;
HANDLE hFile;
DWORD cbWritten;

DWORD cbMessage;
// 打开mailslot
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写入
fResult = WriteFile(hFile,
lpszMessage,
(DWORD) (lstrlen(lpszMessage)
+ 1 ) * sizeof (TCHAR),
& cbWritten,
(LPOVERLAPPED) NULL);

if ( ! fResult)
{
printf(
" WriteFile failed with %d.\n " , GetLastError());
return ;
}
// 结束
printf( " Slot written to successfully.\n " );
CloseHandle(hFile);
return ;
}

参考

[1] 精通Windows API 函数、接口、编程实例

[2] http://www.cnblogs.com/mydomain/archive/2011/01/07/1929874.html

[3] http://msdn.microsoft.com/en-us/library/aa365130%28VS.85%29.aspx

[4] http://www.cnblogs.com/mydomain/archive/2010/09/18/1830476.html?login=1

目录
相关文章
|
4天前
|
人工智能 测试技术 API
Windows用户必备:Postman v11详细安装指南与API测试入门教程(附官网下载
Postman是全球领先的API开发与测试工具,支持REST、SOAP、GraphQL等协议调试。2025年最新版v11新增AI智能生成测试用例、多环境变量同步等功能,适用于前后端分离开发、自动化测试、接口文档自动生成及团队协作共享API资源。本文详细介绍Postman的软件定位、核心功能、安装步骤、首次配置、基础使用及常见问题解答,帮助用户快速上手并高效利用该工具进行API开发与测试。
|
2月前
|
监控 搜索推荐 开发工具
2025年1月9日更新Windows操作系统个人使用-禁用掉一下一些不必要的服务-关闭占用资源的进程-禁用服务提升系统运行速度-让电脑不再卡顿-优雅草央千澈-长期更新
2025年1月9日更新Windows操作系统个人使用-禁用掉一下一些不必要的服务-关闭占用资源的进程-禁用服务提升系统运行速度-让电脑不再卡顿-优雅草央千澈-长期更新
186 2
2025年1月9日更新Windows操作系统个人使用-禁用掉一下一些不必要的服务-关闭占用资源的进程-禁用服务提升系统运行速度-让电脑不再卡顿-优雅草央千澈-长期更新
|
5月前
|
开发框架 .NET API
Windows Forms应用程序中集成一个ASP.NET API服务
Windows Forms应用程序中集成一个ASP.NET API服务
131 9
|
5月前
|
Java 关系型数据库 MySQL
java控制Windows进程,服务管理器项目
本文介绍了如何使用Java的`Runtime`和`Process`类来控制Windows进程,包括执行命令、读取进程输出和错误流以及等待进程完成,并提供了一个简单的服务管理器项目示例。
74 1
|
6月前
|
网络协议 API Windows
MASM32编程调用 API函数RtlIpv6AddressToString,windows 10 容易,Windows 7 折腾
MASM32编程调用 API函数RtlIpv6AddressToString,windows 10 容易,Windows 7 折腾
|
7月前
|
Java Windows
【Azure Developer】Windows中通过pslist命令查看到Java进程和线程信息,但为什么和代码中打印出来的进程号不一致呢?
【Azure Developer】Windows中通过pslist命令查看到Java进程和线程信息,但为什么和代码中打印出来的进程号不一致呢?
|
7月前
|
Windows
Windows中如何查看被占用的端口、杀掉对应的进程
这篇文章介绍了在Windows系统中如何查看被占用的端口号以及如何杀掉占用端口的进程,包括使用命令提示符的`netstat -ano | findstr 端口号`命令查找进程PID,然后通过任务管理器或`taskkill /PID PID号`命令来结束进程。
Windows中如何查看被占用的端口、杀掉对应的进程
|
7月前
|
JavaScript Windows
NodeJs——如何获取Windows电脑指定应用进程信息
NodeJs——如何获取Windows电脑指定应用进程信息
173 0
|
7月前
|
Linux Windows
Windows查找监听端口对应的进程及其路径
Windows查找监听端口对应的进程及其路径
162 0
|
9月前
|
存储 数据安全/隐私保护 Windows
逆向学习Windows篇:进程句柄操作详解
逆向学习Windows篇:进程句柄操作详解
336 0

热门文章

最新文章