MFC 进程之间通讯之命名管道

命名管道(NamedPipe)是服务器进程和一个或多个客户进程之间通信的单向或双向管道。不同于匿名管道的是:命名管道可以在不相关的进程之间和不同计算机之间使用,服务器建立命名管道时给它指定一个名字,任何进程都可以通过该名字打开管道的另一端,根据给定的权限和服务器进程通信。命名管道提供了相对简单的编程接口,使通过网络传输数据并不比同一计算机上两进程之间通信更困难,不过如果要同时和多个进程通信它就力不从心了。

 

 

 

还是上讲的两个工程和进程(参看:内存映射文件)

 

在每个工程中分别添加namedpipe类的实现文件:

NamedPipe.h

#pragma once
class CNamedPipe
{
    HANDLE m_hHandleWritePipe;
    HANDLE m_hHandleReadPipe;

public:
    CNamedPipe(void);
    ~CNamedPipe(void);
    BOOL Create(CString strPipeName);
    BOOL Delete();
    BOOL WaitConnect();

    BOOL OpenPipe(CString strPipeName);

    BOOL SendData(const char *pStr, DWORD dwSize);
    BOOL ReadData(char *DesStr, DWORD dwSize);
    
};

NamedPipe.cpp

#include "StdAfx.h"
#include "NamedPipe.h"


CNamedPipe::CNamedPipe(void)
{
    m_hHandleWritePipe = NULL;
    m_hHandleReadPipe = NULL;
}


CNamedPipe::~CNamedPipe(void)
{
    Delete();
}

/*
    Function:    create named pipe
    PARAM:    strPipeName[in] : pipe name
    RETURN:    
            TRUE: create success
            FALSE: create failed
*/
BOOL CNamedPipe::Create(CString strPipeName)
{
    m_hHandleWritePipe = ::CreateNamedPipe(CString("\\\\.\\pipe\\") + CString(strPipeName), PIPE_ACCESS_DUPLEX, 
        PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE|PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 0, 0, NMPWAIT_WAIT_FOREVER, NULL); 

    if(NULL == m_hHandleWritePipe)
    {
        return FALSE;
    }

    return TRUE;
}

/*
    Function: delete handle and release memory
    Param: NULL
    return: 
            TRUE: delete success
            FALSE: delete failed
*/

BOOL CNamedPipe::Delete()
{
    if(NULL == m_hHandleWritePipe)
    {
        return TRUE;
    }
    else
    {
        if(!::DisconnectNamedPipe(m_hHandleWritePipe))
        {
            return FALSE;
        }

        if(!::CloseHandle(m_hHandleWritePipe))
        {
            return FALSE;
        }
    }
    

    if(NULL == m_hHandleReadPipe)
    {
        return TRUE;
    }
    else
    {
        if(!::CloseHandle(m_hHandleWritePipe))
        {
            return FALSE;
        }
    }
    
    return TRUE;
}


/*
    Function: wait client connect
    Param: NULL
    return: 
        TRUE: connect success
        FALSE: connect failed
            
*/
BOOL CNamedPipe::WaitConnect()
{
    BOOL bResult = ::ConnectNamedPipe(m_hHandleWritePipe, NULL);

    int err = GetLastError();

    return bResult;
}


/*
    Function: send data
    Param: pStr[in]: address
           dwSize[in]: buffer size
    return: 
        TRUE: send success
        FALSE: send failed
            
*/
BOOL CNamedPipe::SendData(const char *pStr, DWORD dwSize)
{
    BOOL bResult = TRUE;

    DWORD    dwWrite;
    if (!WriteFile(m_hHandleWritePipe, pStr, dwSize, &dwWrite, NULL))
    {
        AfxMessageBox("write pipe failed!");

        bResult = FALSE;
    }
    

    return bResult;
}


/*
    Function: open exist pipe
    Param: strPipeName[in]: pipe name
    return: 
        TRUE: open success
        FALSE: open failed
            
*/
BOOL CNamedPipe::OpenPipe(CString strPipeName)
{
    if (WaitNamedPipe(CString("\\\\.\\Pipe\\")+ CString(strPipeName), NMPWAIT_WAIT_FOREVER) == FALSE)
    {
        int err = GetLastError();

        return FALSE;
    }
        

    m_hHandleReadPipe = CreateFile(CString("\\\\.\\Pipe\\")+ CString(strPipeName), GENERIC_READ | GENERIC_WRITE, 0,
        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 
    if ((long)m_hHandleReadPipe == -1)
        return FALSE;

    return TRUE;
}

/*
    Function: read data from pipe
    Param:    DesStr[out]: address
            dwSize[out]; buffer size
    return: 
        TRUE: open success
        FALSE: open failed
            
*/
BOOL CNamedPipe::ReadData(char *DesStr, DWORD dwSize)
{
    DWORD len = 0;
    BOOL bResult = ReadFile(m_hHandleReadPipe, DesStr, dwSize, &len, NULL);

    return bResult;
}

 

在ShareMemoryTest工程中的按钮响应函数添加如下代码:

void CShareMemoryTestDlg::OnBnClickedOk()
{
    // TODO: Add your control notification handler code here
    //CDialogEx::OnOK();

    /*CString strShareMemory = "hello my first mapping file!\n";

    CShareMemory ShareMemory;

    char *pShareMemory = ShareMemory.Create("D:\ShareMemoryTestFile.txt", strShareMemory.GetLength());

    if(pShareMemory)
    {
        sprintf(pShareMemory, strShareMemory);

        AfxMessageBox("write over");
    }*/
    
    CNamedPipe namedPipe;
    namedPipe.Create("namedpipe");
    if(namedPipe.WaitConnect())
    {
        char data[32] = "test named pipe.";
        namedPipe.SendData(data, 32);
    }
}

 

在ShareMemoryTest2工程中的按钮响应函数添加如下代码:

void CShareMemoryTest2Dlg::OnBnClickedOk()
{
    // TODO: Add your control notification handler code here
    //CDialogEx::OnOK();

    /*CShareMemory ShareMemory;

    char *pShareMemory = ShareMemory.Open("D:\ShareMemoryTestFile.txt");

    if(pShareMemory)
    {
        AfxMessageBox(pShareMemory);

    }*/

    CNamedPipe namedPipe;
    namedPipe.OpenPipe("namedpipe");
    
    char data[32];
    memset(data, 0, 32);
    namedPipe.ReadData(data, 32);

    AfxMessageBox(data);
}

先运行第一个进程,后运行第二个进程,如下图所示:

 

posted on 2021-08-03 18:06  wu.g.q  阅读(609)  评论(0编辑  收藏  举报

导航