首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

进程间通信 - 匿名管道实现(3)

进程间通信 - 匿名管道实现(3)

示例:匿名管道实现父子进程间通信
父进程实现:(简单 MFC 程序)
项目结构:
image
消息以及成员函数和成员变量的声明:
public:
    //创建匿名管道
    afx_msg void OnBnClickedBtnCreatePipe();
    //写匿名管道
    afx_msg void OnBnClickedBtnWritePipe();
    //读匿名管道
    afx_msg void OnBnClickedBtnReadPipe();

    //定义父进程读匿名管道的成员函数
    void ParentReadPipe(void);
    //定义父进程写匿名管道的成员函数
    void ParentWritePipe(void);
    //创建 SECURITY_ATTRIBUTES 结构的成员函数
    void CreateSecurityAttributes(PSECURITY_ATTRIBUTES pSa);
    //创建 STARTUPINFO 结构的成员函数
    void CreateStartUpInfo(LPSTARTUPINFO lpStartUpInfo);
    //创建匿名管道的成员函数
    void CreateNoNamedPipe(void);

    //分别代表要从匿名管道中读的数据和要写到匿名管道中的数据
    CString m_CStrReadPipe;
    CString m_CStrWritePipe;

    //保存创建匿名管道后所得到的对匿名管道的读写句柄
    HANDLE hPipeRead;
    HANDLE hPipeWrite;

    //保证匿名管道只创建一次
    BOOL m_PipeIsCreated;
消息映射表定义:
const int        dataLength    = 100;

CNoNamedPipeParentDlg::CNoNamedPipeParentDlg(CWnd* pParent /*=NULL*/)
    : CDialogEx(CNoNamedPipeParentDlg::IDD, pParent)
    , m_CStrReadPipe(_T(""))
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

    m_PipeIsCreated = FALSE;
}

void CNoNamedPipeParentDlg:oDataExchange(CDataExchange* pDX)
{
    CDialogEx:oDataExchange(pDX);
    DDX_Text(pDX, IDC_EDIT_WRITE_PIPE, m_CStrWritePipe);
    DDX_Text(pDX, IDC_EDIT_READ_PIPE, m_CStrReadPipe);
}

BEGIN_MESSAGE_MAP(CNoNamedPipeParentDlg, CDialogEx)
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_BN_CLICKED(IDC_BTN_CREATE_PIPE,
                &CNoNamedPipeParentDlg::OnBnClickedBtnCreatePipe)
    ON_BN_CLICKED(IDC_BTN_WRITE_PIPE,
                &CNoNamedPipeParentDlg::OnBnClickedBtnWritePipe)
    ON_BN_CLICKED(IDC_BTN_READ_PIPE,
                &CNoNamedPipeParentDlg::OnBnClickedBtnReadPipe)
END_MESSAGE_MAP()
消息处理函数:
//创建匿名管道按钮的消息处理函数
void CNoNamedPipeParentDlg::OnBnClickedBtnCreatePipe()
{
    if(m_PipeIsCreated == FALSE)
    {
        this->CreateNoNamedPipe();
    }
}


//写入数据到匿名管道中按钮的消息处理函数
void CNoNamedPipeParentDlg::OnBnClickedBtnWritePipe()
{
    this->arentWritePipe();
}


//从匿名管道中读取数据按钮的消息处理函数
void CNoNamedPipeParentDlg::OnBnClickedBtnReadPipe()
{
    this->arentReadPipe();
}


//接收数据
void CNoNamedPipeParentDlg:arentReadPipe(void)
{
    DWORD            dwRead;
    char *            pReadBuf;
    CString            cStrRecvData;

    pReadBuf = new char[dataLength];
    memset(pReadBuf, 0, dataLength);

    if(!ReadFile(hPipeRead, pReadBuf, dataLength, &dwRead, NULL))
    {
        MessageBox(TEXT("   从匿名管道接收数据失败 ..."),
            TEXT("提示"), MB_ICONERROR);
        return;
    }

    cStrRecvData = "   从匿名管道接收数据成功:    ";
    cStrRecvData += pReadBuf;

    this->m_CStrReadPipe.Empty();

    this->m_CStrReadPipe = pReadBuf;
    UpdateData(FALSE);

    MessageBox(cStrRecvData, TEXT("提示"), MB_ICONINFORMATION);
}


//发送数据
void CNoNamedPipeParentDlg:arentWritePipe(void)
{
    UpdateData();

    if(!this->m_CStrWritePipe.IsEmpty())
    {
        char *            pSendData;
        DWORD            dwWrite;
        CString            cStrSendData;

        //在这里需要将 Unicode 字符集转换为 ASCII 字符集
        pSendData = new char[this->m_CStrWritePipe.GetLength() + 1];
        memset(pSendData, 0, this->m_CStrWritePipe.GetLength() + 1);
        for(int i=0;i<this->m_CStrWritePipe.GetLength();i++)
        {
            pSendData[i] = (char)this->m_CStrWritePipe.GetAt(i);
        }

        if(!WriteFile(hPipeWrite, pSendData,
            this->m_CStrWritePipe.GetLength() + 1, &dwWrite, NULL))
        {
            MessageBox(TEXT("   给匿名管道发送数据失败 ..."),
                TEXT("提示"), MB_ICONERROR);
            return;
        }

        cStrSendData = "   给匿名管道发送数据成功:    ";
        cStrSendData += this->m_CStrWritePipe;

        this->m_CStrWritePipe.Empty();
        UpdateData(FALSE);

        MessageBox(cStrSendData, TEXT("提示"), MB_ICONINFORMATION);
    }
    else
    {
        MessageBox(TEXT("   请先输入要发送给匿名管道的数据 ..."),
            TEXT("提示"), MB_ICONERROR);
    }
}
继承事业,薪火相传
返回列表