zoukankan      html  css  js  c++  java
  • 匿名管道 双向通信 需要两个

    http://www.cppblog.com/returnnull/archive/2007/05/11/23855.html

    http://www.cppblog.com/ice197983/articles/4425.html

    http://blog.163.com/kksunshine@yeah/blog/static/118612388201121154017976/

    http://blog.163.com/tangmin927@126/blog/static/31537494200922043055553/

    http://www.cnblogs.com/BoyXiao/archive/2011/01/01/1923828.html

    View Code
    #include <Windows.h>
    
    int main(int argc, char* argv[])
    {
        HANDLE hWrite;//管道的写入句柄
        HANDLE hRead; //管道的读取句柄
        HANDLE hWrite2;//管道的写入句柄
        HANDLE hRead2; //管道的读取句柄
        SECURITY_ATTRIBUTES sa;
        //总共就三个参数
        sa.bInheritHandle=TRUE; //表示可被子进程所继承
        sa.lpSecurityDescriptor=NULL; //安全描述符号一般都设置成NULL,即默认描述符
        sa.nLength=sizeof(SECURITY_ATTRIBUTES); //管道长度
        if(!CreatePipe(&hRead,&hWrite,&sa,0))
        {
            printf("创建匿名函数失败!\n");
        }
    
        if(!CreatePipe(&hRead2,&hWrite2,&sa,0))
        {
            printf("创建匿名函数失败!\n");
        }
        STARTUPINFO sui;
        PROCESS_INFORMATION pi;
        //调用ZeroMemory方法将该结构体中的所有成员都置为0,这是因为这个结构体的成员很多,如果开始的时候没有置为0的话,那它的值是随机的,将这样的结构体传给CreateProcess,可能会影响到执行的结果。
        memset(&sui,0,sizeof(STARTUPINFO));
        sui.cb            =sizeof(STARTUPINFO); //设置结构体的大小
        sui.dwFlags        |=STARTF_USESTDHANDLES; //该标识表示标准输入句柄,标准输出句柄和错误句柄是有用的
        sui.hStdInput    =hRead2; //将子进程的输入句柄设置成父进程的读句柄
        sui.hStdOutput    =hWrite; //将子进程的输出句柄设置成父进程的写句柄
        sui.hStdError    =GetStdHandle(STD_ERROR_HANDLE); //得到标准错误句柄,是父进程的错误句柄,该行代码在本程序中没有实际的用途意义
    
        //因为是匿名管道,是没有名称的管道,只有通过CreateProcess由上而下的传递管道操作句柄。
        //if(!CreateProcess(_T("c:\\windows\\system32\\cmd.exe"),NULL,NULL,NULL,TRUE,0,NULL,NULL,&sui,&pi))
        if(!CreateProcess(_T("D:\\Visual Studio 2012\\Projects\\boost测试\\Debug\\piple_child.exe"),NULL,NULL,NULL,TRUE,0,NULL,NULL,&sui,&pi))
        {
            printf("创建子进程失败!\n");
            CloseHandle(hRead);
            CloseHandle(hWrite);
    
            CloseHandle(hRead2);
            CloseHandle(hWrite2);
    
            hRead=NULL;
            hWrite=NULL;
            hRead2=NULL;
            hWrite2=NULL;
        }
        else
        {
            //创建一个新的进程的时候,系统会创建一个进程内核对象和一个线程内核对象,内核对象都有一个使用基数,初始调用的时候,都设置为1。在CreateProcess返回之前,该函数打开进程和线程的内核对象,并将进程相关的句柄放置到结构体PROCESS_INFORMATION的hProcess和hThread中,当Process在内部打开这些对象的时候,使得每个对象的使用基数增加到2了。如果在父进程中不需要使用这两个句柄,就将这个句柄进行关闭,使得使用基数减1。当子进程终结的时候,系统会在将使用基数减1,使得子进程的进程内核对象和线程内核对象的使用基数变为0,这样内核对象就可以被释放了。
            CloseHandle(pi.hProcess); //关闭子进程的句柄
            CloseHandle(pi.hThread); //关闭子进程中主线程的句柄
        }
    
        char *buf= "ping www.sina.com.cn\r\n";
        DWORD dwWrite;
        //进程的输入重定向到hReadPipe2,所以从hWritePipe2写入
        if(!WriteFile(hWrite2,buf,strlen(buf)+1,&dwWrite,NULL))
        {
            printf("匿名管道写入数据失败!\n");
        }
    
        char bufRead[1000];
        DWORD dwRead;
    
        while (true)
        {
            //进程的输出重定向到hWritePipe1,所以从hReadPipe1读取
            if(!ReadFile(hRead,bufRead,1000 -1 ,&dwRead,NULL))
            {
                printf("匿名管道读取数据失败!\n");
            }
            else
            {
                bufRead[dwRead] = '\0'; 
                printf("%s\n",bufRead);
            }
        }
    }
    View Code
    #include "stdafx.h"
    #include <Windows.h>
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        DWORD dwReaded =0;                
        HANDLE hRead  = GetStdHandle(STD_INPUT_HANDLE); 
        HANDLE hWrite = GetStdHandle(STD_OUTPUT_HANDLE);
    
        //HANDLE hRead2  = GetStdHandle(STD_INPUT_HANDLE); 
        //HANDLE hWrite2 = GetStdHandle(STD_OUTPUT_HANDLE);
    
        if( hRead )
        {                  
            /*'从管道接收数据*/
            const int  nBufSize = 2048;
            char        szBuf[nBufSize];
    
            if(ReadFile(hRead, &szBuf,nBufSize, &dwReaded, NULL))
            {
                    //char buf[]="http://www.sina.com.cn";
                    DWORD dwWrite;
                    if(!WriteFile(hWrite,szBuf,dwReaded,&dwWrite,NULL))
                    {
                        printf("写入数据失败!\n");
                    }
            }
    
        }
        //printf("child\n");
        return 0;
    }
  • 相关阅读:
    BBED Structure
    Git 入门操作笔记总结
    archive_a: 2017/10
    (数论六)关于欧拉(定理、公式、函数、降幂)
    ES6解构
    生成天气预报网站
    vue动态添加路由,跳转页面时,页面报错路由重复:vue-router.esm.js?8c4f:16 [vue-router] Duplicate named routes definition: { name: "Login", path: "/login" }
    express中的中间件(middleware)、自定义中间件、静态文件中间件、路由中间件
    jQuery的ajax请求express服务器返回数据
    express搭建web服务器、路由、get、post请求、multer上传文件、EJS模板引擎的使用
  • 原文地址:https://www.cnblogs.com/logitechlike/p/3064035.html
Copyright © 2011-2022 走看看