Windows中的管道技术

   在以前学Linux的时候,碰到过管道的问题,认为管道不过是一个程序的输出作为一个程序的输入。就像这样:
   #cat file | grep "abc"
   这里,cat file的output,直接当作grep "abc"这个命令的input,利用管道,可以改变程序默认的input与output.

   
   今天无意中翻MSDN,看到windows当中也有Pipe的概念.以前都一直不知道,汗~~
   
   Pipe是怎么定义的:
         A pipe is a section of shared memory that processes use for communication. The process that creates a pipe is the pipe server. A process that connects to a pipe is a pipe client. One process writes information to the pipe, then the other process reads the information from the pipe. 

         也就是说,管道就是一部份共享内存以便进程可以用来相互通信,创建了Pipe内核对象的进程就是一个Pipe Server, 当另一个进程与这个进程创建的Pipe Server连接时,就称为Pipe Client.当一个进程往Piple当中写入信息时,另一个进程便可以从这个Pipe读出这个信息。

There are two types of pipes: anonymous pipes and named pipes. Anonymous pipes require less overhead than named pipes, but offer limited services.

The term pipe, as used here, implies that a pipe is used as an information conduit. Conceptually, a pipe has two ends. A one-way pipe allows the process at one end to write to the pipe, and allows the process at the other end to read from the pipe. A two-way (or duplex) pipe allows a process to read and write from its end of the pipe:

   Pipe分为两种:一个是anonymous pipes(末名命Pipe),另一个是named pipes(命名Pipe), anonymous pipes所需要的开销要比named pipes要来得少,但是缺点是提供的功能也少。
   pipe这个术语在这里的意思是指:作为一个提供信息的管道,从概念上来理解,Pipe包含了两个端,一端可以允许进程写入,另一端允许进程读出。两个端都可以让进程读或者写。

1.Anonymous Pipes

An anonymous pipe is an unnamed, one-way pipe that typically transfers data between a parent process and a child process. Anonymous pipes are always local; they cannot be used for communication over a network.
      可以允许父进程与子进程之间传输数据。它常常用于本地机器,对于网络内的不同机器之间的通信它并不适合。

2.Named Pipes

A named pipe is a named, one-way or duplex pipe for communication between the pipe server and one or more pipe clients. All instances of a named pipe share the same pipe name, but each instance has its own buffers and handles, and provides a separate conduit for client-server communication. The use of instances enables multiple pipe clients to use the same named pipe simultaneously.
   命名Pipe中的两个端可以作为一台pipe服务器与另一台(或多台)pipe客户端通信的工具。所有的pipe实例对象共享Pipe Name,但是,每个Pipe实例却有自己的buffer和handle.另外,Pipe Server与各个Pipe client传输数据所用的管道也是不同的,并不共享。它最大的作用在于可以让多个Pipe Client用这个Pipe Name来同时传送数据。

Any process can access named pipes, subject to security checks, making named pipes an easy form of communication between related or unrelated processes. Named pipes can be used to provide communication between processes on the same computer or between processes on different computers across a network.
   任何进程都可以控制named pipes。并遵照其安全性检查,任何有关联的和不关联的进程都可以通过Named Pipes进行通信,可以在一个网络内或不同网络之间的进程进行通信。

Any process can act as both a server and a client, making peer-to-peer communication possible. As used here, the term pipe server refers to a process that creates a named pipe, and the term pipe client refers to a process that connects to an instance of a named pipe.
   进程既可以作为Server端又可以作为Client端,在端对端的通信环境下,术语Pipe Server是指创建Pipe的那个进程,而Pipe Client是指连接Pipe实例的进程。





Example:


   第一个,先看一个unonymous pipe的例子。这个例子是讲把一个DOS进程上的内容通过管道技术输出到一个MFC应用程序的CEdit控件中。

   例子来源:http://dev.csdn.net/develop/article/18/18338.shtm

   首先,创建一个Pipe,设置好其两个端,用CreatePipe函数。在CreatePipe前,设定其安全选项,因为要与子进程通信,子进程也需要用到这个pipe内核对象. 所以内核对象的句柄还是要被继承的。(内核对象详见核心编程第三章
  
HANDLE hReadPipe, hWritePipe;
SECURITY_ATTRIBUTES sa;
          
sa.nLength 
= sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor 
= NULL; //使用系统默认的安全描述符
sa.bInheritHandle = TRUE; //一定要为TRUE,不然句柄不能被继承。

CreeatePipe(&hReadPipe,&hWritePipe,&sa,0); //创建pipe内核对象,设置好hReadPipe,hWritePipe.

   下面,创建一个DOS进程与其进行通信.创建进程的函数是CreateProcess.这个函数中有个LPSTARTUPINFO lpStartupInfo参数要注意一下.它设定的是创建进程窗口的风格,获得更多的创建进程的方法,见:核心编程第四章

   
  STARTUPINFO si;
  PROCESS_INFORMATION pi; 
  si.cb 
= sizeof(STARTUPINFO);
  GetStartupInfo(
&si); 
  si.hStdError 
= hWritePipe; //设定其标准错误输出为hWritePipe
  si.hStdOutput = hWritePipe; //设定其标准输出为hWritePipe
  si.wShowWindow = SW_HIDE;
  si.dwFlags 
= STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
  
if (!CreateProcess(NULL,"c:\\windows\\system32\\cmd.exe/c dir /?"
        ,NULL,NULL,TRUE,NULL,NULL,NULL,
&si,&pi)) {
        MessageBox(
"Error on CreateProcess()");
        
return;
  }

  CloseHandle(hWritePipe);

   上面设置的是Dos窗口的内容输出到hWritePipe,下面就是要把hReadPipe设置好,两个Process之间就可以通信了.
   
char buffer[4096= {0};
  DWORD bytesRead; 
  
while (true{
      
if (ReadFile(hReadPipe,buffer,4095,&bytesRead,NULL) == NULL)//从hReadPipe中读出数据.
          break;
      m_Edit1 
+= buffer;
      UpdateData(
false);
      Sleep(
200); 
  }
 



还有Named Pipes的内容,下回分解...........
posted @ 2006-05-27 13:49  shipfi  阅读(15388)  评论(2编辑  收藏  举报