﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-&lt;table border="0" cellspacing="0" cellpadding="0" style="margin-  left:0px;display:inline;height:30px;"&gt;&lt;tr&gt;&lt;td style="font-weight:bold; font-size:16px; line-  height:30px;"&gt;一年十二月&amp;nbsp谁主春秋&lt;/td&gt;&lt;td style="font-size:14px; line-height:30px;"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;-随笔分类-Opensrc</title><link>http://www.cppblog.com/qinqing1984/category/10071.html</link><description>关注：操作系统、网络、数据库和安全</description><language>zh-cn</language><lastBuildDate>Fri, 22 Nov 2019 11:47:00 GMT</lastBuildDate><pubDate>Fri, 22 Nov 2019 11:47:00 GMT</pubDate><ttl>60</ttl><item><title>一种扩展nginx支持windows服务的方法</title><link>http://www.cppblog.com/qinqing1984/archive/2019/11/20/216988.html</link><dc:creator>春秋十二月</dc:creator><author>春秋十二月</author><pubDate>Wed, 20 Nov 2019 11:45:00 GMT</pubDate><guid>http://www.cppblog.com/qinqing1984/archive/2019/11/20/216988.html</guid><wfw:comment>http://www.cppblog.com/qinqing1984/comments/216988.html</wfw:comment><comments>http://www.cppblog.com/qinqing1984/archive/2019/11/20/216988.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/qinqing1984/comments/commentRss/216988.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qinqing1984/services/trackbacks/216988.html</trackback:ping><description><![CDATA[<span style="font-size: 14pt;"><strong>描述</strong></span><br />
&nbsp;&nbsp;&nbsp;nginx是一款著名的高性能开源Web与反向代理服务器，支持windows和linux操作系统，因为在windows系统上还不支持SCM（服务控制管理），所以只能以控制台方式运行，但这样并不是在后台运行，也不能在系统登录前启动。针对这些问题，本方法通过改进源码，使nginx良好地支持了SCM，方便了部署运行<br />
<div><br />
<strong style="font-size: 14pt;">特点</strong><br />
&nbsp; &nbsp;最大地复用了nginx源码；支持SCM，并兼容控制台运行方式；统一处理异常退出而报告服务停止<br />
</div>
<strong style="font-size: 14pt;"><br />
实现</strong><br /><div>&nbsp; &nbsp;<strong style="font-size: 12pt;">变换原主函数</strong></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;将原来的main函数更名为ngx_main，并增加第3个参数is_scm来标识运行方式，非0表示服务方式，0表示控制台方式，流程如下<br />
&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/images/cppblog_com/qinqing1984/ngx_mod_old_main.png" width="303" height="679" alt="" /><br /><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;图上红色部分为插入的逻辑，其它部分为nginx原来的逻辑。由于服务初始化须将错误记录在log（日志）中，所以应在初始化log模块后调用</div><br /><div><strong style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;增加主函数</strong></div><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这个主函数也就是程序入口main，可被控制台或SCM调用，当被SCM调用时，注册服务以及启动服务控制调度程序，流程如下<br />&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/images/cppblog_com/qinqing1984/ngx_add_main.png" width="251" height="558" alt="" /><br />&nbsp; &nbsp; &nbsp; 如果以命令行启动nginx 也就是master进程（管理进程），或nginx产生worker进程（工作进程）时，那么以控制台方式调用main，进而以is_scm为0调用ngx_main，当ngx_main返回时，就表示master或worker进程退出了&nbsp; &nbsp;<br /><div><div><br /><strong style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;服务主函数</strong></div><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;由SCM生成的一个逻辑线程调用，流程如下<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/images/cppblog_com/qinqing1984/ngx_service_main.png" width="171" height="254" alt="" /><br />&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;这里的逻辑线程代替了nginx的master进程，到这里就表明已经以SCM方式运行了，所以以is_scm为1调用ngx_main，当ngx_main返回时，就表明master进程退出了，应该更新服务状态为已停止，然后返回表明当前服务结束了<br /><br /><span style="font-size: 12pt;"><strong>&nbsp;&nbsp;&nbsp;服务初始化</strong></span></div><div>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;由ngx_main调用，见变换原主函数流程图，流程如下<br />&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/images/cppblog_com/qinqing1984/ngx_service_init.png" width="180" height="245" alt="" />&nbsp;<br />&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;由于在nginx实现中，有多处出现异常错误而直接退出，因此首先注册了进程退出处理器，在其内报告服务状态为已停止，这样只要当进程退出了，在SCM上就能看到已停止的状态了<br /><br />&nbsp; &nbsp;<strong style="font-size: 12pt;">服务控制处理器</strong><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;由SCM的主线程调用，流程如下</div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<img src="http://www.cppblog.com/images/cppblog_com/qinqing1984/ngx_service_ctrl_handler.png" width="226" height="353" alt="" /><br />&nbsp; &nbsp;<br />&nbsp; &nbsp;<strong style="font-size: 12pt;">调用关系</strong><br />&nbsp; &nbsp; &nbsp; 下图左边为master进程调用模块与函数，右边为worker进程调用模块与函数，委托主函数是<span style="color: red;">ngx_main</span><br />&nbsp; &nbsp; &nbsp; &nbsp;<img src="http://www.cppblog.com/images/cppblog_com/qinqing1984/ngx_scm_call.png" width="717" height="459" alt="" />&nbsp; &nbsp; &nbsp;</div></div></div></div><img src ="http://www.cppblog.com/qinqing1984/aggbug/216988.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qinqing1984/" target="_blank">春秋十二月</a> 2019-11-20 19:45 <a href="http://www.cppblog.com/qinqing1984/archive/2019/11/20/216988.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一种统计云查询黑文件的方法及系统</title><link>http://www.cppblog.com/qinqing1984/archive/2016/08/25/214212.html</link><dc:creator>春秋十二月</dc:creator><author>春秋十二月</author><pubDate>Thu, 25 Aug 2016 03:10:00 GMT</pubDate><guid>http://www.cppblog.com/qinqing1984/archive/2016/08/25/214212.html</guid><wfw:comment>http://www.cppblog.com/qinqing1984/comments/214212.html</wfw:comment><comments>http://www.cppblog.com/qinqing1984/archive/2016/08/25/214212.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/qinqing1984/comments/commentRss/214212.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qinqing1984/services/trackbacks/214212.html</trackback:ping><description><![CDATA[<strong style="font-size: 14pt;">描述</strong><br />
&nbsp;&nbsp;&nbsp;云查杀平台以nginx作为反向代理服务器，作为安全终端与云查询服务的桥梁。当安全终端需要查询黑文件时，HTTP请求及其响应都会经过nginx，为了获取并统计一天24小时查询的黑文件数量，就得先截获经过nginx的HTTP响应，再做数据分析。截获HTTP数据流有多种方法，为了简单高效，这里使用了挂接HTTP过滤模块的方法，另外为了不影响nginx本身的IO处理，将HTTP响应实体发送到另一个进程即统计服务，由统计服务来接收并分析HTTP响应，架构如下图
<div align="center"><img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/qinqing1984/kstat_schema.png" width="599" height="289" /></div>
&nbsp;&nbsp;&nbsp;统计服务由1个接收线程和1个存储线程构成，其中接收线程负责接收从nginx过滤模块发来的HTTP响应实体，解析它并提取黑文件MD5，加入共享环形队列；而存储线程从共享环形队列移出黑文件MD5，插入到临时内存映射文件，于每天定时同步到磁盘文件。<br />
<br />
<strong style="font-size: 14pt">特点</strong><br />
&nbsp;&nbsp;&nbsp;这种架构减少了nginx IO延迟，保证了nginx的稳定高效运行，从而不影响用户的业务运行；本地连接为非阻塞的，支持了统计服务的独立运行与升级。<br />
<br />
<strong style="font-size: 14pt">实现</strong><br />
&nbsp;&nbsp;&nbsp;<strong style="font-size: 12pt">nginx过滤模块</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;该流程运行在nginx工作进程。<br />
<div align="center"><img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/qinqing1984/kstat_ngxmod.png" width="279" height="802" /></div>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;由于nginx采用了异步IO机制，因此仅当截获到HTTP响应实体也就是有数据经过时，才有后面的操作；若没有数据，则什么也不用做。这里每次发送前先判断是否连接了统计服务，是为了支持统计服务的独立运行与升级，换句话说，不管统计服务是否运行或崩溃，都不影响nginx的运行。<br />
<br />
<strong style="font-size: 12pt">统计服务</strong><br />
&nbsp;&nbsp;&nbsp;<strong>接收线程</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这里的接收线程也就是主线程。<br />
<div align="center"><img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/qinqing1984/kstat_receiver.png" width="575" height="592" /></div>
&nbsp;&nbsp;
<hr width="97%" />
&nbsp;&nbsp;&nbsp;<strong>存储线程</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;存储线程为另一个工作线程。<br />
<div align="center"><img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/qinqing1984/kstat_storer.png" width="492" height="644" /></div>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;同步文件定时器的时间间隔要比新建文件定时器的短，由于定时器到期的事件处理是一种异步执行流，所以将它们当做并行，与&#8220;从q头移出黑文件MD5&#8221;操作画在了同一水平方向。<img src ="http://www.cppblog.com/qinqing1984/aggbug/214212.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qinqing1984/" target="_blank">春秋十二月</a> 2016-08-25 11:10 <a href="http://www.cppblog.com/qinqing1984/archive/2016/08/25/214212.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>nginx iocp（3）：scm服务控制</title><link>http://www.cppblog.com/qinqing1984/archive/2016/07/12/211381.html</link><dc:creator>春秋十二月</dc:creator><author>春秋十二月</author><pubDate>Tue, 12 Jul 2016 07:31:00 GMT</pubDate><guid>http://www.cppblog.com/qinqing1984/archive/2016/07/12/211381.html</guid><wfw:comment>http://www.cppblog.com/qinqing1984/comments/211381.html</wfw:comment><comments>http://www.cppblog.com/qinqing1984/archive/2016/07/12/211381.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/qinqing1984/comments/commentRss/211381.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qinqing1984/services/trackbacks/211381.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp;为了使nginx支持windows服务，本文阐述以下主要的改进实现。ngx_main函数&nbsp;&nbsp;&nbsp;为了在SCM服务中复用main函数的逻辑，将其重命名为ngx_main，并添加第3个参数is_scm以兼容控制台运行方式，声明在core/nginx.h中。&nbsp;&nbsp;&nbsp; Code highligh...&nbsp;&nbsp;<a href='http://www.cppblog.com/qinqing1984/archive/2016/07/12/211381.html'>阅读全文</a><img src ="http://www.cppblog.com/qinqing1984/aggbug/211381.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qinqing1984/" target="_blank">春秋十二月</a> 2016-07-12 15:31 <a href="http://www.cppblog.com/qinqing1984/archive/2016/07/12/211381.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>nginx iocp（2）：udp异步接收</title><link>http://www.cppblog.com/qinqing1984/archive/2015/06/25/211041.html</link><dc:creator>春秋十二月</dc:creator><author>春秋十二月</author><pubDate>Thu, 25 Jun 2015 09:01:00 GMT</pubDate><guid>http://www.cppblog.com/qinqing1984/archive/2015/06/25/211041.html</guid><wfw:comment>http://www.cppblog.com/qinqing1984/comments/211041.html</wfw:comment><comments>http://www.cppblog.com/qinqing1984/archive/2015/06/25/211041.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/qinqing1984/comments/commentRss/211041.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qinqing1984/services/trackbacks/211041.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;nginx的域名解析器使用已连接udp（收发前先调用ngx_udp_connect）发送dns查询、接收dns响应，如上篇<a href="http://www.cppblog.com/qinqing1984/archive/2015/06/24/211030.html" target="_blank">tcp异步连接</a>所讲，iocp需要先投递udp的接收操作，才能引发接收完成的事件，因此要对域名解析器和udp异步接收作些改进。<br />
<br />
<strong style="font-size: 12pt">发送后投递</strong><br />
&nbsp; &nbsp; dns查询由ngx_resolver_send_query函数实现，定义在core/ngx_resolver.c中。
<div align="center">
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px">
<div align="left"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080">&nbsp;1</span><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;ngx_int_t&nbsp;</span><span style="color: #800000"><strong>ngx_resolver_send_query</strong></span><span style="color: #000000">(ngx_resolver_t&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">r,&nbsp;ngx_resolver_node_t&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">rn)<br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img id="Codehighlighter1_85_516_Open_Image" onclick="this.style.display='none'; Codehighlighter1_85_516_Open_Text.style.display='none'; Codehighlighter1_85_516_Closed_Image.style.display='inline'; Codehighlighter1_85_516_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_85_516_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_85_516_Closed_Text.style.display='none'; Codehighlighter1_85_516_Open_Image.style.display='inline'; Codehighlighter1_85_516_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_85_516_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_85_516_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<img alt="" src="http://www.cppblog.com/Images/dot.gif" /><br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img id="Codehighlighter1_126_191_Open_Image" onclick="this.style.display='none'; Codehighlighter1_126_191_Open_Text.style.display='none'; Codehighlighter1_126_191_Closed_Image.style.display='inline'; Codehighlighter1_126_191_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_126_191_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_126_191_Closed_Text.style.display='none'; Codehighlighter1_126_191_Open_Image.style.display='inline'; Codehighlighter1_126_191_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(rn</span><span style="color: #000000">-&gt;</span><span style="color: #000000">naddrs&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;(u_short)&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">)&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_126_191_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_126_191_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;ngx_send(uc</span><span style="color: #000000">-&gt;</span><span style="color: #000000">connection,&nbsp;rn</span><span style="color: #000000">-&gt;</span><span style="color: #000000">query,&nbsp;rn</span><span style="color: #000000">-&gt;</span><span style="color: #000000">qlen);<br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<img alt="" src="http://www.cppblog.com/Images/dot.gif" /><br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /><br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #0000ff">#if</span><span style="color: #000000">&nbsp;(NGX_HAVE_INET6)</span><span style="color: #000000"><br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img id="Codehighlighter1_264_331_Open_Image" onclick="this.style.display='none'; Codehighlighter1_264_331_Open_Text.style.display='none'; Codehighlighter1_264_331_Closed_Image.style.display='inline'; Codehighlighter1_264_331_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_264_331_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_264_331_Closed_Text.style.display='none'; Codehighlighter1_264_331_Open_Image.style.display='inline'; Codehighlighter1_264_331_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(rn</span><span style="color: #000000">-&gt;</span><span style="color: #000000">query6&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;rn</span><span style="color: #000000">-&gt;</span><span style="color: #000000">naddrs6&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;(u_short)&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">)&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_264_331_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_264_331_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;ngx_send(uc</span><span style="color: #000000">-&gt;</span><span style="color: #000000">connection,&nbsp;rn</span><span style="color: #000000">-&gt;</span><span style="color: #000000">query6,&nbsp;rn</span><span style="color: #000000">-&gt;</span><span style="color: #000000">qlen);<br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<img alt="" src="http://www.cppblog.com/Images/dot.gif" /><br />
</span><span style="color: #008080">13</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">14</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #0000ff">#endif</span><span style="color: #000000"><br />
</span><span style="color: #008080">15</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /><br />
</span><span style="color: #008080">16</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #0000ff">#if</span><span style="color: #000000">&nbsp;(NGX_WIN32)&nbsp;</span><span style="color: #000000"><br />
</span><span style="color: #008080">17</span><span style="color: #000000"><img id="Codehighlighter1_400_489_Open_Image" onclick="this.style.display='none'; Codehighlighter1_400_489_Open_Text.style.display='none'; Codehighlighter1_400_489_Closed_Image.style.display='inline'; Codehighlighter1_400_489_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_400_489_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_400_489_Closed_Text.style.display='none'; Codehighlighter1_400_489_Open_Image.style.display='inline'; Codehighlighter1_400_489_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(ngx_event_flags&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;</span><span style="color: #ff0000">NGX_USE_IOCP_EVENT)</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_400_489_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_400_489_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">18</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uc</span><span style="color: #000000">-&gt;</span><span style="color: #000000">connection</span><span style="color: #000000">-&gt;</span><span style="color: #000000">read</span><span style="color: #000000">-&gt;</span><span style="color: #000000">ready&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">;<br />
</span><span style="color: #008080">19</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: red">ngx_resolver_read_response</span><span style="color: #000000">(uc</span><span style="color: #000000">-&gt;</span><span style="color: #000000">connection</span><span style="color: #000000">-&gt;</span><span style="color: #000000">read);<br />
</span><span style="color: #008080">20</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">21</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #0000ff">#endif</span><span style="color: #000000"><br />
</span><span style="color: #008080">22</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /><br />
</span><span style="color: #008080">23</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;NGX_OK;<br />
</span><span style="color: #008080">24</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span></div>
</div>
</div>
&nbsp; &nbsp; 当nginx用于代理连接上游服务器前，要先解析域名，首次调用链为：<span style="color: #993300;">ngx_http_upstream_init_request</span>-&gt;<span style="color: #993300;">ngx_resolver_name</span>-&gt;<span style="color: #993300;">ngx_resolver_name_locked</span>-&gt;<span style="color: #993300;">ngx_resolver_send_query</span>；若5s（单次超时）后还没收到dns响应，则再发送1次查询，调用链为：<span style="color: #993300;">ngx_resolver_resend_handler</span>-&gt;<span style="color: #993300;">ngx_resolver_resend</span>-&gt;<span style="color: #993300;">ngx_resolver_send_query</span>，如此反复，直到收到响应或30s（默认总超时）后不再发送查询。它调用ngx_send发送dns查询，16行~21行代码为笔者添加，ngx_resolver_read_response函数用于接收并分析dns响应报文，它会调用到下面的ngx_udp_overlapped_wsarecv函数。<br />
<br />
<strong style="font-size: 12pt">异步接收</strong><br />
&nbsp;&nbsp;&nbsp;由ngx_udp_overlapped_wsarecv函数实现，定义在os/win32/ngx_udp_wsarecv.c中。
<div align="center">
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px">
<div align="left"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080">&nbsp;1</span><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #000000">ssize_t&nbsp;</span><span style="color: #800000"><strong>ngx_udp_overlapped_wsarecv</strong></span><span style="color: #000000">(ngx_connection_t&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">c,&nbsp;u_char&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">buf,&nbsp;size_t&nbsp;size)<br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img id="Codehighlighter1_82_1619_Open_Image" onclick="this.style.display='none'; Codehighlighter1_82_1619_Open_Text.style.display='none'; Codehighlighter1_82_1619_Closed_Image.style.display='inline'; Codehighlighter1_82_1619_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_82_1619_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_82_1619_Closed_Text.style.display='none'; Codehighlighter1_82_1619_Open_Image.style.display='inline'; Codehighlighter1_82_1619_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_82_1619_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_82_1619_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp; &nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flags,&nbsp;rc;<br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp; WSABUF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wsabuf;<br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;ngx_err_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err;<br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp; ngx_event_t&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">rev;<br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;WSAOVERLAPPED&nbsp;&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">ovlp;<br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;u_long&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bytes;<br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;rev&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;c</span><span style="color: #000000">-&gt;</span><span style="color: #000000">read;<br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img id="Codehighlighter1_265_380_Open_Image" onclick="this.style.display='none'; Codehighlighter1_265_380_Open_Text.style.display='none'; Codehighlighter1_265_380_Closed_Image.style.display='inline'; Codehighlighter1_265_380_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_265_380_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_265_380_Closed_Text.style.display='none'; Codehighlighter1_265_380_Open_Image.style.display='inline'; Codehighlighter1_265_380_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(</span><span style="color: #000000">!</span><span style="color: #000000">rev</span><span style="color: #000000">-&gt;</span><span style="color: #000000">ready)&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_265_380_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_265_380_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">13</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ngx_log_error(NGX_LOG_ALERT,&nbsp;c</span><span style="color: #000000">-&gt;</span><span style="color: #000000">log,&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">ngx_udp_overlapped_wsarecv&nbsp;second&nbsp;wsa&nbsp;post</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
</span><span style="color: #008080">14</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;NGX_AGAIN</span>;<br />
<span style="color: #008080">15</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">16</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">17</span><span style="color: #000000"><img id="Codehighlighter1_405_670_Open_Image" onclick="this.style.display='none'; Codehighlighter1_405_670_Open_Text.style.display='none'; Codehighlighter1_405_670_Closed_Image.style.display='inline'; Codehighlighter1_405_670_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_405_670_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_405_670_Closed_Text.style.display='none'; Codehighlighter1_405_670_Open_Image.style.display='inline'; Codehighlighter1_405_670_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(rev</span><span style="color: #000000">-&gt;</span><span style="color: #000000">complete)&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_405_670_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_405_670_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">18</span><span style="color: #000000"><img id="Codehighlighter1_452_637_Open_Image" onclick="this.style.display='none'; Codehighlighter1_452_637_Open_Text.style.display='none'; Codehighlighter1_452_637_Closed_Image.style.display='inline'; Codehighlighter1_452_637_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_452_637_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_452_637_Closed_Text.style.display='none'; Codehighlighter1_452_637_Open_Image.style.display='inline'; Codehighlighter1_452_637_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(ngx_event_flags&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;NGX_USE_IOCP_EVENT)&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_452_637_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_452_637_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">19</span><span style="color: #000000"><img id="Codehighlighter1_517_632_Open_Image" onclick="this.style.display='none'; Codehighlighter1_517_632_Open_Text.style.display='none'; Codehighlighter1_517_632_Closed_Image.style.display='inline'; Codehighlighter1_517_632_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_517_632_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_517_632_Closed_Text.style.display='none'; Codehighlighter1_517_632_Open_Image.style.display='inline'; Codehighlighter1_517_632_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(rev</span><span style="color: #000000">-&gt;</span><span style="color: #000000">ovlp.error&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;</span><span style="color: red">rev</span><span style="color: red">-&gt;</span><span style="color: red">ovlp.error&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #ff0000">ERROR_MORE_DATA</span><span style="color: #000000">)&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_517_632_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_517_632_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">20</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ngx_connection_error(c,&nbsp;rev</span><span style="color: #000000">-&gt;</span><span style="color: #000000">ovlp.error,&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">ngx_udp_overlapped_wsarecv()&nbsp;failed</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
</span><span style="color: #008080">21</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;NGX_ERROR;<br />
</span><span style="color: #008080">22</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">23</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">24</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;<img alt="" src="http://www.cppblog.com/Images/dot.gif" /><br />
</span><span style="color: #008080">25</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;rev</span><span style="color: #000000">-&gt;</span><span style="color: #000000">complete&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />
</span><span style="color: #008080">26</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">27</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">28</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;ovlp&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: red;">NULL</span>;<br />
<span style="color: #008080">29</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;wsabuf.buf&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(CHAR&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">)&nbsp;buf;<br />
</span><span style="color: #008080">30</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;wsabuf.len&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(ULONG)&nbsp;size;<br />
</span><span style="color: #008080">31</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;flags&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />
</span><span style="color: #008080">32</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">33</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />retry:&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">34</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;rc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;WSARecv(c</span><span style="color: #000000">-&gt;</span><span style="color: #000000">fd,&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">wsabuf,&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">,&nbsp;(DWORD</span><span style="color: #000000">*</span><span style="color: #000000">)</span><span style="color: #000000">&amp;</span><span style="color: #000000">bytes,&nbsp;(LPDWORD)</span><span style="color: #000000">&amp;</span><span style="color: #000000">flags,&nbsp;ovlp,&nbsp;NULL);<br />
</span><span style="color: #008080">35</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">36</span><span style="color: #000000"><img id="Codehighlighter1_864_1502_Open_Image" onclick="this.style.display='none'; Codehighlighter1_864_1502_Open_Text.style.display='none'; Codehighlighter1_864_1502_Closed_Image.style.display='inline'; Codehighlighter1_864_1502_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_864_1502_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_864_1502_Closed_Text.style.display='none'; Codehighlighter1_864_1502_Open_Image.style.display='inline'; Codehighlighter1_864_1502_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(rc&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">)&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_864_1502_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_864_1502_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">37</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rev</span><span style="color: #000000">-&gt;</span><span style="color: #000000">ready&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />
</span><span style="color: #008080">38</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;ngx_socket_errno;<br />
</span><span style="color: #008080">39</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">40</span><span style="color: #000000"><img id="Codehighlighter1_948_982_Open_Image" onclick="this.style.display='none'; Codehighlighter1_948_982_Open_Text.style.display='none'; Codehighlighter1_948_982_Closed_Image.style.display='inline'; Codehighlighter1_948_982_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_948_982_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_948_982_Closed_Text.style.display='none'; Codehighlighter1_948_982_Open_Image.style.display='inline'; Codehighlighter1_948_982_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(err&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;WSA_IO_PENDING)&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_948_982_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_948_982_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">41</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;NGX_AGAIN;<br />
</span><span style="color: #008080">42</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">43</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">44</span><span style="color: #000000"><img id="Codehighlighter1_1018_1374_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1018_1374_Open_Text.style.display='none'; Codehighlighter1_1018_1374_Closed_Image.style.display='inline'; Codehighlighter1_1018_1374_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_1018_1374_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_1018_1374_Closed_Text.style.display='none'; Codehighlighter1_1018_1374_Open_Image.style.display='inline'; Codehighlighter1_1018_1374_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(err&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;WSAEWOULDBLOCK)&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_1018_1374_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_1018_1374_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">45</span><span style="color: #000000"><img id="Codehighlighter1_1071_1338_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1071_1338_Open_Text.style.display='none'; Codehighlighter1_1071_1338_Closed_Image.style.display='inline'; Codehighlighter1_1071_1338_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_1071_1338_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_1071_1338_Closed_Text.style.display='none'; Codehighlighter1_1071_1338_Open_Image.style.display='inline'; Codehighlighter1_1071_1338_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(ngx_event_flags&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;NGX_USE_IOCP_EVENT)&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_1071_1338_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_1071_1338_Open_Text"><span style="color: #000000">{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">46</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rev</span><span style="color: #000000">-&gt;</span><span style="color: #000000">ovlp.type&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;NGX_IOCP_IO;<br />
</span><span style="color: #008080">47</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ovlp&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(WSAOVERLAPPED&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">)</span><span style="color: #000000">&amp;</span><span style="color: #000000">rev</span><span style="color: #000000">-&gt;</span><span style="color: #000000">ovlp;<br />
</span><span style="color: #008080">48</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ngx_memzero(ovlp,&nbsp;</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(WSAOVERLAPPED));<br />
</span><span style="color: #008080">49</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">50</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wsabuf.buf&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: red;">NULL</span>;<br /><span style="color: #008080">51</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #000000">wsabuf.len&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: red">0</span><span style="color: #000000">;<br />
</span><span style="color: #008080">52</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flags&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #ff0000">MSG_PEEK</span>;<br />
<span style="color: #008080">53</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">54</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">goto</span><span style="color: #000000">&nbsp;retry;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">55</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">56</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">57</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;NGX_AGAIN;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">58</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">59</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">60</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ngx_connection_error(c,&nbsp;err,&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">ngx_udp_overlapped_wsarecv()&nbsp;failed</span><span style="color: #000000">"</span><span style="color: #000000">);&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">61</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rev</span><span style="color: #000000">-&gt;</span><span style="color: #000000">error&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">;<br />
</span><span style="color: #008080">62</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">63</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;NGX_ERROR;<br />
</span><span style="color: #008080">64</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">65</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">66</span><span style="color: #000000"><img id="Codehighlighter1_1559_1600_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1559_1600_Open_Text.style.display='none'; Codehighlighter1_1559_1600_Closed_Image.style.display='inline'; Codehighlighter1_1559_1600_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_1559_1600_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_1559_1600_Closed_Text.style.display='none'; Codehighlighter1_1559_1600_Open_Image.style.display='inline'; Codehighlighter1_1559_1600_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;((ngx_event_flags&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;NGX_USE_IOCP_EVENT)&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;ovlp)&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_1559_1600_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_1559_1600_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">67</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rev</span><span style="color: #000000">-&gt;</span><span style="color: #000000">ready&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />
</span><span style="color: #008080">68</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: red">NGX_AGAIN;</span><span style="color: #000000"><br />
</span><span style="color: #008080">69</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">70</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">71</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;bytes;<br />
</span><span style="color: #008080">72</span><span style="color: #000000;"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span></div>
</div>
</div>
&nbsp;&nbsp;&nbsp;先以非阻塞方式接收，若发生WSAWOULDBLOCK错误，则使用MSG_PEEK标志投递一个0字节的重叠接收操作，当dns响应返回时发生完成事件，会再次进入ngx_resolver_read_response而调用到该函数，此时rev-&gt;complete为1，rev-&gt;ovlp.error为ERROR_MORE_DATA（GetQueuedCompletionStatus返回的错误），由于使用了MSG_PEEK，因此数据还在接收缓冲区中，要忽略ERROR_MORE_DATA而继续接收，这时就能成功了。不管WSARecv返回WSA_IO_PENDING错误还是成功，iocp都会得到完成通知，所以这里当重叠操作投递成功时，返回NGX_AGAIN，便于在回调内统一处理。<img src ="http://www.cppblog.com/qinqing1984/aggbug/211041.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qinqing1984/" target="_blank">春秋十二月</a> 2015-06-25 17:01 <a href="http://www.cppblog.com/qinqing1984/archive/2015/06/25/211041.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>nginx iocp（1）：tcp异步连接</title><link>http://www.cppblog.com/qinqing1984/archive/2015/06/24/211030.html</link><dc:creator>春秋十二月</dc:creator><author>春秋十二月</author><pubDate>Wed, 24 Jun 2015 09:02:00 GMT</pubDate><guid>http://www.cppblog.com/qinqing1984/archive/2015/06/24/211030.html</guid><wfw:comment>http://www.cppblog.com/qinqing1984/comments/211030.html</wfw:comment><comments>http://www.cppblog.com/qinqing1984/archive/2015/06/24/211030.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/qinqing1984/comments/commentRss/211030.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qinqing1984/services/trackbacks/211030.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;iocp是Windows NT操作系统的一种高效IO模型，对应于Linux中的epoll和FreeBSD中的kqueue，nginx对ske(select、kqueue和epoll的首写字母组合)的支持很好，但截止到1.6.2版本，还不支持iocp。由于ske都是反应器模式，即先注册IO事件，当IO事件发生（读写通知）时，在其回调内主动调用API来读或写数据；而iocp是前摄器模式，要先投递IO操作，才能引发IO事件（完成通知）的发生，在其回调内数据已被动由操作系统读或写完成。因此，iocp的特点决定了nginx对它的支持与ske有所不同。通过hg clone <a href="http://hg.nginx.org/nginx">http://hg.nginx.org/nginx</a>下载的nginx源代码，虽然实现了iocp事件模块、异步接受连接、部分异步读写，但根本不能正常工作，而且不支持异步连接和SCM服务控制，笔者在参考ske模块的实现基础上，改进支持了如下特性：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. 异步接受连接时的负载均衡<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. 正反向代理的异步连接<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3. 异步聚合读写<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4. 域名解析时的UDP异步接收<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.&nbsp;异步文件传输<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6.&nbsp;SCM服务控制<br />
&nbsp;&nbsp;&nbsp;由于2、4、6均为原创，其它几点的思路皆源于ske模块的实现（只是平台API不同），因此本文先阐述异步连接的实现。为了兼容select事件模块，所有iocp相关的代码使用NGX_HAVE_IOCP宏和（或）NGX_USE_IOCP_EVENT标志包围，其中NGX_HAVE_IOCP宏用于条件编译，在WIN32平台下，定义为1；当选择的事件模块为iocp时，全局变量ngx_event_flags才包含NGX_USE_IOCP_EVENT标志。<br />
<br />
<strong style="font-size: 12pt">异步连接对端<br />
</strong>&nbsp;&nbsp;&nbsp;由ngx_event_connect_peer函数（这里省去了与异步连接无关的代码）实现，定义在event/ngx_event_connect.c中，因为connect不支持异步连接事件的完成通知，所以要使用扩展API ConnectEx。&nbsp;
<div align="center"></div>
<div align="center"></div>
<div align="center">
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px">
<div align="left"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080">&nbsp;1</span><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #000000">ngx_int_t&nbsp;</span><span style="color: #800000"><strong>ngx_event_connect_peer</strong></span><span style="color: #000000">(ngx_peer_connection_t&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">pc)<br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img id="Codehighlighter1_60_1409_Open_Image" onclick="this.style.display='none'; Codehighlighter1_60_1409_Open_Text.style.display='none'; Codehighlighter1_60_1409_Closed_Image.style.display='inline'; Codehighlighter1_60_1409_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_60_1409_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_60_1409_Closed_Text.style.display='none'; Codehighlighter1_60_1409_Open_Image.style.display='inline'; Codehighlighter1_60_1409_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_60_1409_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_60_1409_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rc;<br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;ngx_int_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">event</span><span style="color: #000000">;<br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;ngx_err_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err;<br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;ngx_uint_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;level,family;<br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;ngx_socket_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s;<br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;ngx_event_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">rev,&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">wev;<br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span style="color: #000000"><br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;s&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;ngx_socket(family&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;pc</span><span style="color: #000000">-&gt;</span><span style="color: #000000">sockaddr</span><span style="color: #000000">-&gt;</span><span style="color: #000000">sa_family,&nbsp;SOCK_STREAM,&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">);<br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<img alt="" src="http://www.cppblog.com/Images/dot.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">#if</span><span style="color: #000000">&nbsp;(NGX_HAVE_IOCP)</span><span style="color: #000000"><br />
</span><span style="color: #008080">13</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">((pc</span><span style="color: #000000">-&gt;</span><span style="color: #000000">local</span><span style="color: #000000">==</span><span style="color: #000000">NULL</span><span style="color: #000000">||</span><span style="color: #000000">pc</span><span style="color: #000000">-&gt;</span><span style="color: #000000">local</span><span style="color: #000000">-&gt;</span><span style="color: #000000">sockaddr</span><span style="color: #000000">-&gt;</span><span style="color: #000000">sa_family&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;family)&nbsp;<br />
</span><span style="color: #008080">14</span><span style="color: #000000"><img id="Codehighlighter1_435_521_Open_Image" onclick="this.style.display='none'; Codehighlighter1_435_521_Open_Text.style.display='none'; Codehighlighter1_435_521_Closed_Image.style.display='inline'; Codehighlighter1_435_521_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_435_521_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_435_521_Closed_Text.style.display='none'; Codehighlighter1_435_521_Open_Image.style.display='inline'; Codehighlighter1_435_521_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;(ngx_event_flags&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;NGX_USE_IOCP_EVENT))</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_435_521_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_435_521_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">15</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(</span><span style="color: #ff0000">ngx_iocp_set_localaddr</span><span style="color: #000000">(pc</span><span style="color: #000000">-&gt;</span><span style="color: #000000">log,family,</span><span style="color: #000000">&amp;</span><span style="color: #000000">pc</span><span style="color: #000000">-&gt;</span><span style="color: #000000">local)&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;NGX_OK)<br />
</span><span style="color: #008080">16</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">goto</span><span style="color: #000000">&nbsp;failed;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">17</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">18</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">#endif</span><span style="color: #000000"><br /></span><font color="#008080">19</font><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<img alt="" src="http://www.cppblog.com/Images/dot.gif" />&nbsp;&nbsp;&nbsp;<br />
<span style="color: #008080">20</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">21</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">#if</span><span style="color: #000000">&nbsp;(NGX_HAVE_IOCP)</span><span style="color: #000000"><br />
</span><span style="color: #008080">22</span><span style="color: #000000"><img id="Codehighlighter1_601_828_Open_Image" onclick="this.style.display='none'; Codehighlighter1_601_828_Open_Text.style.display='none'; Codehighlighter1_601_828_Closed_Image.style.display='inline'; Codehighlighter1_601_828_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_601_828_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_601_828_Closed_Text.style.display='none'; Codehighlighter1_601_828_Open_Image.style.display='inline'; Codehighlighter1_601_828_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(ngx_event_flags</span><span style="color: #000000">&amp;</span><span style="color: #000000">NGX_USE_IOCP_EVENT)</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_601_828_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_601_828_Open_Text"><span style="color: #000000">{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">23</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LPWSAOVERLAPPED&nbsp;&nbsp;&nbsp;ovlp;<br />
</span><span style="color: #008080">24</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ovlp&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(LPWSAOVERLAPPED)</span><span style="color: #000000">&amp;</span><span style="color: #000000">wev</span><span style="color: #000000">-&gt;</span><span style="color: #000000">ovlp;<br />
</span><span style="color: #008080">25</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ngx_memzero(ovlp,</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(WSAOVERLAPPED));<br />
</span><span style="color: #008080">26</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wev</span><span style="color: #000000">-&gt;</span><span style="color: #000000">ovlp.type&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;NGX_IOCP_CONNECT;<br />
</span><span style="color: #008080">27</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #ff0000">ngx_connectex</span><span style="color: #000000">(s,pc</span><span style="color: #000000">-&gt;</span><span style="color: #000000">sockaddr,pc</span><span style="color: #000000">-&gt;</span><span style="color: #000000">socklen,NULL,</span><span style="color: #000000">0</span><span style="color: #000000">,NULL,ovlp)&nbsp;</span><span style="color: #000000">?</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">&nbsp;:&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">;<br />
</span><span style="color: #008080">28</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<br /></span><font color="#008080">29</font><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #0000ff">else</span><span style="color: #000000"><br />
</span><span style="color: #008080">30</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;connect(s,&nbsp;pc</span><span style="color: #000000">-&gt;</span><span style="color: #000000">sockaddr,&nbsp;pc</span><span style="color: #000000">-&gt;</span><span style="color: #000000">socklen);<br />
</span><span style="color: #008080">31</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">#else</span><span style="color: #000000"><br />
</span><span style="color: #008080">32</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;connect(s,&nbsp;pc</span><span style="color: #000000">-&gt;</span><span style="color: #000000">sockaddr,&nbsp;pc</span><span style="color: #000000">-&gt;</span><span style="color: #000000">socklen);<br />
</span><span style="color: #008080">33</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">#endif</span><span style="color: #000000"><br />
</span><span style="color: #008080">34</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">35</span><span style="color: #000000"><img id="Codehighlighter1_959_1400_Open_Image" onclick="this.style.display='none'; Codehighlighter1_959_1400_Open_Text.style.display='none'; Codehighlighter1_959_1400_Closed_Image.style.display='inline'; Codehighlighter1_959_1400_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_959_1400_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_959_1400_Closed_Text.style.display='none'; Codehighlighter1_959_1400_Open_Image.style.display='inline'; Codehighlighter1_959_1400_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(rc&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">)&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_959_1400_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_959_1400_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">36</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;ngx_socket_errno;<br />
</span><span style="color: #008080">37</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(err&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;NGX_EINPROGRESS<br />
</span><span style="color: #008080">38</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">#if</span><span style="color: #000000">&nbsp;(NGX_WIN32)</span><span style="color: #000000"><br /></span><font color="#008080">39</font><img id="Codehighlighter1_1041_1089_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1041_1089_Open_Text.style.display='none'; Codehighlighter1_1041_1089_Closed_Image.style.display='inline'; Codehighlighter1_1041_1089_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_1041_1089_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_1041_1089_Closed_Text.style.display='none'; Codehighlighter1_1041_1089_Open_Image.style.display='inline'; Codehighlighter1_1041_1089_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_1041_1089_Closed_Text">/**/</span><span id="Codehighlighter1_1041_1089_Open_Text"><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;Winsock&nbsp;returns&nbsp;WSAEWOULDBLOCK&nbsp;(NGX_EAGAIN)&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">40</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;err&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;NGX_EAGAIN<br />
</span><span style="color: #008080">41</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">#if</span><span style="color: #000000">&nbsp;(NGX_HAVE_IOCP)</span><span style="color: #000000"><br />
</span><span style="color: #008080">42</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;</span><span style="color: #ff0000">err&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #ff0000">WSA_IO_PENDING</span><span style="color: #000000"><br />
</span><span style="color: #008080">43</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">#endif</span><span style="color: #000000"><br />
</span><span style="color: #008080">44</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">#endif</span><span style="color: #000000"><br />
</span><span style="color: #008080">45</span><span style="color: #000000"><img id="Codehighlighter1_1188_1397_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1188_1397_Open_Text.style.display='none'; Codehighlighter1_1188_1397_Closed_Image.style.display='inline'; Codehighlighter1_1188_1397_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_1188_1397_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_1188_1397_Closed_Text.style.display='none'; Codehighlighter1_1188_1397_Open_Image.style.display='inline'; Codehighlighter1_1188_1397_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_1188_1397_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_1188_1397_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">46</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img alt="" src="http://www.cppblog.com/Images/dot.gif" /><br />
</span><span style="color: #008080">47</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ngx_log_error(level,&nbsp;c</span><span style="color: #000000">-&gt;</span><span style="color: #000000">log,&nbsp;err,&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">connect()&nbsp;to&nbsp;%V&nbsp;failed</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;pc</span><span style="color: #000000">-&gt;</span><span style="color: #000000">name);<br />
</span><span style="color: #008080">48</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ngx_close_connection(c);<br /></span><font color="#008080">49</font><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pc<span style="color: #000000">-&gt;</span><span style="color: #000000">connection&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;NULL;<br />
</span><span style="color: #008080">50</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">51</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;NGX_DECLINED;<br />
</span><span style="color: #008080">52</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">53</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">54</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp; &nbsp;&nbsp;<img alt="" src="http://www.cppblog.com/Images/dot.gif" /><br />
</span><span style="color: #008080">55</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span></div>
</div>
</div>
&nbsp;&nbsp;&nbsp;调用ConnectEx前要先bind本地地址，不然发生WSAEINVAL错误；由于域名解析可能返回IPv6记录，导致创建本地套接字的地址族为AF_INET6，因此bind时需要匹配IPv6地址，不然发生WSAEFAULT错误，导致nginx返回<span style="color: red;">Internal Server Error</span>错误给前端，因此绑定前要调用<a href="#ngx_iocp_set_localaddr">ngx_iocp_set_localaddr</a>设定正确的本地地址，当且仅当pc-&gt;local为空或地址族不匹配时。<br />
<br />
<strong style="font-size: 12pt">本地初始化与设定</strong><br />
&nbsp;&nbsp;&nbsp;支持IPv6，实现在event/modules/ngx_iocp_module.c。<br />
&nbsp;&nbsp; 地址变量定义如下。<br />
<div align="center">
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px">
<div align="left"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080">1</span><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" /><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;sockaddr_in&nbsp;&nbsp;sin;<br />
</span><span style="color: #008080">2</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">#if</span><span style="color: #000000">&nbsp;(NGX_HAVE_INET6)</span><span style="color: #000000"><br />
</span><span style="color: #008080">3</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;sockaddr_in6&nbsp;&nbsp;sin6;<br />
</span><span style="color: #008080">4</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">#endif</span><span style="color: #000000"><br />
</span><span style="color: #008080">5</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;ngx_addr_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local_addr;</span></div>
</div>
</div>
&nbsp; &nbsp;sin对应IPv4，sin6对应IPv6，作为bind的套接字本地地址。<br />
<br />
&nbsp;&nbsp;&nbsp;sin和sin6在启动iocp事件模块时调用ngx_iocp_init初始化。&nbsp;&nbsp;&nbsp;
<div align="center"></div>
<div align="center">
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px">
<div align="left"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080">&nbsp;1</span><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" /><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;ngx_int_t&nbsp;</span><span style="color: #800000"><strong>ngx_iocp_init</strong></span><span style="color: #000000">(ngx_cycle_t&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">cycle,&nbsp;ngx_msec_t&nbsp;timer)<br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img id="Codehighlighter1_69_378_Open_Image" onclick="this.style.display='none'; Codehighlighter1_69_378_Open_Text.style.display='none'; Codehighlighter1_69_378_Closed_Image.style.display='inline'; Codehighlighter1_69_378_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_69_378_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_69_378_Closed_Text.style.display='none'; Codehighlighter1_69_378_Open_Image.style.display='inline'; Codehighlighter1_69_378_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_69_378_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_69_378_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<img alt="" src="http://www.cppblog.com/Images/dot.gif" /><br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;sin.sin_family&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;AF_INET;<br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;sin.sin_port&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;sin.sin_addr.s_addr&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;INADDR_ANY;<br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" /></span><span style="color: #0000ff">#if</span><span style="color: #000000">&nbsp;(NGX_HAVE_INET6)</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;sin6.sin6_family&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;AF_INET6;<br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;sin6.sin6_port&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;sin6.sin6_addr&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;in6addr_any;<br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" /></span><span style="color: #0000ff">#endif</span><span style="color: #000000"><br />
</span><span style="color: #008080">13</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">14</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;local_addr.name.len&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(</span><span style="color: #000000">"</span><span style="color: #000000">INADDR_ANY</span><span style="color: #000000">"</span><span style="color: #000000">)&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">;<br />
</span><span style="color: #008080">15</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;local_addr.name.data&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(u_char&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">)</span><span style="color: #000000">"</span><span style="color: #000000">INADDR_ANY</span><span style="color: #000000">"</span><span style="color: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">16</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<img alt="" src="http://www.cppblog.com/Images/dot.gif" /><br />
</span><span style="color: #008080">17</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span></div>
</div>
</div>
&nbsp;&nbsp;&nbsp;不论IP地址或端口，都指定为0，表示由系统自动分配出口IP地址和未占用的端口。<br />
<br />
&nbsp;&nbsp;&nbsp;<a id="ngx_iocp_set_localaddr">本地设定由ngx_iocp_set_localaddr实现。<br />
<div align="center">
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px">
<div align="left"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080">&nbsp;1</span><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" /><span style="color: #000000">ngx_int_t&nbsp;</span><span style="color: #800000"><strong>ngx_iocp_set_localaddr</strong></span><span style="color: #000000">(ngx_log_t&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">log,&nbsp;in_port_t&nbsp;family,&nbsp;ngx_addr_t&nbsp;</span><span style="color: #000000">**</span><span style="color: #000000">local)<br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img id="Codehighlighter1_87_522_Open_Image" onclick="this.style.display='none'; Codehighlighter1_87_522_Open_Text.style.display='none'; Codehighlighter1_87_522_Closed_Image.style.display='inline'; Codehighlighter1_87_522_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_87_522_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_87_522_Closed_Text.style.display='none'; Codehighlighter1_87_522_Open_Image.style.display='inline'; Codehighlighter1_87_522_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_87_522_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_87_522_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;sockaddr&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">sa;<br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;socklen_t&nbsp;len;<br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img id="Codehighlighter1_151_208_Open_Image" onclick="this.style.display='none'; Codehighlighter1_151_208_Open_Text.style.display='none'; Codehighlighter1_151_208_Closed_Image.style.display='inline'; Codehighlighter1_151_208_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_151_208_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_151_208_Closed_Text.style.display='none'; Codehighlighter1_151_208_Open_Image.style.display='inline'; Codehighlighter1_151_208_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(AF_INET&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;family)</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_151_208_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_151_208_Open_Text"><span style="color: #000000">{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sa&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">sin;<br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;sockaddr_in);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" /></span><span style="color: #0000ff">#if</span><span style="color: #000000">&nbsp;(NGX_HAVE_INET6)</span><span style="color: #000000"><br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img id="Codehighlighter1_259_313_Open_Image" onclick="this.style.display='none'; Codehighlighter1_259_313_Open_Text.style.display='none'; Codehighlighter1_259_313_Closed_Image.style.display='inline'; Codehighlighter1_259_313_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_259_313_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_259_313_Closed_Text.style.display='none'; Codehighlighter1_259_313_Open_Image.style.display='inline'; Codehighlighter1_259_313_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(AF_INET6&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;family)</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_259_313_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_259_313_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sa&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">sin6;<br />
</span><span style="color: #008080">13</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;sockaddr_in6);<br />
</span><span style="color: #008080">14</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">15</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" /></span><span style="color: #0000ff">#endif</span><span style="color: #000000"><br />
</span><span style="color: #008080">16</span><span style="color: #000000"><img id="Codehighlighter1_327_424_Open_Image" onclick="this.style.display='none'; Codehighlighter1_327_424_Open_Text.style.display='none'; Codehighlighter1_327_424_Closed_Image.style.display='inline'; Codehighlighter1_327_424_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_327_424_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_327_424_Closed_Text.style.display='none'; Codehighlighter1_327_424_Open_Image.style.display='inline'; Codehighlighter1_327_424_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_327_424_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_327_424_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">17</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ngx_log_error(NGX_LOG_ALERT,&nbsp;log,&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">not&nbsp;supported&nbsp;address&nbsp;family</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
</span><span style="color: #008080">18</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;NGX_ERROR;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">19</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">20</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" /><br />
</span><span style="color: #008080">21</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;local_addr.sockaddr&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;sa;<br />
</span><span style="color: #008080">22</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;local_addr.socklen&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;len;</span><span style="color: #000000"><br />
</span><span style="color: #008080">23</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">local&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">local_addr;<br />
</span><span style="color: #008080">24</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" /><br />
</span><span style="color: #008080">25</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;NGX_OK;<br />
</span><span style="color: #008080">26</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span></div>
</div>
</div>
</a>&nbsp;&nbsp;&nbsp;对于除IPv4和IPv6外的协议族，则记录一个错误日志。必要时也可扩展支持其它的协议族，例如NetBIOS（对应地址族为AF_NETBIOS），但要看ConnectEx是否支持。<img src ="http://www.cppblog.com/qinqing1984/aggbug/211030.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qinqing1984/" target="_blank">春秋十二月</a> 2015-06-24 17:02 <a href="http://www.cppblog.com/qinqing1984/archive/2015/06/24/211030.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>面向对象锁框架的设计与实现</title><link>http://www.cppblog.com/qinqing1984/archive/2014/12/28/209327.html</link><dc:creator>春秋十二月</dc:creator><author>春秋十二月</author><pubDate>Sun, 28 Dec 2014 15:38:00 GMT</pubDate><guid>http://www.cppblog.com/qinqing1984/archive/2014/12/28/209327.html</guid><wfw:comment>http://www.cppblog.com/qinqing1984/comments/209327.html</wfw:comment><comments>http://www.cppblog.com/qinqing1984/archive/2014/12/28/209327.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/qinqing1984/comments/commentRss/209327.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qinqing1984/services/trackbacks/209327.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp;本文描述了一种简单的跨平台锁框架的设计与实现，该框架小巧实用、易于扩展，它的特点如下：&nbsp; &nbsp; &nbsp;&#9679; 实现了线程间互斥锁&nbsp; &nbsp; &nbsp;&#9679; 实现优化了单线程环境中的空锁和空级别锁&nbsp; &nbsp; &nbsp;&#9679; 支持编译时或运行时选择锁&nbsp; ...&nbsp;&nbsp;<a href='http://www.cppblog.com/qinqing1984/archive/2014/12/28/209327.html'>阅读全文</a><img src ="http://www.cppblog.com/qinqing1984/aggbug/209327.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qinqing1984/" target="_blank">春秋十二月</a> 2014-12-28 23:38 <a href="http://www.cppblog.com/qinqing1984/archive/2014/12/28/209327.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于boost asio实现的ssl socket框架</title><link>http://www.cppblog.com/qinqing1984/archive/2013/03/20/198644.html</link><dc:creator>春秋十二月</dc:creator><author>春秋十二月</author><pubDate>Wed, 20 Mar 2013 12:47:00 GMT</pubDate><guid>http://www.cppblog.com/qinqing1984/archive/2013/03/20/198644.html</guid><wfw:comment>http://www.cppblog.com/qinqing1984/comments/198644.html</wfw:comment><comments>http://www.cppblog.com/qinqing1984/archive/2013/03/20/198644.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/qinqing1984/comments/commentRss/198644.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qinqing1984/services/trackbacks/198644.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 情景分析&nbsp;&nbsp;&nbsp;现已存在一个可用稳定的异步客户端类http_client_base，该类基于boost asio实现了连接服务器，发送请求，获取响应和解析http数据等操作，该类的大致实现框架如下Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.C...&nbsp;&nbsp;<a href='http://www.cppblog.com/qinqing1984/archive/2013/03/20/198644.html'>阅读全文</a><img src ="http://www.cppblog.com/qinqing1984/aggbug/198644.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qinqing1984/" target="_blank">春秋十二月</a> 2013-03-20 20:47 <a href="http://www.cppblog.com/qinqing1984/archive/2013/03/20/198644.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用正则表达式解析URL</title><link>http://www.cppblog.com/qinqing1984/archive/2011/11/27/161035.html</link><dc:creator>春秋十二月</dc:creator><author>春秋十二月</author><pubDate>Sun, 27 Nov 2011 09:22:00 GMT</pubDate><guid>http://www.cppblog.com/qinqing1984/archive/2011/11/27/161035.html</guid><wfw:comment>http://www.cppblog.com/qinqing1984/comments/161035.html</wfw:comment><comments>http://www.cppblog.com/qinqing1984/archive/2011/11/27/161035.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/qinqing1984/comments/commentRss/161035.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qinqing1984/services/trackbacks/161035.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;在开发HTTP相关程序时，经常会碰到从网络链接URL中提取协议名、服务器、路径等目标对象，如果使用C/C++字符串操作函数，那么则显得有点麻烦且代码不易维护，其实关于文本内容的解析工作，都可优先考虑使用正则表达式库来解决处理，C++方面的正则库也有很多种，如atl、pcre、boost。下面就使用boost中的regex来解析URL提取协议名、服务器、路径为目标说明其用法。<br />
<br />
<strong>协议名</strong><br />&nbsp;&nbsp;&nbsp;可有可无，如果有时则后面必跟着://，如果没有，则默认为使用http协议。通常还有其它的协议如https、ssl、ftp、mailto等。因此匹配协议名的正则表达式应该是(?:(mailto|ssh|ftp|https?)://)?，注意这个表达式本身捕获了协议名，但不包括://。<br />
&nbsp; &nbsp;<br />
<strong>服务器</strong><br />&nbsp;&nbsp;&nbsp;或是域名，如www.csdn.net；或是IP地址，如192.168.1.1，可带端口号，如192.168.1.1:8080。匹配域名的正则表达式为(?:[a-z0-9](?:[-a-z0-9]*[a-z0-9])?\.)+(?:com|net|edu|biz|gov|org|in(?:t|fo)|(?-i:[a-z][a-z]))，表达式"(?:com|net|edu|biz|gov|org|in(?:t|fo)"匹配了com、net、edu、biz、gov、org、int、info等常见的域名，而(?-i:[a-z][a-z])匹配了国家代码，而且只允许小写为合法的，如www.richcomm.com.cn。匹配IP要尽量精确，考虑到IP每部分应为数字且范围在0-255之间，因此表达式应为(?:[01]?\d\d?|2[0-4]\d|25[0-5])\.(?:[01]?\d\d?|2[0-4]\d|25[0-5])\.(?:[01]?\d\d?|2[0-4]\d|25[0-5])\.(?:[01]?\d\d?|2[0-4]\d|25[0-5])。注意以上域名或IP的正则式本身不捕获它们，这是为了留在后面作为整体捕获。<br />
&nbsp;&nbsp;&nbsp;端口号的正则表达式为(?::(\d{1,5}))?，这里限制了端口号为1至5位的数字，更精确的匹配如要求在某范围如[1024,65535]间则可参考以上IP正则模式。综上所得，匹配服务器的正则表达式为((?:(?:[a-z0-9](?:[-a-z0-9]*[a-z0-9])?\.)+(?:com|net|edu|biz|gov|org|in(?:t|fo)|(?-i:[a-z][a-z]))|(?:[01]?\d\d?|2[0-4]\d|25[0-5])\.(?:[01]?\d\d?|2[0-4]\d|25[0-5])\.(?:[01]?\d\d?|2[0-4]\d|25[0-5])\.(?:[01]?\d\d?|2[0-4]\d|25[0-5])))(?::(\d{1,5}))?，这个正则式作为整体捕获了域名或IP，及端口号（若有），如www.csdn.net，则得到www.csdn.net和空（没有端口，http默认为80，https默认为443）子串；192.168.1.1:8080则得到192.168.1.1和8080子串。<br />
&nbsp;&nbsp;&nbsp;<br />
<strong>路径</strong><br />&nbsp; &nbsp;最简单的形式为(/.*)?，更精确的形式为/[^.!,?;"'&lt;&gt;()\[\]{}\s\x7F-\xFF]*(?:[.!,?]+[^.!,?;"'&lt;&gt;()\[\]{}\s\x7F-\xFF]+)*。<br />
&nbsp; &nbsp;<br />
&nbsp;&nbsp;&nbsp;以上所有正则表达式均为ascii字符集，对于unicode字符集则在其前加L即可。<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;为方便使用，封装成了两个自由模板函数，如下所示
<div align="center">
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px">
<div align="left"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080">&nbsp;1</span><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #000000">template</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;charT</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />inline&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;boost_match(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;charT</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;pattern,</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;charT</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;text,unsigned&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;flags</span><span style="color: #000000">=</span><span style="color: #000000">boost::regex::normal,boost::match_results</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;charT</span><span style="color: #000000">*&gt;*</span><span style="color: #000000">&nbsp;result</span><span style="color: #000000">=</span><span style="color: #000000">NULL)<br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img id="Codehighlighter1_177_379_Open_Image" onclick="this.style.display='none'; Codehighlighter1_177_379_Open_Text.style.display='none'; Codehighlighter1_177_379_Closed_Image.style.display='inline'; Codehighlighter1_177_379_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_177_379_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_177_379_Closed_Text.style.display='none'; Codehighlighter1_177_379_Open_Image.style.display='inline'; Codehighlighter1_177_379_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_177_379_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_177_379_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;boost::basic_regex</span><span style="color: #000000">&lt;</span><span style="color: #000000">charT,boost::regex_traits</span><span style="color: #000000">&lt;</span><span style="color: #000000">charT</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;expression(pattern,flags);&nbsp;<br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(NULL</span><span style="color: #000000">==</span><span style="color: #000000">result)<br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;boost::regex_match(text,expression);<br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;boost::regex_match(text,</span><span style="color: #000000">*</span><span style="color: #000000">result,expression);<br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />template</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;charT</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />inline&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;boost_search(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;charT</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;pattern,</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;charT</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;text,unsigned&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;flags</span><span style="color: #000000">=</span><span style="color: #000000">boost::regex::normal,boost::match_results</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;charT</span><span style="color: #000000">*&gt;*</span><span style="color: #000000">&nbsp;result</span><span style="color: #000000">=</span><span style="color: #000000">NULL)<br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img id="Codehighlighter1_560_764_Open_Image" onclick="this.style.display='none'; Codehighlighter1_560_764_Open_Text.style.display='none'; Codehighlighter1_560_764_Closed_Image.style.display='inline'; Codehighlighter1_560_764_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_560_764_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_560_764_Closed_Text.style.display='none'; Codehighlighter1_560_764_Open_Image.style.display='inline'; Codehighlighter1_560_764_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_560_764_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_560_764_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">13</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;boost::basic_regex</span><span style="color: #000000">&lt;</span><span style="color: #000000">charT,boost::regex_traits</span><span style="color: #000000">&lt;</span><span style="color: #000000">charT</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;expression(pattern,flags);&nbsp;<br />
</span><span style="color: #008080">14</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(NULL</span><span style="color: #000000">==</span><span style="color: #000000">result)<br />
</span><span style="color: #008080">15</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;boost::regex_search(text,expression);<br />
</span><span style="color: #008080">16</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;boost::regex_search(text,</span><span style="color: #000000">*</span><span style="color: #000000">result,expression);<br />
</span><span style="color: #008080">17</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span></div>
</div>
</div>
&nbsp; &nbsp;<br />
&nbsp;&nbsp;&nbsp;<span>测试示例如下&nbsp;&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp;
<div align="center">
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px">
<div align="left"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080">&nbsp;1</span><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" alt="" /><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;protocol&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">(?:(mailto|ssh|ftp|https?)://)?</span><span style="color: #000000">"</span><span style="color: #000000">;<br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;hostname&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">(?:[a-z0-9](?:[-a-z0-9]*[a-z0-9])?\\.)+(?:com|net|edu|biz|gov|org|in(?:t|fo)|(?-i:[a-z][a-z]))</span><span style="color: #000000">"</span><span style="color: #000000">;<br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;ip&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">(?:[01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.(?:[01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.(?:[01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.(?:[01]?\\d\\d?|2[0-4]\\d|25[0-5])</span><span style="color: #000000">"</span><span style="color: #000000">;<br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;port&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">(?::(\\d{1,5}))?</span><span style="color: #000000">"</span><span style="color: #000000">;<br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;path&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">(/.*)?</span><span style="color: #000000">"</span><span style="color: #000000">;<br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;pattern&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;protocol&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">((?:</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;hostname&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">|</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;ip&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">))</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;port&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;path;<br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" alt="" /><br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;_tmain(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;argc,&nbsp;_TCHAR</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;argv[])<br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img id="Codehighlighter1_617_2477_Open_Image" onclick="this.style.display='none'; Codehighlighter1_617_2477_Open_Text.style.display='none'; Codehighlighter1_617_2477_Closed_Image.style.display='inline'; Codehighlighter1_617_2477_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_617_2477_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_617_2477_Closed_Text.style.display='none'; Codehighlighter1_617_2477_Open_Image.style.display='inline'; Codehighlighter1_617_2477_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_617_2477_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_617_2477_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">namespace</span><span style="color: #000000">&nbsp;boost;<br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" /><br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">形式1:&nbsp;带协议名,服务器为名称,不带端口号</span><span style="color: #008000"><br />
</span><span style="color: #008080">13</span><span style="color: #008000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;ret;<br />
</span><span style="color: #008080">14</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;text&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">http://www.cppblog.com/qinqing1984</span><span style="color: #000000">"</span><span style="color: #000000">;<br />
</span><span style="color: #008080">15</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;boost::cmatch&nbsp;what;<br />
</span><span style="color: #008080">16</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;ret</span><span style="color: #000000">=</span><span style="color: #000000">boost_match(pattern.c_str(),text.c_str(),regex::icase</span><span style="color: #000000">|</span><span style="color: #000000">regex::perl,</span><span style="color: #000000">&amp;</span><span style="color: #000000">what);<br />
</span><span style="color: #008080">17</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(ret);<br />
</span><span style="color: #008080">18</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(what[</span><span style="color: #000000">1</span><span style="color: #000000">].str()</span><span style="color: #000000">==</span><span style="color: #000000">"</span><span style="color: #000000">http</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
</span><span style="color: #008080">19</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(what[</span><span style="color: #000000">2</span><span style="color: #000000">].str()</span><span style="color: #000000">==</span><span style="color: #000000">"</span><span style="color: #000000">www.cppblog.com</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
</span><span style="color: #008080">20</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(what[</span><span style="color: #000000">3</span><span style="color: #000000">].str()</span><span style="color: #000000">==</span><span style="color: #000000">""</span><span style="color: #000000">);<br />
</span><span style="color: #008080">21</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(what[</span><span style="color: #000000">4</span><span style="color: #000000">].str()</span><span style="color: #000000">==</span><span style="color: #000000">"</span><span style="color: #000000">/qinqing1984</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
</span><span style="color: #008080">22</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" /><br />
</span><span style="color: #008080">23</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">形式2:&nbsp;不带协议名,服务器为名称,带端口号</span><span style="color: #008000"><br />
</span><span style="color: #008080">24</span><span style="color: #008000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;text&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">www.cppblog.com:80/qinqing1984</span><span style="color: #000000">"</span><span style="color: #000000">;<br />
</span><span style="color: #008080">25</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;ret</span><span style="color: #000000">=</span><span style="color: #000000">boost_match(pattern.c_str(),text.c_str(),regex::icase</span><span style="color: #000000">|</span><span style="color: #000000">regex::perl,</span><span style="color: #000000">&amp;</span><span style="color: #000000">what);<br />
</span><span style="color: #008080">26</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(ret);<br />
</span><span style="color: #008080">27</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(what[</span><span style="color: #000000">1</span><span style="color: #000000">].str()</span><span style="color: #000000">==</span><span style="color: #000000">""</span><span style="color: #000000">);<br />
</span><span style="color: #008080">28</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(what[</span><span style="color: #000000">2</span><span style="color: #000000">].str()</span><span style="color: #000000">==</span><span style="color: #000000">"</span><span style="color: #000000">www.cppblog.com</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
</span><span style="color: #008080">29</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(what[</span><span style="color: #000000">3</span><span style="color: #000000">].str()</span><span style="color: #000000">==</span><span style="color: #000000">"</span><span style="color: #000000">80</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
</span><span style="color: #008080">30</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(what[</span><span style="color: #000000">4</span><span style="color: #000000">].str()</span><span style="color: #000000">==</span><span style="color: #000000">"</span><span style="color: #000000">/qinqing1984</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
</span><span style="color: #008080">31</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" /><br />
</span><span style="color: #008080">32</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">形式3:&nbsp;不带协议名,服务器为名称,不带路径</span><span style="color: #008000"><br />
</span><span style="color: #008080">33</span><span style="color: #008000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;text&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">www.cppblog.com:80</span><span style="color: #000000">"</span><span style="color: #000000">;<br />
</span><span style="color: #008080">34</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;ret</span><span style="color: #000000">=</span><span style="color: #000000">boost_match(pattern.c_str(),text.c_str(),regex::icase</span><span style="color: #000000">|</span><span style="color: #000000">regex::perl,</span><span style="color: #000000">&amp;</span><span style="color: #000000">what);<br />
</span><span style="color: #008080">35</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(ret);<br />
</span><span style="color: #008080">36</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(what[</span><span style="color: #000000">1</span><span style="color: #000000">].str()</span><span style="color: #000000">==</span><span style="color: #000000">""</span><span style="color: #000000">);<br />
</span><span style="color: #008080">37</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(what[</span><span style="color: #000000">2</span><span style="color: #000000">].str()</span><span style="color: #000000">==</span><span style="color: #000000">"</span><span style="color: #000000">www.cppblog.com</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
</span><span style="color: #008080">38</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(what[</span><span style="color: #000000">3</span><span style="color: #000000">].str()</span><span style="color: #000000">==</span><span style="color: #000000">"</span><span style="color: #000000">80</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
</span><span style="color: #008080">39</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(what[</span><span style="color: #000000">4</span><span style="color: #000000">].str()</span><span style="color: #000000">==</span><span style="color: #000000">""</span><span style="color: #000000">);<br />
</span><span style="color: #008080">40</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" /><br />
</span><span style="color: #008080">41</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">形式4:&nbsp;协议为https,服务器为IP,带端口号</span><span style="color: #008000"><br />
</span><span style="color: #008080">42</span><span style="color: #008000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;text&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">https://192.168.1.1:443/index.html</span><span style="color: #000000">"</span><span style="color: #000000">;<br />
</span><span style="color: #008080">43</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;ret</span><span style="color: #000000">=</span><span style="color: #000000">boost_match(pattern.c_str(),text.c_str(),regex::icase</span><span style="color: #000000">|</span><span style="color: #000000">regex::perl,</span><span style="color: #000000">&amp;</span><span style="color: #000000">what);<br />
</span><span style="color: #008080">44</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(ret);<br />
</span><span style="color: #008080">45</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(what[</span><span style="color: #000000">1</span><span style="color: #000000">].str()</span><span style="color: #000000">==</span><span style="color: #000000">"</span><span style="color: #000000">https</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
</span><span style="color: #008080">46</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(what[</span><span style="color: #000000">2</span><span style="color: #000000">].str()</span><span style="color: #000000">==</span><span style="color: #000000">"</span><span style="color: #000000">192.168.1.1</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
</span><span style="color: #008080">47</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(what[</span><span style="color: #000000">3</span><span style="color: #000000">].str()</span><span style="color: #000000">==</span><span style="color: #000000">"</span><span style="color: #000000">443</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
</span><span style="color: #008080">48</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(what[</span><span style="color: #000000">4</span><span style="color: #000000">].str()</span><span style="color: #000000">==</span><span style="color: #000000">"</span><span style="color: #000000">/index.html</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
</span><span style="color: #008080">49</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" /><br />
</span><span style="color: #008080">50</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">形式5:&nbsp;端口超过5位数</span><span style="color: #008000"><br />
</span><span style="color: #008080">51</span><span style="color: #008000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;text&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">ftp://192.168.1.1:888888</span><span style="color: #000000">"</span><span style="color: #000000">;<br />
</span><span style="color: #008080">52</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;ret</span><span style="color: #000000">=</span><span style="color: #000000">boost_match(pattern.c_str(),text.c_str(),regex::icase</span><span style="color: #000000">|</span><span style="color: #000000">regex::perl,</span><span style="color: #000000">&amp;</span><span style="color: #000000">what);<br />
</span><span style="color: #008080">53</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(</span><span style="color: #000000">!</span><span style="color: #000000">ret);<br />
</span><span style="color: #008080">54</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" /><br />
</span><span style="color: #008080">55</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">形式6:&nbsp;没有协议名</span><span style="color: #008000"><br />
</span><span style="color: #008080">56</span><span style="color: #008000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;text&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">//192.168.1.1/index.html</span><span style="color: #000000">"</span><span style="color: #000000">;<br />
</span><span style="color: #008080">57</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;ret</span><span style="color: #000000">=</span><span style="color: #000000">boost_match(pattern.c_str(),text.c_str(),regex::icase</span><span style="color: #000000">|</span><span style="color: #000000">regex::perl,</span><span style="color: #000000">&amp;</span><span style="color: #000000">what);<br />
</span><span style="color: #008080">58</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(</span><span style="color: #000000">!</span><span style="color: #000000">ret);<br />
</span><span style="color: #008080">59</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" /><br />
</span><span style="color: #008080">60</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">形式7:&nbsp;没有服务器</span><span style="color: #008000"><br />
</span><span style="color: #008080">61</span><span style="color: #008000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;text&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">http:///index.html</span><span style="color: #000000">"</span><span style="color: #000000">;<br />
</span><span style="color: #008080">62</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;ret</span><span style="color: #000000">=</span><span style="color: #000000">boost_match(pattern.c_str(),text.c_str(),regex::icase</span><span style="color: #000000">|</span><span style="color: #000000">regex::perl,</span><span style="color: #000000">&amp;</span><span style="color: #000000">what);<br />
</span><span style="color: #008080">63</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(</span><span style="color: #000000">!</span><span style="color: #000000">ret);<br />
</span><span style="color: #008080">64</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" /><br />
</span><span style="color: #008080">65</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">形式8:&nbsp;不合法的服务器</span><span style="color: #008000"><br />
</span><span style="color: #008080">66</span><span style="color: #008000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;text&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">cppblog/index.html</span><span style="color: #000000">"</span><span style="color: #000000">;<br />
</span><span style="color: #008080">67</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;ret</span><span style="color: #000000">=</span><span style="color: #000000">boost_match(pattern.c_str(),text.c_str(),regex::icase</span><span style="color: #000000">|</span><span style="color: #000000">regex::perl,</span><span style="color: #000000">&amp;</span><span style="color: #000000">what);<br />
</span><span style="color: #008080">68</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;assert(</span><span style="color: #000000">!</span><span style="color: #000000">ret);<br />
</span><span style="color: #008080">69</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" /><br />
</span><span style="color: #008080">70</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />
</span><span style="color: #008080">71</span><span style="color: #000000"><img align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" alt="" />}</span></span></div>
</div>
</div>
&nbsp;&nbsp;&nbsp;对URL的解析，因时间有限，本文所述不尽详细，只是略作分析，以点带面，更多的精确匹配则依赖于实际的应用需求。<img src ="http://www.cppblog.com/qinqing1984/aggbug/161035.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qinqing1984/" target="_blank">春秋十二月</a> 2011-11-27 17:22 <a href="http://www.cppblog.com/qinqing1984/archive/2011/11/27/161035.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于stl序列容器实现的通用集合类 (线程安全版)</title><link>http://www.cppblog.com/qinqing1984/archive/2011/10/21/158841.html</link><dc:creator>春秋十二月</dc:creator><author>春秋十二月</author><pubDate>Fri, 21 Oct 2011 10:43:00 GMT</pubDate><guid>http://www.cppblog.com/qinqing1984/archive/2011/10/21/158841.html</guid><wfw:comment>http://www.cppblog.com/qinqing1984/comments/158841.html</wfw:comment><comments>http://www.cppblog.com/qinqing1984/archive/2011/10/21/158841.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/qinqing1984/comments/commentRss/158841.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qinqing1984/services/trackbacks/158841.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp;在《基于stl序列容器实现的通用集合类》一文中，已经讲到了具体实现，近来因再次用到它又改进完善了，主要体现在以下几点：1）增加了查找操作方法，支持按值类型和谓词条件两种方式。2）增加重载了按值类型和谓词条件2种方式删除元素的方法。3）增加了2个模板参数以支持线程安全，一个是线程模型模板类，一个是互斥锁类，使用loki库来实现，因此所有方法现在都是线程安全的，当需...&nbsp;&nbsp;<a href='http://www.cppblog.com/qinqing1984/archive/2011/10/21/158841.html'>阅读全文</a><img src ="http://www.cppblog.com/qinqing1984/aggbug/158841.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qinqing1984/" target="_blank">春秋十二月</a> 2011-10-21 18:43 <a href="http://www.cppblog.com/qinqing1984/archive/2011/10/21/158841.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于stl序列容器实现的通用集合类</title><link>http://www.cppblog.com/qinqing1984/archive/2011/07/16/151151.html</link><dc:creator>春秋十二月</dc:creator><author>春秋十二月</author><pubDate>Sat, 16 Jul 2011 04:23:00 GMT</pubDate><guid>http://www.cppblog.com/qinqing1984/archive/2011/07/16/151151.html</guid><wfw:comment>http://www.cppblog.com/qinqing1984/comments/151151.html</wfw:comment><comments>http://www.cppblog.com/qinqing1984/archive/2011/07/16/151151.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/qinqing1984/comments/commentRss/151151.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qinqing1984/services/trackbacks/151151.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp;在面向对象开发时，对实际问题分析进而抽象出一种类型，往往会考虑到2个方面：1）类型的内部成员和方法的定义描述 2）类型的多实例存取操作。其中第1点是类型本身数据结构的设计，第2点是类型容器数据结构的选择设计。在stl中，容器有序列式和关联式两种，前者代表有vector，list，deque等；后者代表有set，multiset，map，multimap等，对于一...&nbsp;&nbsp;<a href='http://www.cppblog.com/qinqing1984/archive/2011/07/16/151151.html'>阅读全文</a><img src ="http://www.cppblog.com/qinqing1984/aggbug/151151.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qinqing1984/" target="_blank">春秋十二月</a> 2011-07-16 12:23 <a href="http://www.cppblog.com/qinqing1984/archive/2011/07/16/151151.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>空基类优化EBO之深度探索</title><link>http://www.cppblog.com/qinqing1984/archive/2011/07/10/150584.html</link><dc:creator>春秋十二月</dc:creator><author>春秋十二月</author><pubDate>Sun, 10 Jul 2011 04:58:00 GMT</pubDate><guid>http://www.cppblog.com/qinqing1984/archive/2011/07/10/150584.html</guid><wfw:comment>http://www.cppblog.com/qinqing1984/comments/150584.html</wfw:comment><comments>http://www.cppblog.com/qinqing1984/archive/2011/07/10/150584.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/qinqing1984/comments/commentRss/150584.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qinqing1984/services/trackbacks/150584.html</trackback:ping><description><![CDATA[<strong style="font-size: 12pt">继承情景</strong><br />
&nbsp;&nbsp;&nbsp;我们知道一个空的类，也就是其内部没有非静态数据成员，没有虚指针（包括指向虚函数表和虚基类子对象的指针），它的大小通常为1，当然在某些对齐要求严格系统上可能是另一个数（通常是4），如果空类被继承，那么派生类的大小会怎么样呢？一个支持C++标准和EBO的编译器对此会进行空基类的优化，也就是不给空的基类子对象分配空间，换句话说，空基类子对象的地址和其派生类实例的地址是相同的。从编译器实现的角度来看，需要考虑继承时的不同情况，下图中P表示父类，C表示子类，圆形表示空类，矩形表示非空类。单继承EBO情况如下图所示
<div align="center"><img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/qinqing1984/s_ebo_inherit_ex_2.JPG" width="461" height="260" /></div>
&nbsp;&nbsp; EBO-1反映的是空类派生自空基类，EBO-2反映的是非空类派生自空基类，EBO-3、EBO-4反映的是在继承链中，对空基类的优化能不能传递到后代中。多继承EBO如下图所示<br />
<div align="center"><img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/qinqing1984/m_ebo_inherit_ex_1.JPG" width="655" height="157" /></div>
&nbsp;&nbsp;&nbsp;EBO-5反映的是空类派生自两个空基类，EBO-6反映的是非空类派生自两个空基类，EBO-6反映的是空类派生自一个非空基类和一个空基类，EBO-7反映的是非空类派生自一个非空基类和一个空基类。以上8种情况，不论是单继承还是多继承，一个完全支持EBO的编译器就应该能把空基类部分都优化掉。<br />
<br />
<strong style="font-size: 12pt">优化应用</strong><br />
&nbsp;&nbsp;&nbsp;<span>由于空基类优化技术节省了对象不必要的空间，提高了运行效率，因此成为某些强大技术的基石，基于类型定义类如stl中的binary_function、unary_function、iterator、iterator_traits的实现复用；基于策略类如内存管理、多线程安全同步的实现复用。当某个类存在空类类型的数据成员时，也可考虑借助EBO优化对象布局，例如下
<div align="center">
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px">
<div align="left"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080; font-size: 10pt">1</span><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #000000; font-size: 10pt">template</span><span style="color: #000000; font-size: 10pt">&lt;</span><span style="color: #000000; font-size: 10pt">typename&nbsp;T1,typename&nbsp;T2</span><span style="color: #000000; font-size: 10pt">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080; font-size: 10pt">2</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff; font-size: 10pt">class</span><span style="color: #000000; font-size: 10pt">&nbsp;EBO<br />
</span><span style="color: #008080; font-size: 10pt">3</span><span style="color: #000000"><img id="Codehighlighter1_44_75_Open_Image" onclick="this.style.display='none'; Codehighlighter1_44_75_Open_Text.style.display='none'; Codehighlighter1_44_75_Closed_Image.style.display='inline'; Codehighlighter1_44_75_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_44_75_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_44_75_Closed_Text.style.display='none'; Codehighlighter1_44_75_Open_Image.style.display='inline'; Codehighlighter1_44_75_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_44_75_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_44_75_Open_Text"><span style="color: #000000; font-size: 10pt">{<br />
</span><span style="color: #008080; font-size: 10pt">4</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #0000ff; font-size: 10pt">private</span><span style="color: #000000; font-size: 10pt">:<br />
</span><span style="color: #008080; font-size: 10pt">5</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000; font-size: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;T1&nbsp;m_t1;<br />
</span><span style="color: #008080; font-size: 10pt">6</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000; font-size: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;T2&nbsp;m_t2;<br />
</span><span style="color: #008080; font-size: 10pt">7</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" /></span><span style="color: #000000; font-size: 10pt">}</span></span><span style="color: #000000; font-size: 10pt">;</span></div>
</div>
</div>
</span>&nbsp; &nbsp;<span>当T1和T2为空类时，可以改进如下</span><br />
<span></span><span>
<div align="center">
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px">
<div align="left"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080">1</span><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #000000">template</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T1,typename&nbsp;T2</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">2</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;EBO&nbsp;:&nbsp;T1,&nbsp;T2<br />
</span><span style="color: #008080">3</span><span style="color: #000000"><img id="Codehighlighter1_53_55_Open_Image" onclick="this.style.display='none'; Codehighlighter1_53_55_Open_Text.style.display='none'; Codehighlighter1_53_55_Closed_Image.style.display='inline'; Codehighlighter1_53_55_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_53_55_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_53_55_Closed_Text.style.display='none'; Codehighlighter1_53_55_Open_Image.style.display='inline'; Codehighlighter1_53_55_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_53_55_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_53_55_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">4</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000">;</span></div>
</div>
</div>
</span>&nbsp; &nbsp;<br />
&nbsp;&nbsp;&nbsp;<span>更进一步，如果T1或T2为非类类型，如基本内建类型、函数指针等；或T1和T2类型相同时，则直接继承它们会导致编译错误，怎么办呢？这时可以添加一个中间层来解决，代码如下
<div align="center">
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px">
<div align="left"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080">&nbsp;1</span><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #000000">template</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T1,typename&nbsp;T2,</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;isSame,</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;isFirstEmpty,</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;isSecondEmpty</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;EBO_IMPL;<br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />template</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T1,typename&nbsp;T2</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;EBO_IMPL</span><span style="color: #000000">&lt;</span><span style="color: #000000">T1,T2,</span><span style="color: #0000ff">false</span><span style="color: #000000">,</span><span style="color: #0000ff">false</span><span style="color: #000000">,</span><span style="color: #0000ff">false</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img id="Codehighlighter1_175_197_Open_Image" onclick="this.style.display='none'; Codehighlighter1_175_197_Open_Text.style.display='none'; Codehighlighter1_175_197_Closed_Image.style.display='inline'; Codehighlighter1_175_197_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_175_197_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_175_197_Closed_Text.style.display='none'; Codehighlighter1_175_197_Open_Image.style.display='inline'; Codehighlighter1_175_197_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_175_197_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_175_197_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;T1&nbsp;m_t1;<br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;T2&nbsp;m_t2;<br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000">;<br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />template</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T1,typename&nbsp;T2</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;EBO_IMPL</span><span style="color: #000000">&lt;</span><span style="color: #000000">T1,T2,</span><span style="color: #0000ff">false</span><span style="color: #000000">,</span><span style="color: #0000ff">true</span><span style="color: #000000">,</span><span style="color: #0000ff">true</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;:&nbsp;T1,T2<br />
</span><span style="color: #008080">13</span><span style="color: #000000"><img id="Codehighlighter1_281_283_Open_Image" onclick="this.style.display='none'; Codehighlighter1_281_283_Open_Text.style.display='none'; Codehighlighter1_281_283_Closed_Image.style.display='inline'; Codehighlighter1_281_283_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_281_283_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_281_283_Closed_Text.style.display='none'; Codehighlighter1_281_283_Open_Image.style.display='inline'; Codehighlighter1_281_283_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_281_283_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_281_283_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">14</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000">;<br />
</span><span style="color: #008080">15</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br />
</span><span style="color: #008080">16</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />template</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T1,typename&nbsp;T2</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">17</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;EBO_IMPL</span><span style="color: #000000">&lt;</span><span style="color: #000000">T1,T2,</span><span style="color: #0000ff">false</span><span style="color: #000000">,</span><span style="color: #0000ff">true</span><span style="color: #000000">,</span><span style="color: #0000ff">false</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;:&nbsp;T1<br />
</span><span style="color: #008080">18</span><span style="color: #000000"><img id="Codehighlighter1_365_377_Open_Image" onclick="this.style.display='none'; Codehighlighter1_365_377_Open_Text.style.display='none'; Codehighlighter1_365_377_Closed_Image.style.display='inline'; Codehighlighter1_365_377_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_365_377_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_365_377_Closed_Text.style.display='none'; Codehighlighter1_365_377_Open_Image.style.display='inline'; Codehighlighter1_365_377_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_365_377_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_365_377_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">19</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;T2&nbsp;m_t2;<br />
</span><span style="color: #008080">20</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000">;<br />
</span><span style="color: #008080">21</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br />
</span><span style="color: #008080">22</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />template</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T1,typename&nbsp;T2</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">23</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;EBO_IMPL</span><span style="color: #000000">&lt;</span><span style="color: #000000">T1,T2,</span><span style="color: #0000ff">false</span><span style="color: #000000">,</span><span style="color: #0000ff">false</span><span style="color: #000000">,</span><span style="color: #0000ff">true</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;:&nbsp;T2<br />
</span><span style="color: #008080">24</span><span style="color: #000000"><img id="Codehighlighter1_459_471_Open_Image" onclick="this.style.display='none'; Codehighlighter1_459_471_Open_Text.style.display='none'; Codehighlighter1_459_471_Closed_Image.style.display='inline'; Codehighlighter1_459_471_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_459_471_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_459_471_Closed_Text.style.display='none'; Codehighlighter1_459_471_Open_Image.style.display='inline'; Codehighlighter1_459_471_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_459_471_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_459_471_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">25</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;T1&nbsp;m_t1;<br />
</span><span style="color: #008080">26</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000">;<br />
</span><span style="color: #008080">27</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br />
</span><span style="color: #008080">28</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />template</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T1,typename&nbsp;T2</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">29</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;EBO_IMPL</span><span style="color: #000000">&lt;</span><span style="color: #000000">T1,T2,</span><span style="color: #0000ff">true</span><span style="color: #000000">,</span><span style="color: #0000ff">false</span><span style="color: #000000">,</span><span style="color: #0000ff">false</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">30</span><span style="color: #000000"><img id="Codehighlighter1_548_570_Open_Image" onclick="this.style.display='none'; Codehighlighter1_548_570_Open_Text.style.display='none'; Codehighlighter1_548_570_Closed_Image.style.display='inline'; Codehighlighter1_548_570_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_548_570_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_548_570_Closed_Text.style.display='none'; Codehighlighter1_548_570_Open_Image.style.display='inline'; Codehighlighter1_548_570_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_548_570_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_548_570_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">31</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;T1&nbsp;m_t1;<br />
</span><span style="color: #008080">32</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;T2&nbsp;m_t2;<br />
</span><span style="color: #008080">33</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000">;<br />
</span><span style="color: #008080">34</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br />
</span><span style="color: #008080">35</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />template</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T1,typename&nbsp;T2</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">36</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;EBO_IMPL</span><span style="color: #000000">&lt;</span><span style="color: #000000">T1,T2,</span><span style="color: #0000ff">true</span><span style="color: #000000">,</span><span style="color: #0000ff">true</span><span style="color: #000000">,</span><span style="color: #0000ff">true</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;:&nbsp;T1<br />
</span><span style="color: #008080">37</span><span style="color: #000000"><img id="Codehighlighter1_650_662_Open_Image" onclick="this.style.display='none'; Codehighlighter1_650_662_Open_Text.style.display='none'; Codehighlighter1_650_662_Closed_Image.style.display='inline'; Codehighlighter1_650_662_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_650_662_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_650_662_Closed_Text.style.display='none'; Codehighlighter1_650_662_Open_Image.style.display='inline'; Codehighlighter1_650_662_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_650_662_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_650_662_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">38</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;T2&nbsp;m_t2;<br />
</span><span style="color: #008080">39</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000">;<br />
</span><span style="color: #008080">40</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br />
</span><span style="color: #008080">41</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />template</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T1,typename&nbsp;T2</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">42</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;EBO&nbsp;:&nbsp;EBO_IMPL</span><span style="color: #000000">&lt;</span><span style="color: #000000">T1,T2,boost::is_same</span><span style="color: #000000">&lt;</span><span style="color: #000000">T1,T2</span><span style="color: #000000">&gt;</span><span style="color: #000000">::value,boost::is_empty</span><span style="color: #000000">&lt;</span><span style="color: #000000">T1</span><span style="color: #000000">&gt;</span><span style="color: #000000">::value,boost::is_empty</span><span style="color: #000000">&lt;</span><span style="color: #000000">T2</span><span style="color: #000000">&gt;</span><span style="color: #000000">::value</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">43</span><span style="color: #000000"><img id="Codehighlighter1_811_813_Open_Image" onclick="this.style.display='none'; Codehighlighter1_811_813_Open_Text.style.display='none'; Codehighlighter1_811_813_Closed_Image.style.display='inline'; Codehighlighter1_811_813_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_811_813_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_811_813_Closed_Text.style.display='none'; Codehighlighter1_811_813_Open_Image.style.display='inline'; Codehighlighter1_811_813_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_811_813_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_811_813_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">44</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000">;</span></div>
</div>
</div>
</span><span></span>
<div align="center"></div>
<span></span>
<div align="center"></div>
&nbsp;&nbsp;&nbsp;为了简便，直接使用了boost中的is_same，is_empty元函数来判断类型的属性，实际上boost中已经实现了EBO的选择运用工具即compressed_pair类模板，研究其源码可发现，该工具充分考虑到了T1和T2实际类型的各种情况，is_empty的判断是运用sizeof来比较类型大小确定的。替换compressed_pair后，代码如下
<div align="center">
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px">
<div align="left"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080">1</span><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" /><span style="color: #000000">template</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T1,typename&nbsp;T2</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">2</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;EBO:&nbsp;boost::compressed_pair</span><span style="color: #000000">&lt;</span><span style="color: #000000">T1,T2</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">3</span><span style="color: #000000"><img id="Codehighlighter1_75_77_Open_Image" onclick="this.style.display='none'; Codehighlighter1_75_77_Open_Text.style.display='none'; Codehighlighter1_75_77_Closed_Image.style.display='inline'; Codehighlighter1_75_77_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_75_77_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_75_77_Closed_Text.style.display='none'; Codehighlighter1_75_77_Open_Image.style.display='inline'; Codehighlighter1_75_77_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_75_77_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_75_77_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">4</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000">;</span></div>
</div>
</div><img src ="http://www.cppblog.com/qinqing1984/aggbug/150584.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qinqing1984/" target="_blank">春秋十二月</a> 2011-07-10 12:58 <a href="http://www.cppblog.com/qinqing1984/archive/2011/07/10/150584.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>删除vector容器内的重复元素</title><link>http://www.cppblog.com/qinqing1984/archive/2011/06/25/149432.html</link><dc:creator>春秋十二月</dc:creator><author>春秋十二月</author><pubDate>Sat, 25 Jun 2011 06:49:00 GMT</pubDate><guid>http://www.cppblog.com/qinqing1984/archive/2011/06/25/149432.html</guid><wfw:comment>http://www.cppblog.com/qinqing1984/comments/149432.html</wfw:comment><comments>http://www.cppblog.com/qinqing1984/archive/2011/06/25/149432.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/qinqing1984/comments/commentRss/149432.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qinqing1984/services/trackbacks/149432.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;原题为某著名软件公司的试题，大意如下：给定一个容器，要求删除容器中重复的元素，并保持剩余元素的顺序不变。在这里，本文为了全面通用考虑，作了扩展，删除vector中的重复元素，从容器中元素顺序上可分为2种情形：1）保持剩余元素顺序不变，特称为稳定删除，对应下面的stable_unique版本函数模板 2）不考虑顺序变化，特称为快速删除。对应下面的quick_unique版本函数模板。从重复的概念定义也可分为2种情况：1）基于简单的相等判断 2）基于谓词的等价判断。因此，由排列组合得知应该有4种版本的实现，下面给出代码描述
<div align="center">
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 97.14%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px">
<div align="left"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080">&nbsp;1</span><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #008000">//</span><span style="color: #008000">函数对象模板类</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #008000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #000000">template</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;Predicate<br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img id="Codehighlighter1_48_295_Open_Image" onclick="this.style.display='none'; Codehighlighter1_48_295_Open_Text.style.display='none'; Codehighlighter1_48_295_Closed_Image.style.display='inline'; Codehighlighter1_48_295_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_48_295_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_48_295_Closed_Text.style.display='none'; Codehighlighter1_48_295_Open_Image.style.display='inline'; Codehighlighter1_48_295_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_48_295_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_48_295_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;Predicate()<br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img id="Codehighlighter1_64_67_Open_Image" onclick="this.style.display='none'; Codehighlighter1_64_67_Open_Text.style.display='none'; Codehighlighter1_64_67_Closed_Image.style.display='inline'; Codehighlighter1_64_67_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_64_67_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_64_67_Closed_Text.style.display='none'; Codehighlighter1_64_67_Open_Image.style.display='inline'; Codehighlighter1_64_67_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_64_67_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_64_67_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /><br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;Predicate(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;T</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;t)<br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:_t(t)<br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img id="Codehighlighter1_103_106_Open_Image" onclick="this.style.display='none'; Codehighlighter1_103_106_Open_Text.style.display='none'; Codehighlighter1_103_106_Closed_Image.style.display='inline'; Codehighlighter1_103_106_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_103_106_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_103_106_Closed_Text.style.display='none'; Codehighlighter1_103_106_Open_Image.style.display='inline'; Codehighlighter1_103_106_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_103_106_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_103_106_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #000000"><br />
</span><span style="color: #008080">13</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">operator</span><span style="color: #000000">()(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;T</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;t)&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000"><br />
</span><span style="color: #008080">14</span><span style="color: #000000"><img id="Codehighlighter1_144_179_Open_Image" onclick="this.style.display='none'; Codehighlighter1_144_179_Open_Text.style.display='none'; Codehighlighter1_144_179_Closed_Image.style.display='inline'; Codehighlighter1_144_179_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_144_179_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_144_179_Closed_Text.style.display='none'; Codehighlighter1_144_179_Open_Image.style.display='inline'; Codehighlighter1_144_179_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_144_179_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_144_179_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">15</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">可以自定义比较实现</span><span style="color: #008000"><br />
</span><span style="color: #008080">16</span><span style="color: #008000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;_t&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;t;<br />
</span><span style="color: #008080">17</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #000000"><br />
</span><span style="color: #008080">18</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">支持std::unique谓词版本的删除</span><span style="color: #008000"><br />
</span><span style="color: #008080">19</span><span style="color: #008000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">operator</span><span style="color: #000000">()(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;T</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;l,</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;T</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;r)&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000"><br />
</span><span style="color: #008080">20</span><span style="color: #000000"><img id="Codehighlighter1_252_286_Open_Image" onclick="this.style.display='none'; Codehighlighter1_252_286_Open_Text.style.display='none'; Codehighlighter1_252_286_Closed_Image.style.display='inline'; Codehighlighter1_252_286_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_252_286_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_252_286_Closed_Text.style.display='none'; Codehighlighter1_252_286_Open_Image.style.display='inline'; Codehighlighter1_252_286_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_252_286_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_252_286_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">21</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">可以自定义比较实现</span><span style="color: #008000"><br />
</span><span style="color: #008080">22</span><span style="color: #008000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;l&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;r;<br />
</span><span style="color: #008080">23</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">24</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;_t;<br />
</span><span style="color: #008080">25</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000">;<br />
</span><span style="color: #008080">26</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br />
</span><span style="color: #008080">27</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #008000">//</span><span style="color: #008000">quick_unique版本1:&nbsp;相等判断</span><span style="color: #008000"><br />
</span><span style="color: #008080">28</span><span style="color: #008000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #000000">template</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">29</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;quick_unique(std::vector</span><span style="color: #000000">&lt;</span><span style="color: #000000">T</span><span style="color: #000000">&gt;&amp;</span><span style="color: #000000">&nbsp;con)<br />
</span><span style="color: #008080">30</span><span style="color: #000000"><img id="Codehighlighter1_383_478_Open_Image" onclick="this.style.display='none'; Codehighlighter1_383_478_Open_Text.style.display='none'; Codehighlighter1_383_478_Closed_Image.style.display='inline'; Codehighlighter1_383_478_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_383_478_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_383_478_Closed_Text.style.display='none'; Codehighlighter1_383_478_Open_Image.style.display='inline'; Codehighlighter1_383_478_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_383_478_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_383_478_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">31</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;std::sort(con.begin(),con.end());<br />
</span><span style="color: #008080">32</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;con.erase(std::unique(con.begin(),con.end()),con.end());<br />
</span><span style="color: #008080">33</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">34</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br />
</span><span style="color: #008080">35</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #008000">//</span><span style="color: #008000">quick_unique版本2:&nbsp;谓词判断</span><span style="color: #008000"><br />
</span><span style="color: #008080">36</span><span style="color: #008000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #000000">template</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T,template&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;U</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Predicate</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">37</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;quick_unique(std::vector</span><span style="color: #000000">&lt;</span><span style="color: #000000">T</span><span style="color: #000000">&gt;&amp;</span><span style="color: #000000">&nbsp;con)<br />
</span><span style="color: #008080">38</span><span style="color: #000000"><img id="Codehighlighter1_603_713_Open_Image" onclick="this.style.display='none'; Codehighlighter1_603_713_Open_Text.style.display='none'; Codehighlighter1_603_713_Closed_Image.style.display='inline'; Codehighlighter1_603_713_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_603_713_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_603_713_Closed_Text.style.display='none'; Codehighlighter1_603_713_Open_Image.style.display='inline'; Codehighlighter1_603_713_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_603_713_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_603_713_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">39</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;std::sort(con.begin(),con.end());<br />
</span><span style="color: #008080">40</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span>&nbsp;&nbsp;&nbsp;&nbsp;con.erase(std::unique(con.begin(),con.end(),Predicate<span style="color: #000000">&lt;</span><span style="color: #000000">T</span><span style="color: #000000">&gt;</span><span style="color: #000000">()),con.end());<br />
</span><span style="color: #008080">41</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span><span style="color: #000000"><br />
</span><span style="color: #008080">42</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br />
</span><span style="color: #008080">43</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #008000">//</span><span style="color: #008000">stable_unique版本1:&nbsp;相等判断</span><span style="color: #008000"><br />
</span><span style="color: #008080">44</span><span style="color: #008000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #000000">template</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">45</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;stable_unique(std::vector</span><span style="color: #000000">&lt;</span><span style="color: #000000">T</span><span style="color: #000000">&gt;&amp;</span><span style="color: #000000">&nbsp;con)<br />
</span><span style="color: #008080">46</span><span style="color: #000000"><img id="Codehighlighter1_802_985_Open_Image" onclick="this.style.display='none'; Codehighlighter1_802_985_Open_Text.style.display='none'; Codehighlighter1_802_985_Closed_Image.style.display='inline'; Codehighlighter1_802_985_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_802_985_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_802_985_Closed_Text.style.display='none'; Codehighlighter1_802_985_Open_Image.style.display='inline'; Codehighlighter1_802_985_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_802_985_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_802_985_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">47</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;std::vector</span><span style="color: #000000">&lt;</span><span style="color: #000000">T</span><span style="color: #000000">&gt;</span><span style="color: #000000">::iterator&nbsp;it,ret,beg&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;con.begin();<br />
</span><span style="color: #008080">48</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(it&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">con.begin();it</span><span style="color: #000000">!=</span><span style="color: #000000">con.end();)<br />
</span><span style="color: #008080">49</span><span style="color: #000000"><img id="Codehighlighter1_898_983_Open_Image" onclick="this.style.display='none'; Codehighlighter1_898_983_Open_Text.style.display='none'; Codehighlighter1_898_983_Closed_Image.style.display='inline'; Codehighlighter1_898_983_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_898_983_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_898_983_Closed_Text.style.display='none'; Codehighlighter1_898_983_Open_Image.style.display='inline'; Codehighlighter1_898_983_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_898_983_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_898_983_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">50</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;find(beg,it,</span><span style="color: #000000">*</span><span style="color: #000000">it);<br />
</span><span style="color: #008080">51</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(ret&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;it)<br />
</span><span style="color: #008080">52</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;it&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;con.erase(it);<br />
</span><span style="color: #008080">53</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000"><br />
</span><span style="color: #008080">54</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">it;<br />
</span><span style="color: #008080">55</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #000000"><br />
</span><span style="color: #008080">56</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span><span style="color: #000000"><br />
</span><span style="color: #008080">57</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br />
</span><span style="color: #008080">58</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #008000">//</span><span style="color: #008000">stable_unique版本2:&nbsp;谓词判断</span><span style="color: #008000"><br />
</span><span style="color: #008080">59</span><span style="color: #008000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #000000">template</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T,template&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;U</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Predicate</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">60</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;stable_unique(std::vector</span><span style="color: #000000">&lt;</span><span style="color: #000000">T</span><span style="color: #000000">&gt;&amp;</span><span style="color: #000000">&nbsp;con)<br />
</span><span style="color: #008080">61</span><span style="color: #000000"><img id="Codehighlighter1_1112_1312_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1112_1312_Open_Text.style.display='none'; Codehighlighter1_1112_1312_Closed_Image.style.display='inline'; Codehighlighter1_1112_1312_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_1112_1312_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_1112_1312_Closed_Text.style.display='none'; Codehighlighter1_1112_1312_Open_Image.style.display='inline'; Codehighlighter1_1112_1312_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_1112_1312_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_1112_1312_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">62</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;std::vector</span><span style="color: #000000">&lt;</span><span style="color: #000000">T</span><span style="color: #000000">&gt;</span><span style="color: #000000">::iterator&nbsp;it,ret,beg&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;con.begin();<br />
</span><span style="color: #008080">63</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(it&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">con.begin();it</span><span style="color: #000000">!=</span><span style="color: #000000">con.end();)<br />
</span><span style="color: #008080">64</span><span style="color: #000000"><img id="Codehighlighter1_1208_1310_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1208_1310_Open_Text.style.display='none'; Codehighlighter1_1208_1310_Closed_Image.style.display='inline'; Codehighlighter1_1208_1310_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_1208_1310_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_1208_1310_Closed_Text.style.display='none'; Codehighlighter1_1208_1310_Open_Image.style.display='inline'; Codehighlighter1_1208_1310_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_1208_1310_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_1208_1310_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">65</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;find_if(beg,it,Predicate</span><span style="color: #000000">&lt;</span><span style="color: #000000">T</span><span style="color: #000000">&gt;</span><span style="color: #000000">(</span><span style="color: #000000">*</span><span style="color: #000000">it));<br />
</span><span style="color: #008080">66</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(ret&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;it)<br />
</span><span style="color: #008080">67</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;it&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;con.erase(it);<br />
</span><span style="color: #008080">68</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000"><br />
</span><span style="color: #008080">69</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">it;<br />
</span><span style="color: #008080">70</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #000000"><br />
</span><span style="color: #008080">71</span><span style="color: #000000"><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span></span></span></span></span></span></span></span></div>
</div>
</div>
&nbsp;&nbsp;&nbsp;以上代码在vc2005环境下编译测试通过，再进一步扩展，问题完全可以归类为删除某容器内重复元素，只要再加一个模板的模板参数即可template &lt;typename T&gt; class Conn;函数的形参类型变为std::Conn&lt;T&gt;就行了，但要注意的是不同平台下对应容器的erase实现所返回的迭代器可能有所差别，比如map要这样写才能在linux上正确工作：conn.erase(it++)。对于特殊的情况，可对以上4个函数作对应的重载（注意，函数模板没有特化的概念）来解决。<img src ="http://www.cppblog.com/qinqing1984/aggbug/149432.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qinqing1984/" target="_blank">春秋十二月</a> 2011-06-25 14:49 <a href="http://www.cppblog.com/qinqing1984/archive/2011/06/25/149432.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>浅谈ACE中的同步机制</title><link>http://www.cppblog.com/qinqing1984/archive/2009/04/02/78702.html</link><dc:creator>春秋十二月</dc:creator><author>春秋十二月</author><pubDate>Thu, 02 Apr 2009 08:33:00 GMT</pubDate><guid>http://www.cppblog.com/qinqing1984/archive/2009/04/02/78702.html</guid><wfw:comment>http://www.cppblog.com/qinqing1984/comments/78702.html</wfw:comment><comments>http://www.cppblog.com/qinqing1984/archive/2009/04/02/78702.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/qinqing1984/comments/commentRss/78702.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qinqing1984/services/trackbacks/78702.html</trackback:ping><description><![CDATA[<p style="font-size: 10pt"><span style="font-size: 10pt">&nbsp;&nbsp; ACE中的同步机制是轻量级高效的，它不同于MFC中的同步类，MFC中的同步类采用了类继承的方式，而ACE并没有用继承方式，各个不同的锁类是平行的关系，这些类支持相同的接口，即它们的所有公共方法是相同的，因此可被适配用于动态绑定和替换，这种动态绑定是没有虚函数调用开销的,且这些方法代码短小使用了内联实现。应用程序开发者可以通过指定模板实参来使用不同的锁，并可在运行时动态替换。</span></p>
<p style="font-size: 10pt"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp;ACE中的锁是易于使用的，既有互斥锁(ACE_Mutex)又有读写锁(ACE_RW_Mutex)，这些锁又细分为专门用于线程同步(ACE_Thread_Mutex,ACE_RW_Thread_Mutex)和进程(ACE_Process_Mutex,ACE_RW_Process_Mutex)同步的特定锁。相比MFC高级的是ACE中还提供了递归互斥体(ACE_Token)，可有效地用于某些递归例程。</span></p>
<p style="font-size: 10pt"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp;ACE中提供了ACE_Lock锁抽象基类和ACE_Adapter_Lock锁适配器模板类，ACE_Adapter_Lock从ACE_Lock继承，实现了动态绑定和替换。另外，ACE还提供了ACE_Atomic_Op模板类，重载了基本的算术运算符，实现了原子化算术运算。</span></p><img src ="http://www.cppblog.com/qinqing1984/aggbug/78702.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qinqing1984/" target="_blank">春秋十二月</a> 2009-04-02 16:33 <a href="http://www.cppblog.com/qinqing1984/archive/2009/04/02/78702.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>