【转】 Windows中的Pipe
此管道非彼管道,不是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了。
这个程序启动两次不关闭,第一个启动的变成server,第二个启动的变成client。在server上按回车过程开始。client发两条消息给server,server接受并打印在屏幕上。过程完成之后过一秒钟两个程序结束。之所以要等待一秒钟是因为,如果直接结束的话会关闭管道,这个时候没有读出来的消息也就都不见了。
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 }
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
![](http://www.cppblog.com/Images/dot.gif)
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接受并打印在屏幕上。过程完成之后过一秒钟两个程序结束。之所以要等待一秒钟是因为,如果直接结束的话会关闭管道,这个时候没有读出来的消息也就都不见了。
![]() |
|
|
Everyday is lonely day. |
|