• 中兴捧月小结


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

    选择的题目是模拟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 }
  • 相关阅读:
    Sitecore Digital Marketing System, Part 1: Creating personalized, custom content for site visitors(自定义SiteCore中的 Item的Personalize的Condition) -摘自网络
    Send email alert from Performance Monitor using PowerShell script (检测windows服务器的cpu 硬盘 服务等性能,发email的方法) -摘自网络
    使用Mono Cecil 动态获取运行时数据 (Atribute形式 进行注入 用于写Log) [此文报考 xxx is declared in another module and needs to be imported的解决方法]-摘自网络
    秒杀 ILSpy 等反编译利器 DotNet Resolver
    Nagios:企业级系统监控方案
    C# Asp.net中的AOP框架 Microsoft.CCI, Mono.Cecil, Typemock Open-AOP API, PostSharp -摘自网络 (可以利用反射 Attribute 进行面向切面编程 可以用在记录整个方法的Log方面)
    Windows性能监视器之CPU、硬盘、IO等监控方法详解-摘自网络
    网站防刷方案 -摘自网络
    利用XSD配合XSLT產出特定格式Word檔案 -摘自网络
    asp页面快速找到菜单按钮转向的页面的方法
  • 原文地址:https://www.cnblogs.com/njucslzh/p/2131308.html
Copyright © 2020-2023  润新知