栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

windows 端 1 对 1 的简单进程间通讯

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

windows 端 1 对 1 的简单进程间通讯

windows 端 1 对 1 的简单进程间通讯

小王抱着一堆书到了邮局邮递到小李家。邮递员到了小李家,按下门铃,小李发现
书送到了,放书到屋内,然后按照小王的地址给小王回信。这就是一般的通讯过程。
小王是源进程
小李是目标进程
邮局是通讯通道
门铃是通知事件
书是数据
地址是大家规定的通讯目的地标识。

划分为三个层次:
  • 数据层

对象
通讯通道
响铃
信息

  • 进程、线程

接收线程
回调

初始化
启动接收
设置对方的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
#include 
#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();
        }
    }
}
main.cpp
#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;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/698341.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号