Windows进程间通讯

参考文献1:http://blog.csdn.net/left_la/article/details/11564539ios

参考文献2:http://www.cppblog.com/TechLab/archive/2005/12/30/2272.aspx程序员

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////编程

进程间通讯(InterProcess Communication, IPC):安全

  1. 文件映射:文件映射(Memory-Mapped Files)能使进程把文件内容看成进程地址区间一块内存那样来对待。所以,进程没必要使用文件I/O操做, 只需简单的指针操做就可读取和修改文件的内容。 Win32 API容许多个进程访问同一文件映射对象,各个进程在它本身的地址空间里接收内存的指针。经过使用这些指针,不一样进程就能够读或修改文件的内容, 实现了对文件中数据的共享。 
  2. 共享内存:Win32 API中共享内存(Shared Memory)实际就是文件映射的一种特殊状况。进程在建立文件映射对象时用0xFFFFFFFF来代替 文件句柄(HANDLE), 就表示了对应的文件映射对象是从操做系统页面文件访问内存,其它进程打开该文件映射对象就能够访问该内存块。因为共享内存是用 文件映射实现的, 因此它也有较好的安全性,也只能运行于同一计算机上的进程之间。 
  3.  匿名管道 :管道(Pipe)是一种具备两个端点的通讯通道:有一端句柄的进程能够和有另外一端句柄的进程通讯。管道能够是单向-一端是只读的,另外一端点是只写的; 也能够是双向的一管道的两端点既可读也可写。 匿名管道(Anonymous Pipe)是 在父进程和子进程之间,或同一父进程的两个子进程之间传输数据的无名字的单向管道。一般由父进程建立管 道, 而后由要通讯的子进程继承通道的读端点句柄或写 端点句柄,而后实现通讯。父进程还能够创建两个或更多个继承匿名管道读和写句柄的子进程。 这些子进程 可使用管道直接通讯,不须要经过父进程。 匿名管道是单机上实现子进程标准I/O重定向的有效方法,它不能在网上使用,也不能用于两个不相关的进程之间。 
  4. 命名管道 :命名管道(Named Pipe)是服务器进程和一个或多个客户进程之间通讯的单向或双向管道。不一样于匿名管道的是命名管道能够在不相关的进程之间和不 同计算机之间使用,服务器创建命名管道时给它指定一个名字,任何进程均可以经过该名字打开管道的另外一端,根据给定的权限和服务器进程通讯。 命名管道提供了相对简单的编程接口,使经过网络传输数据并不比同一计算机上两进程之间通讯更困难,不过若是要同时和多个进程通讯它就力不从心了。 
  5. 邮件槽:邮件槽(Mailslots)提 供进程间单向通讯能力,任何进程都能创建邮件槽成为邮件槽服务器。其它进程,称为邮件槽客户,能够经过邮件槽的名字给 邮件槽服务器进程发送消息。进来的消 息一直放在邮件槽中,直到服务器进程读取它为止。一个进程既能够是邮件槽服务器也能够是邮件槽客户, 所以可创建多个 邮件槽实现进程间的双向通讯。 
  6.  剪贴板:剪贴板(Clipped Board)实质是Win32 API中一组用来传输数据的函数和消息,为Windows应用程序之间进行数据共享提供了一个 中介, Windows已创建的剪切(复制)-粘贴的机制为不一样应用程序之间共享不一样格式数据提供了一条捷径。当用户在应用程序中执行剪切或复制操做时, 应 用程序把选取的数据用一种或多种格式放在剪贴板上。而后任何其它应用程序均可以从剪贴板上拾取数据,从给定格式中选择适合本身的格式。 
  7. 动态数据交换 :动态数据交换(DDE)是使用共享内存在应用程序之间进行数据交换的一种进程间通讯形式。应用程序可使用DDE进行一次性数据传输,也能够当出现新数据时, 经过发送更新值在应用程序间动态交换数据。 DDE和剪贴板同样既支持标准数据格式(如文本、位图等),又能够支持本身定义的数据格式。但它们的数据传输机制却不一样,一个明显区别是剪贴板操做几乎 
    老是用做对用户指定操做的一次性应答-如从菜单中选择Paste命令。尽管DDE也能够由用户启动,但它继续发挥做用通常没必要用户进一步干预。
  8. 对象链接与嵌入 
    应用程序利用对象链接与嵌入(OLE)技术管理复合文档(由多种数据格式组成的文档),OLE提供使某应用程序更容易调用其它应用程序进行数据编辑的服务。 
    例如,OLE支持的字处理器能够嵌套电子表格,当用户要编辑电子表格时OLE库可自动启动电子表格编辑器。当用户退出电子表格编辑器时, 该表格已在原 始字处理器文档中获得更新。在这里电子表格编辑器变成了字处理器的扩展,而若是使用DDE,用户要显式地启动电子表格编辑器。 
    同DDE技术相同,大多数基于Windows的应用程序都支持OLE技术。 
  9. 动态链接库 
    Win32动态链接库(DLL)中的全局数据能够被调用DLL的全部进程共享,这就又给进程间通讯开辟了一条新的途径,固然访问时要注意同步问题。 虽然能够经过DLL进行进程间数据共享,但从数据安全的角度考虑,咱们并不提倡这种方法,使用带有访问权限控制的共享内存的方法更好一些。 
  10. 远程过程调用 
    Win32 API提供的远程过程调用(RPC)使应用程序可使用远程调用函数,这使在网络上用RPC进行进程通讯就像函数调用那样简单。 
    RPC既能够在单机不一样进程间使用也能够在网络中使用。 
    因为Win32 API提供的RPC服从OSF-DCE (Open Software Foundation Distributed Computing Environment)标准。
    因此经过 Win32 API编写的RPC应用程序能与其它操做系统上支持DEC的RPC应用程序通讯。使用RPC开发者能够创建高性能、紧密耦合的分布式应用程序。 
  11. NetBios函数 
    Win32 API提供NetBios函数用于处理低级网络控制,这主要是为IBM NetBios系统编写与Windows的接口。除非那些有特殊低级网络功能要求的应用程序, 其它应用程序最好不要使用NetBios函数来进行进程间通讯。 
  12. Sockets 
    Windows Sockets规范是以U.C.Berkeley大学BSD UNIX中流行的Socket接口为范例定义的一套Windows下的网 络编程接口。除了Berkeley Socket原有的库函数之外 ,还扩展了一组针对Windows的函数,使程序员能够充分利用Windows的消息机 制进行编程。 
    如今经过Sockets实现进程通讯的网络应用愈来愈多,这主要的缘由是Sockets的跨平台性要比其它IPC机制好得多,另 外WinSock 2.0不只支持TCP/IP协议, 并且还支持其它协议(如IPX)。Sockets的惟一缺点是它支持的是底层通讯操做,这使得在单机 的进程间进行简单数据传递不太方便, 这时使用下面将介绍的WM_COPYDATA消息将更合适些。 
  13. WM_COPYDATA消息 
    WM_COPYDATA是一种很是强大却不为人知的消息。当一个应用向另外一个应用传送数据时,发送方只需使用调用SendMessage函数, 参数是目 的窗口的句柄、传递数据的起始地址、WM_COPYDATA消息。接收方只需像处理其它消息那样处理WM_COPY DATA消息,这样收发双方就实现了 数据共享。 WM_COPYDATA是一种很是简单的方法,它在底层其实是经过文件映射来实现的。 
    它的缺点是灵活性不高,而且它只能用于Windows平台的单机环境下,且要求窗口接受消息。

