技术宅的结界

 找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 244|回复: 0
收起左侧

【翻译】MSDN资料:进程间通讯方法

[复制链接]

984

主题

2143

帖子

5万

积分

用户组: 管理员

一只技术宅

UID
1
精华
197
威望
261 点
宅币
15807 个
贡献
30732 次
宅之契约
0 份
在线时间
1504 小时
注册时间
2014-1-26
发表于 2017-11-19 04:45:57 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有帐号?立即注册→加入我们

x
MSDN原文网址:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365574(v=vs.85).aspx


打下划线的地方是我自己说的话,而其他的则基本基于谷歌翻译。

这个Windows操作系统支持了很多机制用于进程间数据共享。我们把这种行为称作进程间通讯(IPC)。有些进程间通讯支持一台电脑里特定进程之间的进程通讯,而还有的进程间通讯则支持跨电脑、跨网络的进程通讯。

一个典型情况就是应用程序使用“服务端与客户端”的这种关系来管理进程通讯。所谓客户端就是指某个程序或者某个进程它从别的程序或者进程请求某一项服务。然后所谓的服务端他就是负责提供某项服务的程序或者进程。很多程序它既是客户端又是服务端,视情况而定。举个例子,一个文字处理程序它就必须扮演一个客户端的身份从作为服务器的电子表格应用程序请求制造成本汇总表。

当你真的觉得你有必要进行进程间通讯的时候,你就得选择一种方法用于进程间通讯。而具体使用哪种方法,取决于你的需求。因为不同的进程间通讯方法会带来不同的好处。
  • 你的程序它是不是真的有必要进行跨网络的进程间通讯?或者说它只要在一台机器上实现进程间通讯就够了?
  • 你的程序它是不是得和其它操作系统的进程进行通讯?(比如16位Windows或者UNIX)?
  • 你是不是需要用户去选择你的进程要和哪些进程通讯,或者你的程序它自己就能找到钦定的对象?
  • 你的程序是不是要和其它各种不同类型的程序进行通讯,比如复制粘贴数据到别的程序,或者你的程序有必要限制进程间通讯的操作种类?
  • 你的程序是不是对性能要求很严苛?所有的进程间通讯都是需要一些运行成本的。
  • 你的程序是一个有窗口的程序还是一个命令行程序?有些进程间通讯方法需要你有个窗口。


Windows支持以下的几种进程间通讯机制:

剪贴板方式进程间通讯
剪贴板充当应用程序间数据共享的中央存储库。当用户在应用程序中执行剪切或复制操作时,应用程序将选定的数据以一种或多种标准或应用程序定义的格式放在剪贴板上。然后,任何其他应用程序都可以从剪贴板中检索数据,并从可以理解的可用格式中进行选择。剪贴板是非常松散耦合的交换介质,应用程序只需要就数据格式达成一致。应用程序可以驻留在同一台计算机上或网络上的不同计算机上。

关键点:所有的程序都必须支持它们需要的数据的格式。举个例子,一个文本编辑器它就必须支持纯文本格式,能把纯文本复制进剪贴板,以及从剪贴板里面取出纯文本格式的数据。更多信息请参见剪贴板

使用COM组件进行进程间通讯
使用OLE的应用程序管理复合文档 - 即由来自各种不同应用程序的数据组成的文档。OLE提供的服务使应用程序可以方便地调用其他应用程序进行数据编辑。例如,使用OLE的文字处理器可以嵌入电子表格中的图形。用户可以通过选择嵌入的图表进行编辑,从文字处理器内自动启动电子表格。OLE负责启动电子表格并显示图形进行编辑。当用户退出电子表格时,图表将在原始文字处理器文档中更新。电子表格似乎是字处理器的扩展。
OLE的基础是组件对象模型(COM)。使用COM的软件组件可以与各种各样的其他组件进行通信,甚至那些尚未写入的组件。这些组件作为对象和客户进行交互。分布式COM扩展了COM编程模型,使其可以在网络中工作。

关键点:OLE支持复合文档,并使应用程序能够包含嵌入的或链接的数据,在选择时自动启动另一个应用程序进行数据编辑。这使应用程序可以被任何其他使用OLE的应用程序扩展。COM对象通过一组或多组相关函数(称为接口)提供对对象数据的访问。有关更多信息,请参阅COM和ActiveX对象服务。

