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
![](https://i-blog.csdnimg.cn/blog_migrate/918e8df969f9f8c8d002f25cda86cade.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接受并打印在屏幕上。过程完成之后过一秒钟两个程序结束。之所以要等待一秒钟是因为,如果直接结束的话会关闭管道,这个时候没有读出来的消息也就都不见了。