WM_COPYDATA实现进程间数据共享服务器

//WM_COPYDATA实现进程间数据共享
在进程A中:

CString strDataToSend = _T( "Hello" );   //须要传递的数据
HWND hWndReceived;      //进程B的接收数据窗口对象
//COPYDATASTRUCT结构是WM_COPYDATA传递的数据结构对象
COPYDATASTRUCT cpd;
cpd.dwData =  0;
cpd.cbData  =  strDataToSend.GetLength();            //传递的数据长度
cpd.lpData    =  (void*)strDataToSend.GetBuffer(cpd.cbData);  //传递的数据地址
SendMessage( hWndReceived, WM_COPYDATA, 0, (LPARAM) & cpd );
strDataToSend.ReleaseBuffer();


在目标进程B中,先手动创建好函数声明和实现
BEGIN_MESSAGE_MAP(CMyWnd, CWnd)
            //{{AFX_MSG_MAP(CMyWnd)
            ON_WM_COPYDATA()
            //}}AFX_MSG_MAP
END_MESSAGE_MAP()

映射函数:
BOOL CMyWnd::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) 
{
   CString strRecievedText = (LPCSTR) (pCopyDataStruct->lpData);
   return CMyWnd::OnCopyData(pWnd, pCopyDataStruct);
}

共享内存 网络

//a.设定一块共享内存区域 

HANDLE CreateFileMapping(HANDLE,LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCSTR)
//产生一个file-mapping核心对象 
LPVOID MapViewOfFile( 
HANDLE hFileMappingObject, 
DWORD dwDesiredAcess, 
DWORD dwFileOffsetHigh, 
DWORD dwFileOffsetLow, 
DWORD dwNumberOfBytesToMap 
);//获得共享内存的指针 

//b.找出共享内存 
决定这块内存要以点对点(peer to peer)的形式呈现每一个进程都必须有相同的能力,产生共享内存并将它初始化。每一个进程都应该调用CreateFileMapping(), 

而后调用GetLastError().若是传回的错误代码是 ERROR_ALREADY_EXISTS,那么进程就能够假设这一共享内存区 域已经被别的进程打开并初始化了, 

不然该进程就能够合理的认为本身 排在第 一位,并接下来将共享内存初始化。仍是要使用client/server架构中只有server进程才应该产生并初始化共享内存。 
全部的进程都应该使用 
HANDLE OpenFileMapping(DWORD dwDesiredAccess, 
BOOL bInheritHandle, 
LPCTSTR lpName); 
再调用MapViewOfFile(),取得共享内存的指针 


c.同步处理(Mutex) 


d.清理(Cleaning up) BOOL UnmapViewOfFile(LPCVOID lpBaseAddress); 

CloseHandle()

win32下进程间通讯(共享内存)实例分析

http://www.jb51.net/article/52306.htm数据结构

相关文章
相关标签/搜索