中兴捧月小结

今天得知中兴捧月的比赛,作品未能通过复赛,失落是有的,毕竟断断续续也努力了一个月左右。感谢一起奋斗的两位同学。现在想总结一下。

选择的题目是模拟IPTV的实现,其实就是模拟了一下平时看电视的流程,要做视频服务器,交换机,机顶盒,计费服务器四个部分,对问题的理解没有偏差,自认为较好的实现了功能需求。工作不算多,代码大概6k行。


后来看点评,说有的文档太复杂,贴了大段代码;程序代码复杂度高,一个函数实现了太多功能,不易阅读。我感觉我们在这两方面做的不好,文档确实过于复杂了,也没想想仔细安排一下,有几个函数写的不好,应该细分成函数进行调用的。不知道是不是这样,如果中兴的专家组能给出详细的评析就好了,估计他们没这功夫,但还是希望能够做到。



用到的主要技术有


Visual Studio 2010下MFC编程

这个没什么,环境选择,但之前没用2010,也很久不写MFC程序了,用的过程中虽然碰到一些问题,如2010下字符集的处理,总的感觉还不错,环境没特别麻烦的地方。只是10实在是耗资源,内存占个200M,为了智能提示竟然搞了个百兆大小数据库文件,让我很是开了眼界,以后还是少用这个吧。


多线程技术

多线程中用到了对共享资源的访问控制(用的mutex),一定要保证循环时也全部恰当地释放了控制,这个问题调了好半天才发现。


UDP单播、组播技术,TCP单播技术

网上很多了。。有个组播的简单库可以用:MCastlib


GDI绘图

一定要控制好各种DC的申请与释放,特别是申请失败时的处理,不然程序运行一段时间后就崩溃了,DC申请不到。。

举个例子

View Code
 1 CDC* pDC = pWnd->GetDC();
2
3 CDC MemDC; //首先定义一个显示设备对象
4 CBitmap MemBitmap;//定义一个位图对象
5
6 //随后建立与屏幕显示兼容的内存显示设备
7 if(MemDC.CreateCompatibleDC(NULL) == TRUE)
8 {
9 //这时还不能绘图,因为没有地方画
10 //下面建立一个与屏幕显示兼容的位图
11 if(MemBitmap.CreateCompatibleBitmap(pDC,m_iCH3Width,m_iCH3Height) == TRUE)
12 {
13 //将位图选入到内存显示设备中
14 //只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上
15 CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap);
16 if(pOldBit != NULL)
17 {
18 //先用背景色将位图清除干净,这里用的是白色作为背景
19 MemDC.FillSolidRect(0,0,m_iCH3Width,m_iCH3Height,RGB(255,255,255));
20
21 //绘图
22 //MemDC.SetPixel(m_iCH3Center_x, m_iCH3Center_y, RGB(0, 0, 0));// 画圆心
23 CPen * pBlackPen = new CPen(PS_SOLID, 10, RGB(0, 0, 0));
24 CPen * pOldPen = MemDC.SelectObject(pBlackPen);
25 MemDC.Rectangle(pt_current.x,pt_current.y,pt_current.x+5,pt_current.y-5);
26 //将内存中的图拷贝到屏幕上进行显示
27 pDC->BitBlt(0,0,m_iCH3Width,m_iCH3Height,&MemDC,0,0,SRCCOPY);
28
29 MemDC.SelectObject(pOldPen);
30 }
31 else
32 {
33 CString sMsg="";
34 sMsg.Format("pOldBit==null%d",GetLastError());
35 OutputDebugString(sMsg);
36 }
37 }
38 }
39 //绘图完成后的清理
40 pWnd->ReleaseDC(pDC);
41 MemBitmap.DeleteObject();
42 MemDC.DeleteDC();
43 ReleaseDC(&MemDC);


OpenCV库

下载地址:http://sourceforge.net/projects/opencvlibrary/files/opencvwin/2.2/OpenCV-2.2.0-win32-vs2010.exe/download

由于要处理图像数据,一同学建议使用OpenCV库,操作方便,也可以做图像处理。安装的时候要将path添加到系统path里面,或者安装完自己手动添加。

项目设置过程

包含目录:

C:\Program Files\OpenCV2.2\modules\core\include\opencv2\core;C:\Program Files\OpenCV2.2\include\opencv2\ml;C:\Program Files\OpenCV2.2\include\opencv2\core;C:\Program Files\OpenCV2.2\include\opencv;C:\Program Files\OpenCV2.2\include;C:\Program Files\OpenCV2.2\include\opencv2;$(IncludePath)

