• The Windows Pipes Programming windows“管道”编程 之 "匿名管道"


    何为“管道”?

    “管道”是进程间通讯的一段共享内存区域。创建管道的进程成为管道服务器,连接到管道上的进程成为管道客户端。一个进程向管道写数据,其他进程可以从管道中读取数据。

    “管道的分类”

    管道分为两种,匿名管道和命名管道。匿名管道比命名管道需要的开销要小,但是提供的功能要少。管道在这里的含义暗示着它是一种连接信息的管子。管子有两端,单工通讯的管道允许在写端的进程把信息写入管子,在读端的进程读取管道中的信息。全双工通讯的管道允许在两端进行读写。

    匿名管道提供单工通讯,没有名称。并且只能用于本地,不能通过网络通讯。

    命名管道是一个有名称,能提供单工或全双工通讯的管子。它允许一个管道服务器,多个管道客户端。所有命名管道的实例共享一个管道名称,但是每个实例有它自己的缓冲区和句柄,并且为每个服务器/客户端通讯提供单独的信息传输渠道.这种方式允许多个管道客户端同时使用命名管道.任何命名管道都可以被任何进程访问,但是受制与安全检测策略.因此命名管道可以方便的区分相关与不相关的进程.

    任何进程都可以作为服务器或者客户端,这使得p2p通信成为可能.这里管道服务器是指创建管道的进程,管道客户端是指连接到一个命名管道实例上的进程.管道服务器端使用CreateNamedPipe创建命名管道,使用ConnectNamedPipe接收连接请求.管道客户端使用CreateFile 和CallNamedPipe连接命名管道.

    命名管道可以为本地或者通过网络与远程电脑中的进程提供通讯.如果你仅仅想让命名管道运行在本地,可以用本地RPC策略或者禁止访问NT AUTHORITY\NETWORK.

    匿名管道”使用示例

    代码要实现的功能就是创建两个控制台程序,一个控制台写消息,另一个控制台收消息。这是子父进程通信中匿名管道的典型用法,我们先直观看看这个示例是怎么工作的:

     

    左边是父控制台,右边是子控制台。左边输入字符,右边就会显示出来:

    下面是代码:

    父控制台
     1 #include "UnNamedPipe.h"
     2 #include <iostream>
     3 
     4 using namespace std;
     5 
     6 HANDLE g_hReadPipe;
     7 HANDLE g_hWritePipe;
     8 
     9 int main()
    10 {
    11     LPTSTR errbuff;
    12     char strBuff[256] = {0};
    13     char* QUITCHAR = "q";
    14     CUnNamedPipe myPipe;
    15     SECURITY_ATTRIBUTES saAttr;
    16     saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
    17     saAttr.bInheritHandle = TRUE; 
    18     saAttr.lpSecurityDescriptor = NULL; 
    19     STARTUPINFO siStartInfo;
    20     PROCESS_INFORMATION piProcInfo;
    21     DWORD nWriteTo;
    22     TCHAR szAppName[] = TEXT("C:\\Users\\user\\Documents\\Visual Studio 2010\\Projects\\PipeWorkShop\\Debug\\AnonymousPipeClientTest.exe"); 
    23     if(!myPipe.CreatePipe(g_hReadPipe, g_hWritePipe, saAttr, 0))
    24     {
    25         DWORD d = GetLastError();
    26         FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER  | 
    27             FORMAT_MESSAGE_IGNORE_INSERTS  | 
    28             FORMAT_MESSAGE_FROM_SYSTEM,
    29             NULL,
    30             d, 
    31             LANG_NEUTRAL,
    32             (LPTSTR) & errbuff,
    33             0 ,
    34             NULL );
    35         cout<<"can not create pipe!"<<endl;
    36         return 1;
    37     }
    38 
    39     if(!SetHandleInformation(g_hReadPipe, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
    40     {
    41         cout<<"set handle property error!"<<endl;
    42     }
    43     /*if(!SetHandleInformation(g_hWritePipe, HANDLE_FLAG_INHERIT, 0))
    44     {
    45         cout<<"set handle property error!"<<endl;
    46     }*/
    47     ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
    48     siStartInfo.cb = sizeof(STARTUPINFO); 
    49     siStartInfo.hStdInput = g_hReadPipe;
    50     siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    51     siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
    52     
    53     if(!CreateProcess(szAppName, NULL, NULL, NULL, TRUE,CREATE_NEW_CONSOLE, NULL,NULL, &siStartInfo, &piProcInfo))
    54     {
    55         DWORD d = GetLastError();
    56         FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER  | 
    57                      FORMAT_MESSAGE_IGNORE_INSERTS  | 
    58                      FORMAT_MESSAGE_FROM_SYSTEM,
    59                      NULL,
    60                      d, 
    61                      LANG_NEUTRAL,
    62                      (LPTSTR) & errbuff,
    63                       0 ,
    64                      NULL );
    65 
    66         cout<<"can't create process:"<<szAppName<<endl;
    67         cout<<errbuff;
    68         return 0;
    69     }
    70     cout<<"press q to quit, others to show!"<<endl;
    71     while (cin>>strBuff )
    72     {
    73         while(strBuff[0]!=0)
    74         {
    75             if(!WriteFile(g_hWritePipe, strBuff, sizeof strBuff, &nWriteTo, NULL))
    76             {
    77                 cout<<"write file error!"<<endl;
    78                 break;
    79             }
    80             if(strcmp(strBuff, QUITCHAR) == 0)
    81             {
    82                 return 0;;
    83             }
    84             ZeroMemory(strBuff, sizeof(strBuff));
    85         }
    86         
    87     }
    88     CloseHandle(piProcInfo.hProcess);
    89     CloseHandle(piProcInfo.hThread);
    90 
    91     myPipe.ClosePipe(g_hReadPipe);
    92     myPipe.ClosePipe(g_hWritePipe);
    93 
    94     return 0;
    95 }
    子控制台
     1 #include <Windows.h>
     2 #include <iostream>
     3 
     4 using namespace std;
     5 int main()
     6 {
     7     HANDLE hStdin, hStdout;
     8     char buff[256] = {0};
     9     char* QUIT = "q";
    10     DWORD dwRead;
    11     DWORD dwWrite;
    12     hStdin = GetStdHandle(STD_INPUT_HANDLE);
    13     hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    14     if (hStdin == INVALID_HANDLE_VALUE || hStdout == INVALID_HANDLE_VALUE)
    15     {
    16         return 1;
    17     }
    18     cout<<"client is working!"<<endl;
    19     while(1)
    20     {
    21         if(ReadFile(hStdin, buff, 256, &dwRead, NULL) && buff[0] != 0)
    22         {
    23             if(strcmp(buff,QUIT) == 0)
    24                 return 0;
    25             else
    26             {
    27                 cout<<buff<<endl;
    28                 //WriteFile(hStdout, buff, 256, &dwWrite, NULL); there is someting interesting if you use this instead of before one.
    29                 ZeroMemory(buff, sizeof buff);
    30             }
    31             
    32         }
    33         
    34         Sleep(500);
    35     }
    36     cout<<"client will shutdown in 3 sec!"<<endl;
    37     Sleep(3000);
    38     return 0;
    39 }

    接口代码:

     1 /********************************************************************
     2     created:    2012/08/11
     3     file name:    IPipe.h
     4     author:        baesky
     5     http://www.cnblogs.com/Baesky/
     6     purpose:    Give a public interface.
     7 *********************************************************************/
     8 
     9 #pragma once
    10 #include <Windows.h>
    11 class IPipe
    12 {
    13 public:
    14     virtual bool CreatePipe(HANDLE& hReadPipe, HANDLE& hWritePipe, SECURITY_ATTRIBUTES& lpPipeAttributes, DWORD nBuffSize) = 0;
    15     virtual bool ClosePipe(HANDLE hPipe) = 0;
    16 };
    UnNamedPipe.h
     1 #pragma once
     2 #include "IPipe.h"
     3 
     4 
     5 class CUnNamedPipe:public IPipe
     6 {
     7 public:
     8     CUnNamedPipe(void);
     9     ~CUnNamedPipe(void);
    10 
    11     bool CreatePipe(HANDLE& hReadPipe, HANDLE& hWritePipe, SECURITY_ATTRIBUTES& lpPipeAttributes, DWORD nBuffSize);
    12     bool ClosePipe(HANDLE hPipe);
    13 };
    UnNamedPipe.cpp
     1 #include "UnNamedPipe.h"
     2 
     3 
     4 CUnNamedPipe::CUnNamedPipe(void)
     5 {
     6 }
     7 
     8 
     9 CUnNamedPipe::~CUnNamedPipe(void)
    10 {
    11 }
    12 
    13 bool CUnNamedPipe::CreatePipe(HANDLE& hReadPipe, HANDLE& hWritePipe, SECURITY_ATTRIBUTES& lpPipeAttributes, DWORD nBuffSize)
    14 {
    15     return ::CreatePipe(&hReadPipe, &hWritePipe, &lpPipeAttributes, nBuffSize);
    16 }
    17 
    18 bool CUnNamedPipe::ClosePipe(HANDLE hPipe)
    19 {
    20     return CloseHandle(hPipe);
    21 }

     

  • 相关阅读:
    Leetcode NO.110 Balanced Binary Tree 平衡二叉树
    Leetcode NO.226 Invert Binary Tree 翻转二叉树
    Leetcode NO.215 Kth Largest Element In An Array 数组中的第K个最大元素
    根据特征的浏览器判断
    Cygwin在打开在当前目录
    【转帖】科学对待 健康养猫 打造快乐孕妇
    解决chrome浏览器安装扩展、应用程序一直处在“检查中”的问题
    对【SQL SERVER 分布式事务解决方案】的心得补充
    关于“点击这里继续访问您选择的百度XXX”
    VBA一例:如何保持文本框焦点
  • 原文地址:https://www.cnblogs.com/Baesky/p/windows_pipe_anonymous_pipe.html
Copyright © 2020-2023  润新知