使用WM_COPYDATA窗口消息进行进程间通讯
这个方法需要发送方和接收方之间进行合作。接收方必须知道数据的格式并且能找出发送方是谁。重点是你不能一个疏忽就试图直接用指针来修改发送方的内存,也就是说你试图用这个消息传输指针的话,你要想操作这个指针指向的数据你就必须依赖ReadProcessMemory()或者WriteProcessMemory()而这需要你有权限打开目标进程——杀软大概就会觉得你是在搞事,于是把你当作病毒给你拦截了。而且这还需要解决UAC的问题。所以你只能用这个消息来传递实际的数据。

关键点:你需要一个窗口。此外,它比较快。其它的关键点我已经在上文说了。你必须知道你用它传输了啥,并且你要知道不同的进程之间的内存空间是不同的。它们不是一个次元的。所以传输指针的话,对方不能直接使用这个指针,除非在共享数据段。不然就GG。

使用DDE进行进程间通讯
DDE是一种使应用程序能够以各种格式交换数据的协议。应用程序可以使用DDE进行一次性数据交换,也可以使用DDE进行长期的数据交换,其中应用程序在新数据可用时相互更新。
DDE使用的数据格式与剪贴板使用的格式相同。DDE可以被认为是剪贴板机制的扩展。剪贴板几乎总是用于对用户命令的一次性响应,例如从菜单中选择“粘贴”命令。DDE通常也是由一个用户命令发起的,但是它通常在没有进一步用户交互的情况下继续运行。您还可以为通信要求更紧密耦合的应用程序之间的专用IPC定义自定义DDE数据格式。
DDE允许跨网络的数据交互。

关键点:DDE不如新技术高效。但是,如果其他IPC机制不合适,或者必须与仅支持DDE的现有应用程序接口,则仍然可以使用DDE。有关更多信息,请参阅动态数据交换动态数据交换管理库

使用文件映射进行进程间通讯
文件映射使得进程可以像处理进程的地址空间中的内存块一样处理文件的内容。该过程可以使用简单的指针操作来检查和修改文件的内容。当两个或多个进程访问相同的文件映射时,每个进程都会在自己的地址空间中接收一个指向内存的指针,以便读取或修改文件的内容。进程必须使用同步对象(如信号量)来防止多任务环境中的数据损坏。
您可以使用特殊情况下的文件映射来在进程之间提供命名的共享内存。如果在创建文件映射对象时指定了系统交换文件,则文件映射对象将被视为共享内存块。其他进程可以通过打开相同的文件映射对象来访问同一块内存。
文件映射非常高效,还提供了操作系统支持的安全属性,可以帮助防止未授权的数据损坏。文件映射只能在本地计算机上的进程之间使用;它不能通过网络使用。

关键点:文件映射是同一台计算机上的两个或更多进程共享数据的有效方式,但是您必须提供进程之间的同步。有关更多信息,请参阅文件映射同步

使用Mailslot进行进程间通讯
Mailslots提供单向沟通。任何创建Mailslots的过程都是Mailslots服务器。其他进程(称为Mailslots客户端)通过向其Mailslots写入消息来向邮件服务器发送消息。传入消息始终附加到Mailslots。Mailslots保存消息,直到Mailslots服务器读取它们。一个进程既可以是一个Mailslots服务器,也可以是一个Mailslots客户端,因此可以使用多个Mailslots进行双向通信。
Mailslots客户端可以将邮件发送到本地计算机上的Mailslots,另一台计算机上的Mailslots,或指定网络域中所有计算机上具有相同名称的所有Mailslots。广播到域上所有邮件槽的邮件长度不能超过400字节,而发送到单个Mailslots的邮件仅受到Mailslots服务器在创建Mailslots时指定的最大邮件大小的限制。

关键点:邮件区为应用程序发送和接收短消息提供了一个简单的方法。它们还提供了在网络域中的所有计算机上广播消息的能力。有关更多信息,请参阅Mailslots

