小王抱着一堆书到了邮局邮递到小李家。邮递员到了小李家,按下门铃,小李发现
书送到了,放书到屋内,然后按照小王的地址给小王回信。这就是一般的通讯过程。
小王是源进程
小李是目标进程
邮局是通讯通道
门铃是通知事件
书是数据
地址是大家规定的通讯目的地标识。
- 数据层
对象
通讯通道
响铃
信息
- 进程、线程
接收线程
回调
- 类
初始化
启动接收
设置对方的ipc
发送
- 实现
我们这里使用 event 作为门铃
和内存映射实现 - 通讯通道
类就是对象
例子: 类 x; 类 d; d.初始化(自己的通道,自己的响铃); x.初始化(自己的通道,自己的响铃); x.启动接收(超时时间); x.设置对方的IPC(d); x.发送(d,数据);SimpleIPC.h
#pragma once
typedef void (*RecvFn)(void* data,unsigned int data_len);
class CSimpleIPC
{
public:
CSimpleIPC(void);
~CSimpleIPC(void);
bool Init(wchar_t * bell_name,wchar_t* passageway_name);
bool Start(unsigned int timeout,RecvFn fn);
bool Send(void* data,unsigned int data_len) const ;
void SetIPC(CSimpleIPC * ipc)
{
m_ipc = ipc;
}
static unsigned int __stdcall ThreadFn(LPVOID param);
void Handle();
bool SendData( void* data,unsigned int data_len ) const;
private:
//响铃
HANDLE m_evnet;
//通道
HANDLE m_share_mem;
//
HANDLE m_hThread;
//
unsigned int m_timeout;
//
RecvFn m_callback;
CSimpleIPC * m_ipc;
};
SimpleIPC.cpp
#includemain.cpp#include #include #include "SimpleIPC.h" #define MAX_MAP_FILE 128*4096 CSimpleIPC::CSimpleIPC(void) { } CSimpleIPC::~CSimpleIPC(void) { } bool CSimpleIPC::Init( wchar_t * bell_name,wchar_t* passageway_name ) { m_evnet = CreateEvent(NULL,TRUE,FALSE,bell_name); if(!m_evnet) { return false; } m_share_mem = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,MAX_MAP_FILE,passageway_name); if(!m_share_mem) { return false; } return true; } bool CSimpleIPC::Start( unsigned int timeout,RecvFn fn ) { m_timeout = timeout; m_callback = fn; m_hThread = (HANDLE)_beginthreadex(NULL,0,ThreadFn,(LPVOID)this,0,NULL); if(!m_hThread) return false; return true; } bool CSimpleIPC::SendData( void* data,unsigned int data_len ) const { LPVOID share_data = MapViewOfFile(m_share_mem,FILE_MAP_ALL_ACCESS,0,0,4096); if(!share_data) { printf("send failed %dn",GetLastError()); return false; } memcpy(share_data,&data_len,sizeof(data_len)); memcpy((char*)share_data+sizeof(data_len),data,data_len); UnmapViewOfFile(share_data); SetEvent(m_evnet); return true; } bool CSimpleIPC::Send( void* data,unsigned int data_len ) const { if(m_ipc) { return m_ipc->SendData(data,data_len); } return false; } void CSimpleIPC::Handle() { LPVOID data = MapViewOfFile(m_share_mem,FILE_MAP_ALL_ACCESS,0,0,4096); if(data) { unsigned int data_len = *(unsigned int*)data; m_callback?m_callback(data,data_len):void(0); //char buf[1024]={}; //sprintf(buf,"recv:%s",data); //m_ipc->SendData(buf,strlen(buf)); UnmapViewOfFile(data); } else { return ; } ResetEvent(m_evnet); } unsigned int __stdcall CSimpleIPC::ThreadFn( LPVOID param ) { CSimpleIPC * pThread = (CSimpleIPC*)param; while(1) { DWORD dwWait = WaitForSingleObject(pThread->m_evnet,pThread->m_timeout); if(dwWait==WAIT_OBJECT_0) { pThread->Handle(); } } }
#include#include #include #include "SimpleIPC.h" void RecvFunction(void* data,unsigned int data_len) { char* buf =(char*)data+sizeof(data_len); char *tmp_buf = (char *)malloc(data_len+1); memset(tmp_buf,0,data_len+1); memcpy(tmp_buf,buf,data_len); printf("recv %sn",tmp_buf); } int _tmain(int argc,wchar_t* argv[]) { if(argc<5) { return -1; } CSimpleIPC ipc1; if(!ipc1.Init(argv[3],argv[4])) { wprintf(L"dest ipc init failed %s %sn",argv[3],argv[4]); return -1; } CSimpleIPC ipc; if(!ipc.Init(argv[1],argv[2])) { wprintf(L"src ipc init failed %s %sn",argv[1],argv[2]); return -1; } ipc.Start(1000,RecvFunction); ipc.SetIPC(&ipc1); while(1) { char buf[1024]={}; scanf("%s",buf); if(!ipc.Send(buf,strlen(buf))) { wprintf(L"Send failedn"); return -1; } } return 0; }



