程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> Vczh Serialization Demo :在網絡上傳遞復雜對象

Vczh Serialization Demo :在網絡上傳遞復雜對象

編輯:關於C++

今天將Serialization進行了重構,讓其支持容器。於是使用以前的基礎設施就能完成這 個Demo了。

為什麼要做成這個樣子呢?因為模板沒有運行時匹配功能。雖然仍然大量 使用模板,但是接口上就沒有了。模板被用來處理其他的事情。

這個程序分為服務器 端和客戶端兩個部分,使用Socket連接。服務器端監聽到一個客戶端之後將一棵樹發送過去 之後退出。客戶端接收到這棵樹之後將內容打印到屏幕上。於是我們實現一顆多態的樹。樹 的節點分為數字節點、字符串節點和列表節點三種,共同繼承自一個基類。這樣的話就可以 使用多態來構造成一棵樹並進行操作了:

1 class Node : public VL_SerializableObject
2 {
3 public:
4 typedef VL_AutoPtr<Node> Ptr;
5
6 virtual VUnicodeString ToString(VUnicodeString Prefix)=0;
7 };
8
9 class NumberNode : public Node
10 {
11 public:
12 VInt Number;
13
14 NumberNode()
15 {
16 VL_SERIALIZABLE_FIELD(NumberNode,Number);
17 }
18
19 VUnicodeString ToString(VUnicodeString Prefix)
20 {
21 return Prefix+VUnicodeString(Number);
22 }
23 };
24
25 class IdNode : public Node
26 {
27 public:
28 VUnicodeString Id;
29
30 IdNode()
31 {
32 VL_SERIALIZABLE_FIELD(IdNode,Id);
33 }
34
35 VUnicodeString ToString(VUnicodeString Prefix)
36 {
37 return Prefix+Id;
38 }
39 };
40
41 class ListNode : public Node
42 {
43 public:
44 VL_List<Ptr , false , Node*> Children;
45
46 ListNode()
47 {
48 VL_SERIALIZABLE_FIELD(ListNode,Children);
49 }
50
51 VUnicodeString ToString(VUnicodeString Prefix)
52 {
53 VUnicodeString Result;
54 Result+=Prefix+L"List {\r\n";
55 for(VInt i=0;i<Children.GetCount();i++)
56 {
57 if(Children[i])
58 {
59 Result+=Children[i]->ToString(Prefix+L" ")+L"\r\n";
60 }
61 else
62 {
63 Result+=Prefix+L" <NULL>\r\n";
64 }
65 }
66 Result+=Prefix+L"}";
67 return Result;
68 }
69 };

接下來初始化Serializer:

1 void InitializeSeriailzer(VL_Serializer& Serializer)
2 {
3   VL_SERIALIZABLE_CLASS(&Serializer,NumberNode);
4   VL_SERIALIZABLE_CLASS(&Serializer,IdNode);
5   VL_SERIALIZABLE_CLASS (&Serializer,ListNode);
6 }

然後實現一個服務器端的邏輯:

1 Node::Ptr BuildNode()
2 {
3 ListNode* Root=new ListNode;
4 {
5 NumberNode* Number=new NumberNode;
6 Number->Number=10;
7 Root->Children.Add(Number);
8 }
9 {
10 ListNode* List=new ListNode;
11 {
12 NumberNode* Number=new NumberNode;
13 Number->Number=20;
14 List->Children.Add(Number);
15 }
16 List->Children.Add(0);
17 {
18 IdNode* Id=new IdNode;
19 Id->Id=L"Serialization";
20 List->Children.Add(Id);
21 }
22 Root->Children.Add(List);
23 }
24 {
25 IdNode* Id=new IdNode;
26 Id->Id=L"VCZH";
27 Root->Children.Add(Id);
28 }
29 return Root;
30 }
31
32 void ServerMain()
33 {
34 GetConsole()->SetTitle(L"Vczh Library++ 2.0 Communication [Server]");
35
36 VL_Serializer Serializer;
37 InitializeSeriailzer(Serializer);
38
39 VL_SocketServer Server(vspTCP,L"8000",false);
40 if(Server.IsSuccess())
41 {
42 VL_ServerSocket* Socket=Server.WaitForConnection();
43 if(Socket)
44 {
45 GetConsole()->Write(L"監聽到客戶端。\r\n");
46 Node::Ptr MyNode=BuildNode();
47 WriteCommonObject(Socket->GetWriterStream(),Serializer.Serialize(MyNode.Object()));
48 delete Socket;
49 GetConsole()->Write(L"發送成功,關閉服務端。\r\n");
50 }
51 else
52 {
53 GetConsole()->Write(L"監聽端口時發生錯誤。\r\n");
54 }
55 }
56 else
57 {
58 GetConsole()->Write(L"創建Socket時發生錯誤。\r\n");
59 }
60 }