使用管道进行进程间通讯
有两种类型的双向通信管道:匿名管道和命名管道。匿名管道使相关进程能够相互传递信息。通常,匿名管道用于重定向子进程的标准输入或输出,以便它可以与其父进程交换数据。要双向交换数据(双工操作),您必须创建两个匿名管道。父进程使用其写入句柄将数据写入一个管道,而子进程使用其读取句柄从该管道读取数据。同样,子进程将数据写入另一个管道,父进程从中读取数据。匿名管道不能通过网络使用,也不能在不相关的进程之间使用。
命名管道用于在不相关进程的进程和不同计算机上的进程之间传输数据。通常,命名管道服务器进程会创建一个具有众所周知的名称或名称的命名管道,以传达给客户端。知道管道名称的命名管道客户端进程可以打开其另一端,受命名管道服务器进程指定的访问限制。服务器和客户端都连接到管道后,可以通过对管道进行读写操作来交换数据。

典型例子,匿名管道有仨:stdin,stdout和stderr。稍有C常识的人就知道,只要包含了stdio.h就能轻松使用匿名管道。然后printf函数默认是把东西输出到stdout,而perror则是输出东西到stderr。用scanf、getchar等函数可以读取stdin。用fopen、fread、fwrite、fprintf等可以操作各种管道。这种管道用于进程间通讯是十分方便的,而且就算你的程序是窗口程序而非控制台程序,你也是可以用管道的。

在Linux或者Unix,当你使用socket完成了一个TCPIP协议的连接后,你就能直接用read和write写管道的方式发送数据给远程目标了。贼方便。不过我还是习惯send和recv,因为在Windows下,socket不是文件描述符,而是“文件描述符”(注意双引号)。这是为了跨平台代码兼容。


关键点:匿名管道提供了一种有效的方法来将标准输入或输出重定向到同一台计算机上的子进程。 命名管道提供了一个简单的编程接口,用于在两个进程之间传输数据,不管它们驻留在同一台计算机上还是通过网络。 有关更多信息,请参阅管道

使用远程过程调用(RPC)进行进程间通讯
RPC使应用程序可以远程调用功能。 因此,RPC使得IPC像调用函数一样简单。 RPC在单台计算机上的进程或网络上的不同计算机上运行。
Windows提供的RPC与开放软件基础(OSF)分布式计算环境(DCE)兼容。 这意味着使用RPC的应用程序能够与运行其他支持DCE的操作系统的应用程序进行通信。 RPC自动支持数据转换,以适应不同的硬件体系结构以及不同环境之间的字节顺序。
RPC客户端和服务器紧密耦合,但仍然保持高性能。该系统广泛使用RPC来促进操作系统不同部分之间的客户端/服务器关系。

这里我不得不说一句:某火极一时的比特币勒索病毒,也就是某香菇病毒(WannaCry)就是钻了RPC的漏洞钻进了受害者们的电脑。

关键点:RPC是一个功能级接口,支持自动数据转换和与其他操作系统的通信。 使用RPC,您可以创建高性能,紧密耦合的分布式应用程序。 有关更多信息,请参阅Microsoft RPC组件。

使用Windows Sockets进行进程间通讯
Windows套接字是一个协议无关的接口。它利用了底层协议的通信功能。在Windows套接字2中,套接字句柄可以选择用作具有标准文件I / O功能的文件句柄。
Windows套接字基于BSD首先推广的套接字。使用Windows套接字的应用程序可以与其他类型的系统上的其他套接字实现进行通信。但是,并非所有运输服务提供商都支持所有可用选项。

废话那么多总结一下就是:它和网络连接的概念差不多,但不一定走网络。然后“127.0.0.1”这个地址就是“这个包裹是发给自己机器的”的意思。经典的LAMP服务器模型里面php要查询mysql数据库的时候就是走的socket(虽然不是Windows Sockets而是Linux sockets)建立一个TCPIP连接,连接上mysqld进程,然后收发数据实现的进程间通讯。这玩意儿可以跨网传输。并且我比较喜欢这种方法。

关键点:Windows套接字是一个协议独立的接口,能够支持当前和新兴的网络功能。 有关更多信息,请参阅Windows套接字2


本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|技术宅的结界 ( 滇ICP备16008837号|网站地图

GMT+8, 2018-4-25 23:59 , Processed in 0.078201 second(s), 18 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表