进程间通信的方法:
- 共享内存:
Win32Api允许多个进程访问同一个映射对象,获取该映射对象的指针进行操作,这样就实现了不同进程间数据共享
- 首先创建内存映射文件,使用CreateFile()创建用于共享内存的文件
- 创建内存映射对象,利用CreateFile生成的句柄,调用CreateFileMapping函数,创建内存映射对象,用于获取映射内存的操作句柄,进程建通讯时,需要创建有名映射对象
- 建立映射视图文件,将生成的内存映射对象句柄转化为可直接操作的指针,该指针为共享内存的起始地址,也是逻辑页中起始页首地址
- 在另一个进程中使用该共享内存时,需要调用OpenFileMapping接口,获取有名共享内存的句柄
- 使用映射视图文件获取该共享内存的逻辑页首地址,可操作该指针(读写)
- 使用完成后,需要释放映射进入进程的内存,调用UnmapViewOfFile接口,释放内存
- 使用消息WM_COPYDATA 底层实现为内存映射
WM_COPYDATA使用非常便利,当一个进程向另一个进程发送消息时,只需要调用SendMessage或者PostMessage即可,消息使用条件为,需要获取目标进程的主窗口句柄
实现方法:
- 首先创建消息响应的声明和实现
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);
}
- 数据发送方首先获取目标进程的句柄
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
- 创建SOCKET sk = socket(AF_INET,SOCK_STREAM) ;//流式套接字
- 创建连接 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));
- 发送数据
Char* pBuff = new char[1024*10];
Memset(pBuff,0,1024*10);
...// 数据填充代码
Sendto(sk,pBuff,1024*10,0);
- 接收数据
Char* pBuff = new char[1024*10];
Memset(pBuff,0,1024*10);
Recvfrom(sk,pBuff,1024*10,0);
...数据处理
5.关闭套接字,closesocket(sk);
WSACleanup();
释放系统网络资源
如果没有释放,当程序退出时,系统会自动回收,一般客户端和服务器均需要释放
以上内容是这些天个人学习总结,欢迎大家提出批评