进程间通信的几种方式

进程间通信的方法:

  1. 共享内存:

Win32Api允许多个进程访问同一个映射对象,获取该映射对象的指针进行操作,这样就实现了不同进程间数据共享

  1. 首先创建内存映射文件,使用CreateFile()创建用于共享内存的文件
  2. 创建内存映射对象,利用CreateFile生成的句柄,调用CreateFileMapping函数,创建内存映射对象,用于获取映射内存的操作句柄,进程建通讯时,需要创建有名映射对象
  3. 建立映射视图文件,将生成的内存映射对象句柄转化为可直接操作的指针,该指针为共享内存的起始地址,也是逻辑页中起始页首地址
  4. 在另一个进程中使用该共享内存时,需要调用OpenFileMapping接口,获取有名共享内存的句柄
  5. 使用映射视图文件获取该共享内存的逻辑页首地址,可操作该指针(读写)
  6. 使用完成后,需要释放映射进入进程的内存,调用UnmapViewOfFile接口,释放内存
  7. 使用消息WM_COPYDATA 底层实现为内存映射

WM_COPYDATA使用非常便利,当一个进程向另一个进程发送消息时,只需要调用SendMessage或者PostMessage即可,消息使用条件为,需要获取目标进程的主窗口句柄

实现方法:

  1. 首先创建消息响应的声明和实现

BEGIN_MESSAGE_MAP(CMainFram*,CFrameWndEx*)

ON_WN_COPYDATA()

END_MESSAGE_MAP()

BOOL OnCopyData(CWnd*,COPYDATASTRUCT*);

BOOL OnCopyData(CWnd*pWnd,COPYDATASTRUCT*pCopyDataStruct)

{

return CMainFrame::OnCopyData(pWnd,pCopyDataStruct);

}

  1. 数据发送方首先获取目标进程的句柄

HANDLE hHandle = FindWindow(NULL,“**”);

调用SendMessage或者PostMessage发送数据

SendMessage(hHandle,WM_COPYDATA,LPVOID,LPVOID);

3.普通消息

1.创建消息的声明和实现

#define MYMESSAGE USER+100

BEGIN_MESSAGE_MAP(CMainFram*,CFrameWndEx*)

ON_MESSAGE(MYMESSAGE,OnMyMessage)

END_MESSAGE_MAP()

LRESULT OnMyMessage(DWORD,DWORD);

LRESULT OnMyMessage(DWORD,DWORD)
{

Return 0;

}

2.发送方

先查找目标窗口的句柄

#define MYMESSAGE USER+100

HANDLE hHandle = FindWindow(NULL,”**”);

调用SendMessage接口,发送消息

SendMessage(hHandle,MYMESSAGE,DWORD,DWORD);

4.TCP\UDP通讯,可实现本地计算机进程间通讯也可实现不同操作系统下进程间通讯

服务器端:可配合线程及线程池一起使用,目的是为每个连接接入对应的通讯soaket

1.WSAStartup 设置Socket版本信息,一般可以是2.1 2.2

2.创建SOCKET sk = socket(AF_INET,SOCK_STREAM,0);

3.绑定socket 绑定前,需要确定几个参数

sockaddr_in sa;

sa.sin_family = AF_INET;

sa.sin_addr.S_un.S_addr = inet_addr(“196.168.**.**”);

sa.sin_port = htons(10000);

bind(sk,(sockaddr*)&sa,sizeof(sockaddr));

4.监听socket

listen(sk,10);

5.接收连接

sockaddr_in saAcept;

Int nLen = sizeof(sockaddr_in);

accept(sk,&saAcept,&nLen);

6.接收数据recv()

Char* pBuff = new char[1024*10];

memset(pBuff,0,1024*10);

Int nRealLen = recv(pBuff,1024*10,0);

If(nRealLen < 0)

{

If(nRealLen == EAGAIN)

{

Return -1;

}

}

else

{

If(nRealLen == 0)

{

Return 0;

}

Else

{

Write(filePath,pBuff,nLen);

}

}

客户端:

1.设定socket版本 WSAStartup 一般为2.2

  1. 创建SOCKET sk = socket(AF_INET,SOCK_STREAM) ;//流式套接字
  2. 创建连接 connect() 参数

sockaddr_in sa;

sa.sin_family = AF_INET;

sa.sin_addr.S_Un.S_addr = inet_addr(“196.168.**.**”);

sa.sin_port = htons(5000);

Int nRet = connect(sk,(socketaddr*)&sa,sizeof(socketaddr));

  1. 发送数据

Char* pBuff = new char[1024*10];

Memset(pBuff,0,1024*10);

...// 数据填充代码

Sendto(sk,pBuff,1024*10,0);

  1. 接收数据

Char* pBuff = new char[1024*10];

Memset(pBuff,0,1024*10);

Recvfrom(sk,pBuff,1024*10,0);

...数据处理

5.关闭套接字,closesocket(sk);

WSACleanup();

释放系统网络资源

如果没有释放,当程序退出时,系统会自动回收,一般客户端和服务器均需要释放

以上内容是这些天个人学习总结,欢迎大家提出批评

猜你喜欢

转载自www.cnblogs.com/blue-whale/p/10370990.html