下面是客戶端的邏輯:

1 void ClientMain()
2 {
3 GetConsole()->SetTitle(L"Vczh Library++ 2.0 Communication [Client]");
4
5 VL_Serializer Serializer;
6 InitializeSeriailzer(Serializer);
7
8 VL_ClientSocket Socket(vspTCP,L"127.0.0.1",L"8000");
9 if(Socket.Connect())
10 {
11 GetConsole()->Write(L"連接到服務端。\r\n");
12 Node::Ptr MyNode=Serializer.Deserialize(ReadCommonObject(Socket.GetReaderStream()));
13 GetConsole()->Write(MyNode->ToString(L""));
14 }
15 else
16 {
17 GetConsole()->Write(L"連接服務端時發生錯誤。\r\n");
18 }
19 }

最後用Main函數來構造一個Event。程 序將被啟動兩次,先啟動的成為服務器,後啟動的成為客戶端,方便將兩部分的代碼都放在 同一個文件裡面:

1 void vlmain()
2 {
3   GetConsole()- >SetTitle(L"Vczh Library++ 2.0 Communication");
4   GetConsole()->SetTestMemoryLeaks(true);
5   GetConsole()- >SetPauseOnExit(true);
6
7   VL_SynEvent Event;
8   switch (Event.Create(false,false,L"VCZH"))
9   {
10   case VL_SynObject::arSucceed:
11     ServerMain();
12     break;
13   case VL_SynObject::arAlreadyExists:
14     ClientMain();
15     break;
16   case VL_SynObject::arFail:
17     GetConsole()->Write(L"構造Event時發生錯誤。\r\n");
18     break;
19   }
20 }

讓我們看看運行結果:

下面是完 整的代碼:

