今天将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 }
posted on 2008-11-22 02:26
陈梓瀚(vczh) 阅读(2130)
评论(6) 编辑 收藏 引用 所属分类:
C++