此管道非彼管道,不是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接受並列印在螢幕上。過程完成之後過一秒鐘兩個程式結束。之所以要等待一秒鐘是因為,如果直接結束的話會關閉管道,這個時候沒有讀出來的訊息也就都不見了。