1 #include "..\..\..\Library\Platform\VL_Console.h"
2 #include "..\..\..\Library\Data\VL_CommonData.h"
3 #include "..\..\..\Library\Data\VL_Serialization.h"
4 #include "..\..\..\Library\Data\VL_Communication.h"
5 #include "..\..\..\Library\Data\VL_Stream.h"
6 #include "..\..\..\Library\Data\VL_System.h"
7
8 using namespace vl;
9 using namespace vl::platform;
10 using namespace vl::stream;
11 using namespace vl::system;
12 using namespace vl::system::synchronization;
13 using namespace vl::serialization;
14 using namespace vl::commondata;
15 using namespace vl::communication;
16
17 class Node : public VL_SerializableObject
18 {
19 public:
20 typedef VL_AutoPtr<Node> Ptr;
21
22 virtual VUnicodeString ToString(VUnicodeString Prefix)=0;
23 };
24
25 class NumberNode : public Node
26 {
27 public:
28 VInt Number;
29
30 NumberNode()
31 {
32 VL_SERIALIZABLE_FIELD(NumberNode,Number);
33 }
34
35 VUnicodeString ToString(VUnicodeString Prefix)
36 {
37 return Prefix+VUnicodeString(Number);
38 }
39 };
40
41 class IdNode : public Node
42 {
43 public:
44 VUnicodeString Id;
45
46 IdNode()
47 {
48 VL_SERIALIZABLE_FIELD(IdNode,Id);
49 }
50
51 VUnicodeString ToString(VUnicodeString Prefix)
52 {
53 return Prefix+Id;
54 }
55 };
56
57 class ListNode : public Node
58 {
59 public:
60 VL_List<Ptr , false , Node*> Children;
61
62 ListNode()
63 {
64 VL_SERIALIZABLE_FIELD(ListNode,Children);
65 }
66
67 VUnicodeString ToString(VUnicodeString Prefix)
68 {
69 VUnicodeString Result;
70 Result+=Prefix+L"List {\r\n";
71 for(VInt i=0;i<Children.GetCount();i++)
72 {
73 if(Children[i])
74 {
75 Result+=Children[i]->ToString(Prefix+L" ")+L"\r\n";
76 }
77 else
78 {
79 Result+=Prefix+L" <NULL>\r\n";
80 }
81 }
82 Result+=Prefix+L"}";
83 return Result;
84 }
85 };
86
87 void InitializeSeriailzer(VL_Serializer& Serializer)
88 {
89 VL_SERIALIZABLE_CLASS(&Serializer,NumberNode);
90 VL_SERIALIZABLE_CLASS(&Serializer,IdNode);
91 VL_SERIALIZABLE_CLASS(&Serializer,ListNode);
92 }
93
94 Node::Ptr BuildNode()
95 {
96 ListNode* Root=new ListNode;
97 {
98 NumberNode* Number=new NumberNode;
99 Number->Number=10;
100 Root->Children.Add(Number);
101 }
102 {
103 ListNode* List=new ListNode;
104 {
105 NumberNode* Number=new NumberNode;
106 Number->Number=20;
107 List->Children.Add(Number);
108 }
109 List->Children.Add(0);
110 {
111 IdNode* Id=new IdNode;
112 Id->Id=L"Serialization";
113 List->Children.Add(Id);
114 }
115 Root->Children.Add(List);
116 }
117 {
118 IdNode* Id=new IdNode;
119 Id->Id=L"VCZH";
120 Root->Children.Add(Id);
121 }
122 return Root;
123 }
124
125 void ServerMain()
126 {
127 GetConsole()->SetTitle(L"Vczh Library++ 2.0 Communication [Server]");
128
129 VL_Serializer Serializer;
130 InitializeSeriailzer(Serializer);
131
132 VL_SocketServer Server(vspTCP,L"8000",false);
133 if(Server.IsSuccess())
134 {
135 VL_ServerSocket* Socket=Server.WaitForConnection();
136 if(Socket)
137 {
138 GetConsole()->Write(L"監聽到客戶端。\r\n");
139 Node::Ptr MyNode=BuildNode();
140 WriteCommonObject(Socket->GetWriterStream(),Serializer.Serialize(MyNode.Object()));
141 delete Socket;
142 GetConsole()->Write(L"發送成功,關閉服務端。\r\n");
143 }
144 else
145 {
146 GetConsole()->Write(L"監聽端口時發生錯誤。\r\n");
147 }
148 }
149 else
150 {
151 GetConsole()->Write(L"創建Socket時發生錯誤。\r\n");
152 }
153 }
154
155 void ClientMain()
156 {
157 GetConsole()->SetTitle(L"Vczh Library++ 2.0 Communication [Client]");
158
159 VL_Serializer Serializer;
160 InitializeSeriailzer(Serializer);
161
162 VL_ClientSocket Socket(vspTCP,L"127.0.0.1",L"8000");
163 if(Socket.Connect())
164 {
165 GetConsole()->Write(L"連接到服務端。\r\n");
166 Node::Ptr MyNode=Serializer.Deserialize(ReadCommonObject(Socket.GetReaderStream()));
167 GetConsole()->Write(MyNode->ToString(L""));
168 }
169 else
170 {
171 GetConsole()->Write(L"連接服務端時發生錯誤。\r\n");
172 }
173 }
174
175 void vlmain()
176 {
177 GetConsole()->SetTitle(L"Vczh Library++ 2.0 Communication");
178 GetConsole()->SetTestMemoryLeaks(true);
179 GetConsole()->SetPauseOnExit(true);
180
181 VL_SynEvent Event;
182 switch(Event.Create(false,false,L"VCZH"))
183 {
184 case VL_SynObject::arSucceed:
185 ServerMain();
186 break;
187 case VL_SynObject::arAlreadyExists:
188 ClientMain();
189 break;
190 case VL_SynObject::arFail:
191 GetConsole()->Write(L"構造Event時發生錯誤。\r\n");
192 break;
193 }
194 }
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved