随笔-341  评论-2670  文章-0  trackbacks-0
    此管道非彼管道,不是unix用来做命令行的那个。

    Windows的管道可以访问本机或已知机器名的机器上的命名管道,自己也可以建立命名管道。一个命名管道就跟一个server socket一样,可以进行listen,并产生很多实例来跟很多个client交谈。主要函数有:

    CallNamedPipe:连接、读、写、关闭,TimeOut
    ConnectNamedPipe:等待client连接
    CreateNamedPipe:创建named pipe
    DisconnectNamedPipe:断开连接
    PeekNamedPipe:试探pipe输入缓冲区
    WaitNamedPipe:等待直到named pipe可以开始连接,client用
    Client使用CreateFile、WriteFile与ReadFile进行必要的操作。

    最近实习用wcf做项目,惊讶于wcf对网络的封装用起来非常舒服,因此也想在C++上实现一个过过瘾。当然,我并不打算支持SOAP,而且我也想加上远程对象访问的功能,也就是说A产生的对象,传到另一台机器B上,B发给C,C仍然能够调用对象的函数,只要接口正确。wcf可以在同一个端口上host很多属于不同应用程序的服务,Pipe应该可以解决这个消息分派的问题,因为一个端口只能host一个server socket,至少我是这么想的。

    因此封装了一下。上面列出的函数具体用法就自己看msdn了。
 1 #include "..\..\..\..\VL++\Library\Platform\VL_Console.h"
 2 #include "..\..\..\..\VL++\Library\Data\VL_System.h"
 3 #include "..\..\..\..\VL++\Library\Data\VL_Comm.h"
 4 
 5 using namespace vl;
 6 using namespace vl::platform;
 7 using namespace vl::system;
 8 using namespace vl::system::synchronization;
 9 using namespace vl::communication;
10 
11 void vlmain(VL_Console& Con)
12 {
13     Con.SetTitle(L"Vczh Pipe");
14     Con.SetTestMemoryLeaks(true);
15     Con.SetPauseOnExit(true);
16 
17     VBool ServerProcess=false;
18     VL_SynEvent Event;
19     switch(Event.Create(false,true,L"VCZH_EVENT"))
20     {
21     case VL_SynObject::arSucceed:
22         ServerProcess=true;
23         Con.Write(L"Server\r\n");
24         Con.Write(L"Press [ENTER] to start.\r\n");
25         Con.WaitForEnter();
26         break;
27     case VL_SynObject::arAlreadyExists:
28         Con.Write(L"Client\r\n");
29         Con.Write(L"Waiting for signal");
30         Event.WaitFor();
31         Con.Write(L"Signaled\r\n");
32         break;
33     case VL_SynObject::arFail:
34         Con.Write(L"Fail\r\n");
35         return;
36     }
37     if(ServerProcess)
38     {
39         VL_PipeServer Server(L"\\\\.\\pipe\\VczhPipe",true,true,1024,1024);
40         Event.Signal();
41         VL_AutoPtr<VL_ServerPipe> Pipe=Server.WaitForConnection();
42         if(Pipe)
43         {
44             Con.Write(L"消息链接来自:"+Pipe->GetClientComputerName()+L"\r\n");
45             VWChar Buffer[1024];
46             while(true)
47             {
48                 VInt Read=Pipe->ReadData((VBuffer)Buffer,1024);
49                 if(Read==-1)
50                 {
51                     Con.Write(L"Read Fail.\r\n");
52                     break;
53                 }
54                 else if(Read==0)
55                 {
56                     break;
57                 }
58                 else
59                 {
60                     Con.Write(L"*");
61                     Buffer[Read]=0;
62                     Con.Write(Buffer);
63                     Con.Write(L"\r\n");
64                 }
65             }
66         }
67         else
68         {
69             Con.Write(L"Fail.\r\n");
70         }
71         Event.Signal();
72     }
73     else
74     {
75         VL_AutoPtr<VL_ClientPipe> Pipe=new VL_ClientPipe(L"\\\\.\\pipe\\VczhPipe");
76         if(Pipe->Connect())
77         {
78             VWChar Message1[]=L"This is the first message.";
79             VWChar Message2[]=L"This is the second message.";
80             Pipe->WriteData((VBuffer)Message1,sizeof(Message1)-2);
81             Pipe->WriteData((VBuffer)Message2,sizeof(Message2)-2);
82         }
83         else
84         {
85             Con.Write(L"Fail.\r\n");
86         }
87         Event.WaitFor(1000);
88     }
89     Con.Write(L"Stop");
90 }

    这个程序启动两次不关闭,第一个启动的变成server,第二个启动的变成client。在server上按回车过程开始。client发两条消息给server,server接受并打印在屏幕上。过程完成之后过一秒钟两个程序结束。之所以要等待一秒钟是因为,如果直接结束的话会关闭管道,这个时候没有读出来的消息也就都不见了。
posted on 2008-07-31 09:07 陈梓瀚(vczh) 阅读(4319) 评论(1)  编辑 收藏 引用

评论:
# re: Windows中的Pipe 2008-07-31 16:38 | 酸菜
unix的管道不是光作命令行的,只能说unix shell提供了使用管道的途径。  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理