库目录:

C:\Program Files\OpenCV2.2\lib;$(LibraryPath)

把预编译也取消了吧,不然有时候编译会有问题。如果编译不出问题可以不用管,有问题可以试试这样做。

增量链接也取消掉,如果编译不出问题可以不用管,有问题可以试试这样做。

依赖项:opencv_core220d.lib;opencv_highgui220d.lib;opencv_video220d.lib;opencv_ml220d.lib;open

cv_legacy220d.lib;opencv_imgproc220d.lib;%(AdditionalDependencies)

另外,早版本的OpenCV有CvvImage类,很好用,后来却没有了。将它提取过来加入项目里面。文件是:CvvImage

至于使用,比较重要的一个结构是IplImage,包含了十分重要的信息。根据需要自己摸索吧,这里提供一个显示到picturecontrol的方法

 1 IplImage *img=(IplImage*)wParam;
2 CDC *pDC = GetDlgItem(IDC_PIC_BOX)->GetDC();
3 HDC hDC= pDC->GetSafeHdc();
4 CRect rect;
5 GetDlgItem(IDC_PIC_BOX)->GetClientRect(&rect);
6 CvvImage cimg;
7
8 cimg.CopyOf(img,1);
9 cimg.DrawToHDC(hDC,&rect);
10 ReleaseDC(pDC);
11
12 delete img->imageData;
13 img = NULL;

libxml2库

为了管理授权信息和记录账单信息,觉得采用xml格式存储和操作,用了libxml2库。主页:http://xmlsoft.org/

下载解压。假设Visual Studio 2010 安装位置为:C:\Program Files\Microsoft Visual Studio 10.0,记为$VSDIR。
将文件iconv-1.9.2.win32.zip,libxml2-2.7.8.win32.zip,zlib-1.2.5.win32.zip 分别解压,将各自bin 下的文件复制到$VSDIR\VC\bin 目录中,将lib 下的文件复制到$VSDIR\VC\lib 目录下,将include 下的文件复制到$VSDIR\VC\include 目录下。上面的依赖项中添加:iconv.lib;iconv_a.lib;libxml2.lib;libxml2_a.lib;libxml2_a_dll.lib;zdll.lib;zlib.lib

使用多多摸索,提供一点代码,有点乱,而且有些不是MFC的部分

View Code
  1 // 获取节点集合
