WINDOWS匿名管道

WINDOWS匿名管道

我的理解:

windows的匿名管道 在于 父进程和子进程之间创建,需要创建两个管道,一共四个HANDLE,还需要关掉两个

设父进程到子进程的管道为pipein,连接父进程的一端,HANDLE为wt,连接子进程的一端,HANDLE为rd

设子进程到父进程的管道为pipeout,连接父进程的一端,HANDLE为rd,连接子进程的一端,HANDLE为wt

父进程代码解析:

#include "stdafx.h"
#include <string>
#include <iostream>
#include <Windows.h>
 
int main(int argc, char **argv)
{
    //创建两个管道需要的4个句柄
    HANDLE hpipeInRd, hpipeInWt;
    HANDLE hpipeOutRd, hpipeOutWt;
 
    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = FALSE;
 
    if (!CreatePipe(&hpipeOutRd, &hpipeOutWt, &sa, 0)) 
    {
        printf("stdout Create Pipe error!!!");
        return 1;
    }
 
    //将hpipeOutRd关闭
    if(!SetHandleInformation(hpipeOutRd, HANDLE_FLAG_INHERIT, 0))
    {
        printf("stdout SetHandleInformation !!!");
        return 1;
    }
 
    if (!CreatePipe(&hpipeInRd, &hpipeInWt, &sa, 0))
    {
        printf("stdin Create Pipe error!!!");
        return 1;
    }
 
    //将hpipeInWt关闭
    if (!SetHandleInformation(hpipeInWt, HANDLE_FLAG_INHERIT, 0))
    {
        printf("stdout SetHandleInformation !!!");
        return 1;
    }
 
    //创建子进程
    TCHAR lpCommandLine[100] = _T("client");
    PROCESS_INFORMATION pi;//pi 获取子进程的信息
    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    STARTUPINFO si;
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.hStdError = hpipeOutWt;
    si.hStdOutput = hpipeOutWt; //将子进程的标准输出重定向到pipeout管道的写段
    si.hStdInput = hpipeInRd;    //将子进程的标准输入重定向到pipein管道的读端
    si.dwFlags |= STARTF_USESTDHANDLES;
 
    //CREATE_NEW_CONSOLE:子进程将打开一个新的命令行终端
    int ret = CreateProcess(NULL, lpCommandLine, NULL, NULL,
        TRUE, 0/*CREATE_NEW_CONSOLE*/, NULL, NULL, &si, &pi);
 
    if (ret) 
    {
        //此处我暂时没办法知道子进程什么时候打开
        //WaitForSingleObject函数用来检测hHandle事件的信号状态,
        //在某一线程中调用该函数时,线程暂时挂起,如果在挂起的
        //dwMilliseconds毫秒内,线程所等待的对象变为有信号状态,
        //则该函数立即返回;如果超时时间已经到达dwMilliseconds毫秒,
        //但hHandle所指向的对象还没有变成有信号状态,函数照样返回。
        //如果将参数设置为INFINITE, 子线程由于标准输入和标准输出被重定向
        //所以在控制台无法进行人为的输入和输出,父进程无法得到子进程的信号
        //也一直阻塞在那里
        WaitForSingleObject(pi.hProcess, 2);
        printf("child process is created!!!\n");
        //在父进程中不需要子进程的一些东西,
        //所以将子进程句柄和子进程的线程句柄关闭
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    }
 
    //父进程中标准输入,以下有这几种写法
    char buffer[100] = {0};
    DWORD read;
    HANDLE hstdin = GetStdHandle(STD_INPUT_HANDLE);
    ReadFile(hstdin, buffer, sizeof(buffer), &read, NULL);
    //fgets(buffer, sizeof(buffer), stdin);
    //std::cin >> buffer;
    //scanf_s("%s",buffer, sizeof(buffer));
 
    //父进程将从控制台获得的数据写到pipein管道的写端
    DWORD writeBytes;
    WriteFile(hpipeInWt, buffer, strlen(buffer), &writeBytes, NULL);
    
    //父进程从pipeout的读端读取数据
    DWORD readBytes;
    memset(buffer, 0, sizeof(buffer));
    ReadFile(hpipeOutRd, buffer, sizeof(buffer), &readBytes, NULL);
    
    printf("msg from child process is: %s\n", buffer);
 
    //关闭句柄
    CloseHandle(hpipeInRd);
    CloseHandle(hpipeInWt);
    CloseHandle(hpipeOutWt);
    CloseHandle(hpipeOutRd);
    return 0;
}
发布了506 篇原创文章 · 获赞 40 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/huang714/article/details/104749050