通过匿名管道在进程间双向通信

由于匿名管道只能是单向的,因此要建立双向通信必须建立2个管道。

父程序代码:

view plaincopy to clipboardprint?
int main()   
{   
    //定义四个句炳保留两个管道的信息   
    HANDLE hReadPipe1, hWritePipe1, hReadPipe2, hWritePipe2;   
    SECURITY_ATTRIBUTES sat;   
    STARTUPINFO startupinfo;   
    PROCESS_INFORMATION pinfo;   
    BYTE buffer[1024];   
    DWORD byteRead, byteWrite;   
       
    string rString;   
    string m_Host= "Client.exe";   
    sat.nLength=sizeof(SECURITY_ATTRIBUTES);   
    sat.bInheritHandle=true;   
    sat.lpSecurityDescriptor=NULL;   
    //创建管道,它用来做子进程的输出   
    if(!CreatePipe(&hReadPipe1, &hWritePipe1, &sat, NULL))   
    {   
        cout<<("Create Pipe Error!")<<endl;   
        return 1;   
    }   
       
    //创建管道,它用来做子进程的输入   
    if(!CreatePipe(&hReadPipe2, &hWritePipe2, &sat, NULL))   
    {   
        cout<<"Create Pipe Error!"<<endl;   
        return 1;   
    }   
       
    startupinfo.cb=sizeof(STARTUPINFO);   
    //用GetStartupInfo获得当前进程的参数,否则STARTUPINFO参数太多,会让人抓狂   
    GetStartupInfo(&startupinfo);   
    startupinfo.hStdInput = hReadPipe2;   
    startupinfo.hStdError=hWritePipe1;   
    startupinfo.hStdOutput=hWritePipe1;   
    //要有STARTF_USESTDHANDLES,否则hStdInput, hStdOutput, hStdError无效   
    startupinfo.dwFlags=STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;   
    startupinfo.wShowWindow=SW_HIDE;   
    if(!CreateProcess(NULL, (char*)m_Host.c_str(), NULL, NULL, TRUE, NULL, NULL, NULL, &startupinfo, &pinfo))   
    {   
        cout<<("create process error!")<<endl;   
        return 1;   
    }   

    RtlZeroMemory(buffer,1024);   
    //进程的输出重定向到hWritePipe1,所以从hReadPipe1读取   
    // 在从管道中读取到数据前父进程将发生阻塞   
    if (ReadFile(hReadPipe1,buffer,1023,&byteRead,NULL))   
        {   
        cout<<buffer;   
        }   

    string csWrite = "ping www.sina.com.cn\r\n";   
    //进程的输入重定向到hReadPipe2,所以从hWritePipe2写入   
    // 向管道中写数据不会发生阻塞,此循环会一直执行下去。   
    while (WriteFile(hWritePipe2, (LPCVOID)csWrite.c_str(), csWrite.length() + 1, &byteWrite, NULL))   
    {   
    cout << "write " << byteWrite << endl;   
    }   
    
    CloseHandle(hReadPipe1);   
    CloseHandle(hReadPipe2);   
    CloseHandle(hWritePipe1);   
    CloseHandle(hWritePipe2);   
       
    return 0;   


int main()
{
//定义四个句炳保留两个管道的信息
    HANDLE hReadPipe1, hWritePipe1, hReadPipe2, hWritePipe2;
    SECURITY_ATTRIBUTES sat;
    STARTUPINFO startupinfo;
    PROCESS_INFORMATION pinfo;
    BYTE buffer[1024];
    DWORD byteRead, byteWrite;

    string rString;
    string m_Host= "Client.exe";
    sat.nLength=sizeof(SECURITY_ATTRIBUTES);
    sat.bInheritHandle=true;
    sat.lpSecurityDescriptor=NULL;
    //创建管道,它用来做子进程的输出
    if(!CreatePipe(&hReadPipe1, &hWritePipe1, &sat, NULL))
    {
        cout<<("Create Pipe Error!")<<endl;
        return 1;
    }
    
    //创建管道,它用来做子进程的输入
    if(!CreatePipe(&hReadPipe2, &hWritePipe2, &sat, NULL))
    {
        cout<<"Create Pipe Error!"<<endl;
        return 1;
    }
    
    startupinfo.cb=sizeof(STARTUPINFO);
    //用GetStartupInfo获得当前进程的参数,否则STARTUPINFO参数太多,会让人抓狂
    GetStartupInfo(&startupinfo);
    startupinfo.hStdInput = hReadPipe2;
    startupinfo.hStdError=hWritePipe1;
    startupinfo.hStdOutput=hWritePipe1;
    //要有STARTF_USESTDHANDLES,否则hStdInput, hStdOutput, hStdError无效
    startupinfo.dwFlags=STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    startupinfo.wShowWindow=SW_HIDE;
    if(!CreateProcess(NULL, (char*)m_Host.c_str(), NULL, NULL, TRUE, NULL, NULL, NULL, &startupinfo, &pinfo))
    {
        cout<<("create process error!")<<endl;
        return 1;
    }

    RtlZeroMemory(buffer,1024);
    //进程的输出重定向到hWritePipe1,所以从hReadPipe1读取
    // 在从管道中读取到数据前父进程将发生阻塞
    if (ReadFile(hReadPipe1,buffer,1023,&byteRead,NULL))
        {
     cout<<buffer;
        }

    string csWrite = "ping www.sina.com.cn\r\n";
    //进程的输入重定向到hReadPipe2,所以从hWritePipe2写入
    // 向管道中写数据不会发生阻塞,此循环会一直执行下去。
    while (WriteFile(hWritePipe2, (LPCVOID)csWrite.c_str(), csWrite.length() + 1, &byteWrite, NULL))
    {
cout << "write " << byteWrite << endl;
    }

    CloseHandle(hReadPipe1);
    CloseHandle(hReadPipe2);
    CloseHandle(hWritePipe1);
    CloseHandle(hWritePipe2);

    return 0;

}

子进程代码:

view plaincopy to clipboardprint?
int main(int argc, char* argv[])   
{   

    hRead = GetStdHandle(STD_INPUT_HANDLE);   
    hWrite = GetStdHandle(STD_OUTPUT_HANDLE);   

    char s[] = "Hello, I am child process\n";   
    DWORD dwWrite;   
       
    if (!WriteFile(hWrite, s, strlen(s) + 1, &dwWrite, NULL))   
    {   
        out << "Write to pipe failed!" << endl;   
        return -1;   
    }   

    char buf[100];   
    DWORD dwRead;   
    if(!ReadFile(hRead, buf, 100, &dwRead, NULL))   
    {   
        out << "Read from pipe failed!" << endl;   
        return -1;     
    }   
}

MFC是微软基于C++的一个应用程序框架,它可以帮助开发人员快速创建Windows应用程序。进程通信(IPC)是不同进程进行数据交换和通信的一种方法。管道是一种常见的IPC机制,它允许两个进程进行双向通信。 在MFC中,使用管道进行进程通信可以分为两个步骤:创建管道和使用管道进行通信。 首先,需要创建一个管道。可以使用CreatePipe函数来创建匿名管道,它接受两个参数,第一个参数是用于接收管道句柄的指针,第二个参数是用于发送管道句柄的指针。成功创建管道后,你将获得两个句柄,一个用于读取数据,一个用于写入数据。 然后,可以使用ReadFile和WriteFile函数来读取和写入管道中的数据。这些函数可以传入一个管道句柄,一个缓冲区来存储数据以及数据的长度。通过这些函数,可以在两个进程传递数据。 如果需要实现双向通信,可以在每个进程中使用一个管道来进行读取和写入操作。这样,两个进程就可以通过各自的管道进行双向通信了。例如,进程A使用管道A向进程B发送数据,进程B使用管道B向进程A发送数据。 总结起来,MFC可以使用管道进行进程通信,通过创建管道和使用ReadFile和WriteFile函数来实现数据的读取和写入。如果需要双向通信,则可以在两个进程中分别创建管道来进行双向数据传输。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值