2 xmlXPathObjectPtr getNodeSet(xmlDocPtr doc, xmlChar *szXpath)
3 {
4
5 xmlXPathObjectPtr result; //XPath object ptr
6 xmlXPathContextPtr context; //XPath content ptr
7
8 // create the XPath content ptr
9 context = xmlXPathNewContext(doc);
10
11 if (!context)
12 {
13 return NULL;
14 }
15
16 // query the XPath and get the query result
17 result = xmlXPathEvalExpression(szXpath, context);
18
19 // free the content ptr
20 xmlXPathFreeContext(context);
21
22 if (!result)
23 {
24 return NULL;
25 }
26
27
28 // check the result is empty or not
29 if (xmlXPathNodeSetIsEmpty(result->nodesetval))
30 {
31 xmlXPathFreeObject(result);
32 return NULL;
33 }
34
35 return result;
36 }
37
38 int AddNode(CString STBname, CString CHname)
39 {
40 xmlDocPtr doc; // define doc ptr
41
42 xmlNodePtr curNode; // define node ptr
43
44 xmlNodePtr STBnode; // define STB node ptr
45
46 xmlNodePtr CHnode; // define CH node ptr
47
48
49 xmlDocPtr docBilling; // define doc ptr
50
51 xmlNodePtr curNodeBilling; // define node ptr
52
53 xmlNodePtr STBnodeBilling; // define STB node ptr
54
55 xmlNodePtr CHnodeBilling; // define CH node ptr
56
57 string authenticationFileName = "authentication.xml"; // define the name of authentication file
58 string billingFileName = "billing.xml"; // define the name of billing file
59
60 bool flag = false;
61
62
63 // read the authentication file
64 doc = xmlReadFile(authenticationFileName.c_str(),"GB2312",XML_PARSE_RECOVER);
65 if (!doc)
66 {
67 cerr << "Error: Document not parsed successfully."<<endl;
68 return -1;
69 }
70
71 // get the root element
72 curNode = xmlDocGetRootElement(doc);
73 if (!curNode)
74 {
75 cerr << "Error: empty document."<<endl;
76 xmlFreeDoc(doc);
77 return -1;
78 }
79
80 // check the root element
81 if (xmlStrcmp(curNode->name, BAD_CAST "root"))
82 {
83 cerr <<"Error: document of the wrong type, root node != root."<<endl;
84 xmlFreeDoc(doc);
85 return -1;
86 }
87
88
89
90 // read the billing file
91 docBilling = xmlReadFile(billingFileName.c_str(),"GB2312",XML_PARSE_RECOVER);
92 if (!docBilling)
93 {
94 cerr << "Error: Document not parsed successfully."<<endl;
95 xmlFreeDoc(doc);
96 return -1;
97 }
98
99 // get the root element
100 curNodeBilling = xmlDocGetRootElement(docBilling);
101 if (!curNodeBilling)
102 {
103 cerr << "Error: empty document."<<endl;
104 xmlFreeDoc(doc);
105 xmlFreeDoc(docBilling);
106 return -1;
107 }
108
109
110 // check the authentication.xml contains STBname or not
111 // get the child nodes of curNode
112 curNode = curNode->xmlChildrenNode;
113 xmlNodePtr chPtr = NULL;
114
115 curNodeBilling = curNodeBilling->xmlChildrenNode;
116 xmlNodePtr chPtrBilling = NULL;
117
118
119 while(curNode != NULL)
120 {
121 // find the STBname node, get its child nodes
122 if ( (!xmlStrcmp(curNode->name, (const xmlChar *)STBname.GetBuffer(STBname.GetLength()))) )
123 {
124 // get the child nodes of STBname node
125 flag = true;
126 chPtr = curNode->children;
127
128 chPtrBilling = curNodeBilling->children;
129
130 break;
131 }
132 curNode = curNode->next;
133 curNodeBilling = curNodeBilling->next;
134 }
135
136
137 // check the STBname contains CHname or not
138 if (flag)
139 {
140 while (chPtr != NULL)
141 {
142 // compare the parameter CHname and each child node name
143 if ( (!xmlStrcmp(chPtr->name, (const xmlChar *)CHname.GetBuffer(CHname.GetLength()))))
144 {
145 // the node has exsited
146 xmlFreeDoc(doc);
147 xmlFreeDoc(docBilling);
148 return 1;
149 }
150 chPtr = chPtr->next;
151 chPtrBilling = chPtrBilling->next;
152 }
153
154 // create and add the CHname node into authentication.xml
155 CHnode = xmlNewNode(NULL, BAD_CAST CHname.GetBuffer(CHname.GetLength()));
156 xmlAddChild(curNode,CHnode);
157
158 // create and add the CHname node into billing.xml
159 CHnodeBilling = xmlNewNode(NULL, BAD_CAST CHname.GetBuffer(CHname.GetLength()));
160 string chAttr = "totalTime";
161 string chvalue = "0";
162 xmlNewProp(CHnodeBilling, (xmlChar *)chAttr.c_str(), (xmlChar *)chvalue.c_str());
163 xmlAddChild(curNodeBilling,CHnodeBilling);
164
165 }else{
166 // create and add the STBname, CHname node into authentication.xml
167 STBnode = xmlNewNode(NULL, BAD_CAST STBname.GetBuffer(STBname.GetLength()));
168 xmlAddChild(xmlDocGetRootElement(doc),STBnode);
169
170 CHnode = xmlNewNode(NULL, BAD_CAST CHname.GetBuffer(CHname.GetLength()));
171 xmlAddChild(STBnode,CHnode);
172
173
174 // create and add the STBname, CHname node into billing.xml
175 STBnodeBilling = xmlNewNode(NULL, BAD_CAST STBname.GetBuffer(STBname.GetLength()));
176 xmlAddChild(xmlDocGetRootElement(docBilling),STBnodeBilling);
177
178 CHnodeBilling = xmlNewNode(NULL, BAD_CAST CHname.GetBuffer(CHname.GetLength()));
179 string chAttr = "totalTime";
180 string chvalue = "0";
181 xmlNewProp(CHnodeBilling, (xmlChar *)chAttr.c_str(), (xmlChar *)chvalue.c_str());
182 xmlAddChild(STBnodeBilling,CHnodeBilling);
183 }
184
185
186 // save the xml file to disk
187 xmlSaveFormatFile (authenticationFileName.c_str(), doc, 1);
188 xmlSaveFormatFile (billingFileName.c_str(), docBilling, 1);
189
190
191 xmlFreeDoc(doc);
192 xmlFreeDoc(docBilling);
193 return 0;
194 }
195
196 int DeleteNode(CString STBname, CString CHname)
197 {
198 xmlDocPtr doc; // define doc ptr
199
200 xmlNodePtr curNode; // define node ptr
201
202 xmlDocPtr docBilling; // define doc ptr
203
204 xmlNodePtr curNodeBilling; // define node ptr
205
206
207 string authenticationFileName = "authentication.xml"; // define the name of authentication file
208 string billingFileName = "billing.xml"; // define the name of billing file
209
210 bool flag = false;
211
212
213 // read the authentication file
214 doc = xmlReadFile(authenticationFileName.c_str(),"GB2312",XML_PARSE_RECOVER);
215 if (!doc)
216 {
217 cerr << "Error: Document not parsed successfully."<<endl;
218 return -1;
219 }
220
221 // get the root element
222 curNode = xmlDocGetRootElement(doc);
223 if (!curNode)
224 {
225 cerr << "Error: empty document."<<endl;
226 xmlFreeDoc(doc);
227 return -1;
228 }
229
230 // check the root element
231 if (xmlStrcmp(curNode->name, BAD_CAST "root"))
232 {
233 cerr <<"Error: document of the wrong type, root node != root."<<endl;
234 xmlFreeDoc(doc);
235 return -1;
236 }
237
238
239
240 // read the billing file
241 docBilling = xmlReadFile(billingFileName.c_str(),"GB2312",XML_PARSE_RECOVER);
242 if (!docBilling)
243 {
244 cerr << "Error: Document not parsed successfully."<<endl;
245 return -1;
246 }
247
248 // get the root element
249 curNodeBilling = xmlDocGetRootElement(docBilling);
250 if (!curNodeBilling)
251 {
252 cerr << "Error: empty document."<<endl;
253 xmlFreeDoc(doc);
254 xmlFreeDoc(docBilling);
255 return -1;
256 }
257
258
259 // check the authentication.xml contains the node /root/STBname/CHname or not
260 // then delete the node if contain
261 string queryXPath = "/root/" + STBname + "/" + CHname;
262 xmlXPathObjectPtr objectPtr = getNodeSet(doc, (xmlChar *)queryXPath.c_str());
263 if (!objectPtr)
264 {
265 cerr <<"Error: objectPtr is null, the node does not exsit."<<endl;
266 xmlFreeDoc(doc);
267 xmlFreeDoc(docBilling);
268 return 1;
269 }
270
271
272 xmlNodeSetPtr nodeset = objectPtr->nodesetval;
273 xmlNodePtr ptr = nodeset->nodeTab[0];
274
275 xmlNodePtr tempNode = NULL;
276
277 // delete the node in authentication.xml
278 if (!ptr)
279 {
280 // the authentication.xml has not contained the node.
281 cerr <<"Error: the node does not exsit."<<endl;
282 xmlFreeDoc(doc);
283 xmlFreeDoc(docBilling);
284 return 1;
285 }else{
286
287 // delete the node
288 tempNode = ptr->next;
289 xmlUnlinkNode(ptr);
290 xmlFreeNode(ptr);
291 ptr = tempNode;
292 }
293
294
295
296 // delete the node in billing.xml
297 objectPtr = getNodeSet(docBilling, (xmlChar *)queryXPath.c_str());
298 nodeset = objectPtr->nodesetval;
299 ptr = nodeset->nodeTab[0];
300
301 if ( !(ptr->children) )
302 {
303 // the node /root/STBname/CHname has not child nodes
304 tempNode = ptr->next;
305 xmlUnlinkNode(ptr);
306 xmlFreeNode(ptr);
307 ptr = tempNode;
308 }else{
309
310 // the node /root/STBname/CHname has child nodes
311
312 // delete its child nodes
313 xmlNodePtr childPtr = ptr->xmlChildrenNode;
314
315 while(childPtr != NULL)
316 {
317 tempNode = childPtr->next;
318 xmlUnlinkNode(childPtr);
319 xmlFreeNode(childPtr);
320 childPtr = tempNode;
321 }
322
323 // delete the node /root/STBname/CHname itself
324 tempNode = ptr->next;
325 xmlUnlinkNode(ptr);
326 xmlFreeNode(ptr);
327 ptr = tempNode;
328 }
329
330
331 // save the xml file to disk
332 xmlSaveFormatFile (authenticationFileName.c_str(), doc, 1);
333 xmlSaveFormatFile (billingFileName.c_str(), docBilling, 1);
334
335
336 xmlFreeDoc(doc);
337 xmlFreeDoc(docBilling);
338
339 return 0;
340 }

posted on 2011-08-08 22:48  小交响曲  阅读(910)  评论(0编辑  收藏  举报

导航