﻿<?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++博客-aa19870406</title><link>http://www.cppblog.com/aa19870406/</link><description /><language>zh-cn</language><lastBuildDate>Sun, 19 Apr 2026 18:07:49 GMT</lastBuildDate><pubDate>Sun, 19 Apr 2026 18:07:49 GMT</pubDate><ttl>60</ttl><item><title>关于微信和QQ的一点思考</title><link>http://www.cppblog.com/aa19870406/archive/2012/08/28/188540.html</link><dc:creator>MrRightLeft</dc:creator><author>MrRightLeft</author><pubDate>Tue, 28 Aug 2012 10:24:00 GMT</pubDate><guid>http://www.cppblog.com/aa19870406/archive/2012/08/28/188540.html</guid><wfw:comment>http://www.cppblog.com/aa19870406/comments/188540.html</wfw:comment><comments>http://www.cppblog.com/aa19870406/archive/2012/08/28/188540.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.cppblog.com/aa19870406/comments/commentRss/188540.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aa19870406/services/trackbacks/188540.html</trackback:ping><description><![CDATA[<p style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 0px 0px 0.8em; letter-spacing: normal; font: 14px/21px Tahoma, Verdana, STHeiTi, simsun, sans-serif; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">微信要打败qq，如果仅仅局限于陌生人交友，是肯定不行的。所以现在微信会兼顾陌生人交友和熟人交友。因为陌生人交友的模式是调动大家猎奇、尝试新鲜的欲望，如果大家都想去&#8220;约炮&#8221;，但是又经常约不到，就会渐渐失去对它的好奇和新鲜刺激感，那么微信的发展就会遇到瓶颈。qq最大的优势在于它的用户关系链，用户关系链是强联系的，用户很难从它转到别处，当然现在微信的快速发展也是离不开qq的支持的，比如从qq导入好友到微信。所以qq被微信取代的可能性还不是很大，应该是互补的，两强并立。微信的火并不一定在于它的功能强大，或者创新（如摇一摇、漂流瓶），火的本质原因在于用户的&#8220;约炮&#8221;需求，这也是陌陌能异军突起的原因，而相比之下，米聊就后劲不足，因为它没有抓住这个本质需求。</p>
<p style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; margin: 0px 0px 0.8em; letter-spacing: normal; font: 14px/21px Tahoma, Verdana, STHeiTi, simsun, sans-serif; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">由于一开始大部分人的的&#8220;约炮&#8221;需求无法得到满足，继而对于陌生人交友工具的使用会由原来的原始&#8220;约炮&#8221;需求，进化为&#8220;结识新朋友&#8221;的需求，现代大部分人都花费大量时间在互联网上，与人接触的时间会比较少，剩男剩女、宅男宅女很多，这部分需求会比较大，也比较不那么原始。相信不久后会是这部分需求来主导陌生人交友工具的发展。</p>  <img src ="http://www.cppblog.com/aa19870406/aggbug/188540.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aa19870406/" target="_blank">MrRightLeft</a> 2012-08-28 18:24 <a href="http://www.cppblog.com/aa19870406/archive/2012/08/28/188540.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>redis源码剖析-main流程</title><link>http://www.cppblog.com/aa19870406/archive/2012/07/17/183875.html</link><dc:creator>MrRightLeft</dc:creator><author>MrRightLeft</author><pubDate>Tue, 17 Jul 2012 05:28:00 GMT</pubDate><guid>http://www.cppblog.com/aa19870406/archive/2012/07/17/183875.html</guid><wfw:comment>http://www.cppblog.com/aa19870406/comments/183875.html</wfw:comment><comments>http://www.cppblog.com/aa19870406/archive/2012/07/17/183875.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aa19870406/comments/commentRss/183875.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aa19870406/services/trackbacks/183875.html</trackback:ping><description><![CDATA[<div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; border-spacing: 0px; font-size: medium; ">一、redis运行流程<br />以下是redis main函数的运行流程<br /><br /></span><div><font face="Tahoma" size="3"><span style="line-height: normal;"><img src="http://www.cppblog.com/images/cppblog_com/aa19870406/redis.png" width="504" height="1074" alt="" /><br /></span></font></div></div><img src ="http://www.cppblog.com/aa19870406/aggbug/183875.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aa19870406/" target="_blank">MrRightLeft</a> 2012-07-17 13:28 <a href="http://www.cppblog.com/aa19870406/archive/2012/07/17/183875.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>socket accept()返回的socket描述符的端口和listen描述符端口是一样的吗？</title><link>http://www.cppblog.com/aa19870406/archive/2012/07/15/183595.html</link><dc:creator>MrRightLeft</dc:creator><author>MrRightLeft</author><pubDate>Sun, 15 Jul 2012 13:01:00 GMT</pubDate><guid>http://www.cppblog.com/aa19870406/archive/2012/07/15/183595.html</guid><wfw:comment>http://www.cppblog.com/aa19870406/comments/183595.html</wfw:comment><comments>http://www.cppblog.com/aa19870406/archive/2012/07/15/183595.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/aa19870406/comments/commentRss/183595.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aa19870406/services/trackbacks/183595.html</trackback:ping><description><![CDATA[as you know,一个socket是由一个五元组来唯一标示的，即(协议，server_ip, server_port, client_ip, client_port)。只要该五元组中任何一个值不同，则其代表的socket就不同。这里忽略协议的区别，在同一协议的基础上，服务器端的listen socket的端口可以看成(server_ip, server_port, ***, ***),其中***是通配符，它跟任何一个client_ip, client_port值都不同，可以简单看成是（0,0）对，当然实现不是这样的。这样在服务器端accept之后，返回的连接socket的四元组就是(server_ip, server_port, client_ip, client_port)，这里的client_ip，client_port因连接的客户端的不同而不同。所以accept返回的socket和listen socket是不同的，不同之处就在于四元组中的客户端ip和port，而服务器端的server_ip和server_port还是相同的，也就是accpet()函数返回的新的socket描述符的端口和listen端口是一样的。可以使用getsockname()函数来查看它们之间的不同。 <img src ="http://www.cppblog.com/aa19870406/aggbug/183595.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aa19870406/" target="_blank">MrRightLeft</a> 2012-07-15 21:01 <a href="http://www.cppblog.com/aa19870406/archive/2012/07/15/183595.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>同步io与异步io</title><link>http://www.cppblog.com/aa19870406/archive/2012/07/13/183189.html</link><dc:creator>MrRightLeft</dc:creator><author>MrRightLeft</author><pubDate>Fri, 13 Jul 2012 07:45:00 GMT</pubDate><guid>http://www.cppblog.com/aa19870406/archive/2012/07/13/183189.html</guid><wfw:comment>http://www.cppblog.com/aa19870406/comments/183189.html</wfw:comment><comments>http://www.cppblog.com/aa19870406/archive/2012/07/13/183189.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aa19870406/comments/commentRss/183189.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aa19870406/services/trackbacks/183189.html</trackback:ping><description><![CDATA[详见《unix网络编程 第1卷：套接口API》 p136<br />阻塞io模型、非阻塞io模型、I/O复用模型和信号驱动I/O模型都是同步io模型，因为其中真正的io操作将阻塞进程。只有异步I/O模型才是异步的<img src ="http://www.cppblog.com/aa19870406/aggbug/183189.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aa19870406/" target="_blank">MrRightLeft</a> 2012-07-13 15:45 <a href="http://www.cppblog.com/aa19870406/archive/2012/07/13/183189.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>socket close_on_exec</title><link>http://www.cppblog.com/aa19870406/archive/2012/07/13/183183.html</link><dc:creator>MrRightLeft</dc:creator><author>MrRightLeft</author><pubDate>Fri, 13 Jul 2012 07:08:00 GMT</pubDate><guid>http://www.cppblog.com/aa19870406/archive/2012/07/13/183183.html</guid><wfw:comment>http://www.cppblog.com/aa19870406/comments/183183.html</wfw:comment><comments>http://www.cppblog.com/aa19870406/archive/2012/07/13/183183.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aa19870406/comments/commentRss/183183.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aa19870406/services/trackbacks/183183.html</trackback:ping><description><![CDATA[<div style="text-align: center;"><span style="font-size: 24pt; ">socket close_on_exec<br /></span><span style="font-size: 24pt; "><br /></span></div>父进程fork子进程后，子进程会复制父进程的socket描述符。如果想让子进程在exec时，释放掉所拥有的父进程的socket描述符，可以设置父进程的socket&nbsp;close_on_exec特性。<br /><div style="text-align: left;"><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->&nbsp;<span style="color: #0000FF; ">if</span>(&nbsp;fcntl(iSockFd,&nbsp;F_GETFD,&nbsp;arg)&nbsp;&lt;&nbsp;0&nbsp;)&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;这个很重要，要不下面设置不成功&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;{<br />&nbsp; &nbsp; &nbsp; exit(-1);<br />&nbsp;}<br />&nbsp;<br />&nbsp;arg&nbsp;|=&nbsp;FD_CLOEXEC;<br />&nbsp;<br />&nbsp;<span style="color: #0000FF; ">if</span>(&nbsp;fcntl(iSockFd,&nbsp;F_SETFD,&nbsp;1)&nbsp;&lt;&nbsp;0&nbsp;)<br />&nbsp;{<br />&nbsp; &nbsp; &nbsp; exit(-1);<br />&nbsp;}</div><font color="#0000ff" face="monospace"><span style="font-size: 12px; line-height: 18px; white-space: pre;"><br /></span></font></div><img src ="http://www.cppblog.com/aa19870406/aggbug/183183.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aa19870406/" target="_blank">MrRightLeft</a> 2012-07-13 15:08 <a href="http://www.cppblog.com/aa19870406/archive/2012/07/13/183183.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SO_REUSEADDR</title><link>http://www.cppblog.com/aa19870406/archive/2012/07/12/183018.html</link><dc:creator>MrRightLeft</dc:creator><author>MrRightLeft</author><pubDate>Thu, 12 Jul 2012 09:16:00 GMT</pubDate><guid>http://www.cppblog.com/aa19870406/archive/2012/07/12/183018.html</guid><wfw:comment>http://www.cppblog.com/aa19870406/comments/183018.html</wfw:comment><comments>http://www.cppblog.com/aa19870406/archive/2012/07/12/183018.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aa19870406/comments/commentRss/183018.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aa19870406/services/trackbacks/183018.html</trackback:ping><description><![CDATA[<div style="text-align: center;"><span style="font-size: 24pt; ">SO_REUSEADDR<br /><br /></span></div>编写 TCP/SOCK_STREAM 服务程序时，SO_REUSEADDR到底什么意思？这个套接字选项通知内核，如果端口忙，但TCP状态位于 TIME_WAIT ，可以重用端口。如果端口忙，而TCP状态位于其他状态，重用端口时依旧得到一个错误信息，&nbsp;指明"地址已经使用中"。如果你的服务程序停止后想立即重启，而新套接字依旧使用同一端口，此时SO_REUSEADDR 选项非常有用。必须意识到，此时任何非期望数据到达，都可能导致服务程序反应混乱，不过这只是一种可能，事实上很不可能。&nbsp;<img src ="http://www.cppblog.com/aa19870406/aggbug/183018.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aa19870406/" target="_blank">MrRightLeft</a> 2012-07-12 17:16 <a href="http://www.cppblog.com/aa19870406/archive/2012/07/12/183018.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux 文件操作之close</title><link>http://www.cppblog.com/aa19870406/archive/2012/07/12/183010.html</link><dc:creator>MrRightLeft</dc:creator><author>MrRightLeft</author><pubDate>Thu, 12 Jul 2012 08:13:00 GMT</pubDate><guid>http://www.cppblog.com/aa19870406/archive/2012/07/12/183010.html</guid><wfw:comment>http://www.cppblog.com/aa19870406/comments/183010.html</wfw:comment><comments>http://www.cppblog.com/aa19870406/archive/2012/07/12/183010.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aa19870406/comments/commentRss/183010.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aa19870406/services/trackbacks/183010.html</trackback:ping><description><![CDATA[<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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #000000">#include&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">iostream</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />#include&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">fcntl.h</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">namespace</span><span style="color: #000000">&nbsp;std;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;main()<br /><img id="Codehighlighter1_72_349_Open_Image" onclick="this.style.display='none'; Codehighlighter1_72_349_Open_Text.style.display='none'; Codehighlighter1_72_349_Closed_Image.style.display='inline'; Codehighlighter1_72_349_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_72_349_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_72_349_Closed_Text.style.display='none'; Codehighlighter1_72_349_Open_Image.style.display='inline'; Codehighlighter1_72_349_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_72_349_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_72_349_Open_Text"><span style="color: #000000">{<br /><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;fd&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;open(</span><span style="color: #000000">"</span><span style="color: #000000">demo.txt</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;O_RDWR,&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">);<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;close(fd);<br /><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;fd1&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;open(</span><span style="color: #000000">"</span><span style="color: #000000">demo1.txt</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;O_RDWR,&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">);<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">szMsg&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">hello</span><span style="color: #000000">"</span><span style="color: #000000">;<br /><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;size&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;write(fd,&nbsp;szMsg,&nbsp;strlen(szMsg)</span><span style="color: #000000">+</span><span style="color: #000000">1</span><span style="color: #000000">);<br /><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;(</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;size)<br /><img id="Codehighlighter1_276_317_Open_Image" onclick="this.style.display='none'; Codehighlighter1_276_317_Open_Text.style.display='none'; Codehighlighter1_276_317_Closed_Image.style.display='inline'; Codehighlighter1_276_317_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_276_317_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_276_317_Closed_Text.style.display='none'; Codehighlighter1_276_317_Open_Image.style.display='inline'; Codehighlighter1_276_317_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_276_317_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_276_317_Open_Text"><span style="color: #000000">{<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cerr&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">error!</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;endl;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;close(fd1);<br /><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;</span><span style="color: #000000">0</span><span style="color: #000000">;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span></div>猜一下上面程序的执行结果。<br />在write时，fd和fd1的值是一样的，write fd时，实际就是write fd1。<br />为了避免自己在程序中误操作，可以在close(fd)之后，加上fd = -1; <img src ="http://www.cppblog.com/aa19870406/aggbug/183010.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aa19870406/" target="_blank">MrRightLeft</a> 2012-07-12 16:13 <a href="http://www.cppblog.com/aa19870406/archive/2012/07/12/183010.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>redis源码剖析-字符串</title><link>http://www.cppblog.com/aa19870406/archive/2012/07/03/181190.html</link><dc:creator>MrRightLeft</dc:creator><author>MrRightLeft</author><pubDate>Mon, 02 Jul 2012 16:59:00 GMT</pubDate><guid>http://www.cppblog.com/aa19870406/archive/2012/07/03/181190.html</guid><wfw:comment>http://www.cppblog.com/aa19870406/comments/181190.html</wfw:comment><comments>http://www.cppblog.com/aa19870406/archive/2012/07/03/181190.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aa19870406/comments/commentRss/181190.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aa19870406/services/trackbacks/181190.html</trackback:ping><description><![CDATA[<div style="text-align: center;"><span style="font-size: 18pt; ">redis源码剖析-字符串<br /><br /></span></div>redis实现了自己的字符串结构。在文件sds.h/dsd.c中定义。redis中的字符串叫sds(simple dynamic string)。<br />sds实质是char*:<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->typedef&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;*sds;</div>sds通过sdsnewlen()函数来创建,sds sdsnewlen(const void *init, size_t initlen)。该函数内部会创建一个sdshdr的结构,返回值sds，即char *，该结构定义如下:<br /><div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">struct</span>&nbsp;sdshdr<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;len;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;free;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;buf[];<br />};</div>其中len存储当前字符串的长度，free存储该结构体剩余可存储字节数，buf存储字符串值。sdsnewlen()函数在创建sdshdr后，会返回buf的地址（sdshdr-&gt;buf)。<br />sdsnewlen()函数创建了字符串，并返回字符串地址sds,要使用sdshdr中的len和free，则需要获取sdshdr结构体的地址。如何根据获得的sds得到sdshdr结构体的地址呢？<br /><div>redis中参考了linux内核关于通用list(list_head)的实现机制,实现方法如下:<br /><div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">struct</span>&nbsp;sdshdr&nbsp;*sh&nbsp;=&nbsp;&nbsp;(<span style="color: #0000FF; ">void</span>*)&nbsp;(sds-(<span style="color: #0000FF; ">sizeof</span>(<span style="color: #0000FF; ">struct</span>&nbsp;sdshdr)));</div>sds是返回的字符串地址，即sdshdr-&gt;buf，用sds的地址减去其在结构体中的偏移，即可得到sdshdr的地址。由于buf在sdshdr结构体的最后，所以其偏移就是sizeof(len)+sizeof(free),该偏移恰好是sizeof(struct sdshdr)。<br />如果buf在sdshdr中的位置是任意的，如何根据buf的地址获取sdshdr的地址呢？实现如下:<br />假设现在sdshdr声明如下:<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">struct</span>&nbsp;sdshdr<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;len;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;buf[];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;free;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />};</div><font color="#0000ff" size="2">则sdshdr地址如下获取：<br /></font><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">int</span>&nbsp;offset_buf&nbsp;=&nbsp;(<span style="color: #0000FF; ">int</span>)((<span style="color: #0000FF; ">struct</span>&nbsp;sdshdr&nbsp;*)0)-&gt;buf;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><span style="color: #0000FF; ">struct</span>&nbsp;sdshdr&nbsp;*sh&nbsp;=(<span style="color: #0000FF; ">struct</span>&nbsp;sdshdr&nbsp;*)(&nbsp;(<span style="color: #0000FF; ">int</span>)sdsbuf&nbsp;-&nbsp;offset_buf); &nbsp;</div><font color="#0000ff" size="2">其中sdsbuf是调用sdsnewlen()返回的buf地址。即 sds sdsbuf = sdsnewlen(...);<br /></font><span style="font-size: 13px; background-color: #eeeeee; ">((</span><span style="font-size: 13px; color: #0000ff; ">struct</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;sdshdr&nbsp;</span><span style="font-size: 13px; background-color: #eeeeee; ">*</span><span style="font-size: 13px; background-color: #eeeeee; ">)</span><span style="font-size: 13px; background-color: #eeeeee; ">0</span><span style="font-size: 13px; background-color: #eeeeee; ">)</span><span style="font-size: 13px; background-color: #eeeeee; ">-&gt;</span><span style="font-size: 13px; background-color: #eeeeee; ">buf 表示当结构体sdshdr在地址0时，buf相对于sdshdr首地址的偏移。</span><font color="#0000ff" size="2"><br /></font></div><br /> <div class="vimiumReset vimiumHUD" style="right: 150px; opacity: 0; display: none; "></div> <div class="vimiumReset vimiumHUD" style="right: 150px; opacity: 0; display: none; "></div> <div class="vimiumReset vimiumHUD" style="right: 150px; opacity: 0; display: none; "></div> <img src ="http://www.cppblog.com/aa19870406/aggbug/181190.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aa19870406/" target="_blank">MrRightLeft</a> 2012-07-03 00:59 <a href="http://www.cppblog.com/aa19870406/archive/2012/07/03/181190.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>64位网络字节序与主机字节序转换</title><link>http://www.cppblog.com/aa19870406/archive/2012/06/20/179517.html</link><dc:creator>MrRightLeft</dc:creator><author>MrRightLeft</author><pubDate>Wed, 20 Jun 2012 08:50:00 GMT</pubDate><guid>http://www.cppblog.com/aa19870406/archive/2012/06/20/179517.html</guid><wfw:comment>http://www.cppblog.com/aa19870406/comments/179517.html</wfw:comment><comments>http://www.cppblog.com/aa19870406/archive/2012/06/20/179517.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/aa19870406/comments/commentRss/179517.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aa19870406/services/trackbacks/179517.html</trackback:ping><description><![CDATA[<p align="center"><span style="font-size: 18pt"><strong>&nbsp;64位网络字节序与主机字节序转换<br /><br /></strong></span></p>
<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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #000000">unsigned&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;ntohll(unsigned&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;val)<br /><img id="Codehighlighter1_50_269_Open_Image" onclick="this.style.display='none'; Codehighlighter1_50_269_Open_Text.style.display='none'; Codehighlighter1_50_269_Closed_Image.style.display='inline'; Codehighlighter1_50_269_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_50_269_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_50_269_Closed_Text.style.display='none'; Codehighlighter1_50_269_Open_Image.style.display='inline'; Codehighlighter1_50_269_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_50_269_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_50_269_Open_Text"><span style="color: #000000">{<br /><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;(__BYTE_ORDER&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;__LITTLE_ENDIAN)<br /><img id="Codehighlighter1_91_207_Open_Image" onclick="this.style.display='none'; Codehighlighter1_91_207_Open_Text.style.display='none'; Codehighlighter1_91_207_Closed_Image.style.display='inline'; Codehighlighter1_91_207_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_91_207_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_91_207_Closed_Text.style.display='none'; Codehighlighter1_91_207_Open_Image.style.display='inline'; Codehighlighter1_91_207_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_91_207_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_91_207_Open_Text"><span style="color: #000000">{<br /><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;(((unsigned&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;)htonl((</span><span style="color: #0000ff">int</span><span style="color: #000000">)((val&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">32</span><span style="color: #000000">)&nbsp;</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">32</span><span style="color: #000000">)))&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">32</span><span style="color: #000000">)&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;(unsigned&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">)htonl((</span><span style="color: #0000ff">int</span><span style="color: #000000">)(val&nbsp;</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">32</span><span style="color: #000000">));<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><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">&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(__BYTE_ORDER&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;__BIG_ENDIAN)<br /><img id="Codehighlighter1_250_267_Open_Image" onclick="this.style.display='none'; Codehighlighter1_250_267_Open_Text.style.display='none'; Codehighlighter1_250_267_Closed_Image.style.display='inline'; Codehighlighter1_250_267_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_250_267_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_250_267_Closed_Text.style.display='none'; Codehighlighter1_250_267_Open_Image.style.display='inline'; Codehighlighter1_250_267_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_250_267_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_250_267_Open_Text"><span style="color: #000000">{<br /><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;val;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />unsigned&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;htonll(unsigned&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;val)<br /><img id="Codehighlighter1_322_541_Open_Image" onclick="this.style.display='none'; Codehighlighter1_322_541_Open_Text.style.display='none'; Codehighlighter1_322_541_Closed_Image.style.display='inline'; Codehighlighter1_322_541_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_322_541_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_322_541_Closed_Text.style.display='none'; Codehighlighter1_322_541_Open_Image.style.display='inline'; Codehighlighter1_322_541_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_322_541_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_322_541_Open_Text"><span style="color: #000000">{<br /><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;(__BYTE_ORDER&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;__LITTLE_ENDIAN)<br /><img id="Codehighlighter1_363_479_Open_Image" onclick="this.style.display='none'; Codehighlighter1_363_479_Open_Text.style.display='none'; Codehighlighter1_363_479_Closed_Image.style.display='inline'; Codehighlighter1_363_479_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_363_479_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_363_479_Closed_Text.style.display='none'; Codehighlighter1_363_479_Open_Image.style.display='inline'; Codehighlighter1_363_479_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_363_479_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_363_479_Open_Text"><span style="color: #000000">{<br /><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;(((unsigned&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;)htonl((</span><span style="color: #0000ff">int</span><span style="color: #000000">)((val&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">32</span><span style="color: #000000">)&nbsp;</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">32</span><span style="color: #000000">)))&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">32</span><span style="color: #000000">)&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;(unsigned&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">)htonl((</span><span style="color: #0000ff">int</span><span style="color: #000000">)(val&nbsp;</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">32</span><span style="color: #000000">));<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><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">&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(__BYTE_ORDER&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;__BIG_ENDIAN)<br /><img id="Codehighlighter1_522_539_Open_Image" onclick="this.style.display='none'; Codehighlighter1_522_539_Open_Text.style.display='none'; Codehighlighter1_522_539_Closed_Image.style.display='inline'; Codehighlighter1_522_539_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_522_539_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_522_539_Closed_Text.style.display='none'; Codehighlighter1_522_539_Open_Image.style.display='inline'; Codehighlighter1_522_539_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_522_539_Closed_Text"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_522_539_Open_Text"><span style="color: #000000">{<br /><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;val;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span></div>
<p>&nbsp;</p><img src ="http://www.cppblog.com/aa19870406/aggbug/179517.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aa19870406/" target="_blank">MrRightLeft</a> 2012-06-20 16:50 <a href="http://www.cppblog.com/aa19870406/archive/2012/06/20/179517.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何定义变长的TLV结构体？</title><link>http://www.cppblog.com/aa19870406/archive/2012/06/14/178803.html</link><dc:creator>MrRightLeft</dc:creator><author>MrRightLeft</author><pubDate>Thu, 14 Jun 2012 07:46:00 GMT</pubDate><guid>http://www.cppblog.com/aa19870406/archive/2012/06/14/178803.html</guid><wfw:comment>http://www.cppblog.com/aa19870406/comments/178803.html</wfw:comment><comments>http://www.cppblog.com/aa19870406/archive/2012/06/14/178803.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/aa19870406/comments/commentRss/178803.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aa19870406/services/trackbacks/178803.html</trackback:ping><description><![CDATA[<div style="text-align: center;"><strong style="font-size: 18pt; ">如何定义变长的TLV结构体？<br /><br /></strong></div>TLV是一种常用的用于通信的结构体格式。T表示tag，L表示length，V表示value。其中T和L是固定大小的，V是可变大小，L表示的是V的长度。通常用于结构化网络通信中的数据流。如0x3 3 'aa\0'，0x3 5 'aaaa\0',其中0x3表示tag的值，3 or 5表示的是后面的字符串的长度。由于V是可变长度的，所以在定义TLV结构时，需要将V定义成为可变大小。可定义如下：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">struct</span>&nbsp;TLV<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;uint8_t&nbsp;tag;<br />&nbsp;&nbsp;&nbsp;&nbsp;uint16_t&nbsp;len;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;value[0];<br />}__attribute__((packed));</div><br />注意value分配的是0大小，最后一个成员为可变长的数组，对于TLV（Type-Length-Value）形式的结构，或者其他需要变长度的结构体，用这种方式定义最好。使用起来非常方便，创建时，malloc一段结构体大小加上可变长数据长度的空间给它，可变长部分可按数组的方式访问，释放时，直接把整个结构体free掉就可以了。__attribute__(packed)用来强制不对struct TLV进行4字节对齐，目的是为了获取真实的TLV的空间使用情况。<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">int</span>&nbsp;main()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;*szMsg&nbsp;=&nbsp;"aaaaaaaaa";<br />&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;<span style="color: #0000FF; ">sizeof</span>(TLV)&nbsp;&lt;&lt;&nbsp;endl;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">the&nbsp;size&nbsp;of&nbsp;TLV</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;uint16_t&nbsp;len&nbsp;=&nbsp;strlen(szMsg)&nbsp;+&nbsp;1;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;TLV&nbsp;*pTLV;<br />&nbsp;&nbsp;&nbsp;&nbsp;pTLV&nbsp;=&nbsp;(<span style="color: #0000FF; ">struct</span>&nbsp;TLV*)malloc(<span style="color: #0000FF; ">sizeof</span>(<span style="color: #0000FF; ">struct</span>&nbsp;TLV)&nbsp;+&nbsp;<span style="color: #0000FF; ">sizeof</span>(<span style="color: #0000FF; ">char</span>)*len);<br />&nbsp;&nbsp;&nbsp;&nbsp;pTLV-&gt;tag&nbsp;=&nbsp;0x2;<br />&nbsp;&nbsp;&nbsp;&nbsp;pTLV-&gt;len&nbsp;=&nbsp;len;<br />&nbsp;&nbsp;&nbsp;&nbsp;memcpy(pTLV-&gt;value,&nbsp;szMsg,&nbsp;len);<br />&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;pTLV-&gt;value&nbsp;&lt;&lt;&nbsp;endl;<br />&nbsp; &nbsp; free(pTLV);<br />&nbsp; &nbsp; pTLV = NULL;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />}</div><br />这里有关于设置变长TLV的详细说明：<a href="http://www.douban.com/note/213324857/">http://www.douban.com/note/213324857/<br /></a><span style="color: red; "><strong>这里</strong></span><span style="color: red; "><strong>有一个问题，如何实现嵌套TLV结构呢？大家有什么好的思路吗？欢迎交流<br />简单实现了一下嵌套TLV，不知道有没有问题。<br /></strong></span><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#include&nbsp;&lt;iostream&gt;<br /><span style="color: #0000FF; ">using</span>&nbsp;<span style="color: #0000FF; ">namespace</span>&nbsp;std;<br /><br /><span style="color: #0000FF; ">struct</span>&nbsp;TLVNODE<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;uint8_t&nbsp;tag;<br />&nbsp;&nbsp;&nbsp;&nbsp;uint16_t&nbsp;len;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;value[0];<br />}__attribute__&nbsp;((packed));<br /><br /><span style="color: #0000FF; ">struct</span>&nbsp;TLV<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;hei;<br />&nbsp;&nbsp;&nbsp;&nbsp;uint8_t&nbsp;tag;<br />&nbsp;&nbsp;&nbsp;&nbsp;uint16_t&nbsp;len;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;TLVNODE&nbsp;value[0];<br />}&nbsp;__attribute__&nbsp;((packed));<br /><br /><span style="color: #0000FF; ">int</span>&nbsp;main()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">char&nbsp;*szMsg&nbsp;=&nbsp;"aaaaaaaaaaa";</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;<span style="color: #0000FF; ">sizeof</span>(TLV)&nbsp;&lt;&lt;&nbsp;endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">uint16_t&nbsp;len&nbsp;=&nbsp;strlen(szMsg)&nbsp;+&nbsp;1;</span><span style="color: #008000; "><br /></span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;*szNodeMsg&nbsp;=&nbsp;"bbbbbbbbbb";<br />&nbsp;&nbsp;&nbsp;&nbsp;uint16_t&nbsp;nodelen&nbsp;=&nbsp;strlen(szNodeMsg)&nbsp;+&nbsp;1;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;TLVNODE&nbsp;*pNode&nbsp;=&nbsp;(<span style="color: #0000FF; ">struct</span>&nbsp;TLVNODE&nbsp;*)&nbsp;malloc(<span style="color: #0000FF; ">sizeof</span>(<span style="color: #0000FF; ">struct</span>&nbsp;TLVNODE)&nbsp;+&nbsp;<span style="color: #0000FF; ">sizeof</span>(<span style="color: #0000FF; ">char</span>)*nodelen);&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;pNode-&gt;tag&nbsp;=&nbsp;0x3;<br />&nbsp;&nbsp;&nbsp;&nbsp;pNode-&gt;len&nbsp;=&nbsp;nodelen;<br />&nbsp;&nbsp;&nbsp;&nbsp;memcpy(pNode-&gt;value,&nbsp;szNodeMsg,&nbsp;nodelen);<br /><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;TLV&nbsp;*pTlv;<br />&nbsp;&nbsp;&nbsp;&nbsp;uint16_t&nbsp;nodeSize&nbsp;=&nbsp;<span style="color: #0000FF; ">sizeof</span>(<span style="color: #0000FF; ">struct</span>&nbsp;TLVNODE)&nbsp;+&nbsp;<span style="color: #0000FF; ">sizeof</span>(<span style="color: #0000FF; ">char</span>)*nodelen;<br />&nbsp;&nbsp;&nbsp;&nbsp;pTlv&nbsp;=&nbsp;(<span style="color: #0000FF; ">struct</span>&nbsp;TLV*)malloc(<span style="color: #0000FF; ">sizeof</span>(<span style="color: #0000FF; ">struct</span>&nbsp;TLV)&nbsp;+&nbsp;nodeSize);<br />&nbsp;&nbsp;&nbsp;&nbsp;pTlv-&gt;tag&nbsp;=&nbsp;0x2;<br />&nbsp;&nbsp;&nbsp;&nbsp;pTlv-&gt;len&nbsp;=&nbsp;nodeSize;<br /><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;pTlv-&gt;value[0]&nbsp;=&nbsp;(struct&nbsp;TLVNODE)*pNode;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;memcpy(pTlv-&gt;value,&nbsp;pNode,&nbsp;nodeSize);<br />&nbsp;&nbsp;&nbsp;&nbsp;free(pNode);<br />&nbsp;&nbsp;&nbsp;&nbsp;pNode&nbsp;=&nbsp;NULL;<br />&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;<span style="color: #0000FF; ">sizeof</span>(*pTlv)&nbsp;&lt;&lt;&nbsp;endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;len;&nbsp;++i)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pTlv-&gt;value[i]&nbsp;=&nbsp;szMsg[i];&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #008000; ">*/</span><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">memcpy(pTlv-&gt;value,&nbsp;szMsg,&nbsp;len);</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">cout&nbsp;&lt;&lt;&nbsp;pTlv-&gt;value&nbsp;&lt;&lt;&nbsp;endl;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;free(pTlv);<br />&nbsp;&nbsp;&nbsp;&nbsp;pTlv&nbsp;=&nbsp;NULL;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />}</div><span style="color: red; "><strong><br /><br /><br /><br /></strong></span><div class="vimiumReset vimiumHUD" style="right: 150px; opacity: 0; display: none; "></div><div class="vimiumReset vimiumHUD" style="right: 150px; opacity: 0; display: none; "></div><div class="vimiumReset vimiumHUD" style="right: 150px; opacity: 0; display: none; "></div><div class="vimiumReset vimiumHUD" style="right: 150px; opacity: 0; display: none; "></div><div class="vimiumReset vimiumHUD" style="right: 150px; opacity: 0; display: none; "></div> <div class="vimiumReset vimiumHUD" style="right: 150px; opacity: 0; display: none; "></div><img src ="http://www.cppblog.com/aa19870406/aggbug/178803.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aa19870406/" target="_blank">MrRightLeft</a> 2012-06-14 15:46 <a href="http://www.cppblog.com/aa19870406/archive/2012/06/14/178803.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>