zoukankan      html  css  js  c++  java
  • 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 }

     

  • 相关阅读:
    Intent的跳转和传值
    Intent传值的学习
    Activity,Window,View之间是什么关系?
    MATCH_PARENT和FILL_PARENT之间的区别?
    Activity的运行过程
    onCreate和onStart谁的开销大?
    SDKManager连不上墙外的网,列表刷新不出来怎么办?
    AndroidEclipse里的视图里想添加SDK Manager但是找不到怎么办?
    出现“Unable to resolve target 'android-XXX'”怎么处理?
    安卓进程的生命周期
  • 原文地址:https://www.cnblogs.com/Baesky/p/windows_pipe_anonymous_pipe.html
Copyright © 2011-2022 走看看