﻿<?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>BlogJava-储备站-文章分类-C/C++</title><link>http://www.blogjava.net/calvinlau/category/40553.html</link><description>技术储备，从这里开始</description><language>zh-cn</language><lastBuildDate>Fri, 18 Sep 2009 08:37:45 GMT</lastBuildDate><pubDate>Fri, 18 Sep 2009 08:37:45 GMT</pubDate><ttl>60</ttl><item><title>static全局变量与普通的全局变量有什么区别？static局部变量和普通局部变量有什么区别？static函数与普通函数有什么区别？</title><link>http://www.blogjava.net/calvinlau/articles/294233.html</link><dc:creator>calvinlau</dc:creator><author>calvinlau</author><pubDate>Mon, 07 Sep 2009 15:37:00 GMT</pubDate><guid>http://www.blogjava.net/calvinlau/articles/294233.html</guid><wfw:comment>http://www.blogjava.net/calvinlau/comments/294233.html</wfw:comment><comments>http://www.blogjava.net/calvinlau/articles/294233.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/calvinlau/comments/commentRss/294233.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/calvinlau/services/trackbacks/294233.html</trackback:ping><description><![CDATA[<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="ProgId" content="Word.Document" />
<meta name="Generator" content="Microsoft Word 11" />
<meta name="Originator" content="Microsoft Word 11" />
<link rel="File-List" href="file:///C:%5CDOCUME%7E1%5Czhl%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml" /><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:PunctuationKerning/>
<w:DrawingGridVerticalSpacing>7.8 磅</w:DrawingGridVerticalSpacing>
<w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery>
<w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery>
<w:ValidateAgainstSchemas/>
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:Compatibility>
<w:SpaceForUL/>
<w:BalanceSingleByteDoubleByteWidth/>
<w:DoNotLeaveBackslashAlone/>
<w:ULTrailSpace/>
<w:DoNotExpandShiftReturn/>
<w:AdjustLineHeightInTable/>
<w:BreakWrappedTables/>
<w:SnapToGridInCell/>
<w:WrapTextWithPunct/>
<w:UseAsianBreakRules/>
<w:DontGrowAutofit/>
<w:UseFELayout/>
</w:Compatibility>
<w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
</w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles deflockedstate="false" latentstylecount="156">
</w:LatentStyles>
</xml><![endif]--><style>
<!-- /* Font Definitions */
@font-face
{font-family:宋体;
panose-1:2 1 6 0 3 1 1 1 1 1;
mso-font-alt:SimSun;
mso-font-charset:134;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:3 135135232 16 0 262145 0;}
@font-face
{font-family:"\@宋体";
panose-1:2 1 6 0 3 1 1 1 1 1;
mso-font-charset:134;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:3 135135232 16 0 262145 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-parent:"";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
mso-pagination:none;
font-size:10.5pt;
mso-bidi-font-size:12.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:宋体;
mso-font-kerning:1.0pt;}
/* Page Definitions */
@page
{mso-page-border-surround-header:no;
mso-page-border-surround-footer:no;}
@page Section1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
mso-header-margin:36.0pt;
mso-footer-margin:36.0pt;
mso-paper-source:0;}
div.Section1
{page:Section1;}
-->
</style><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:普通表格;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";
mso-ansi-language:#0400;
mso-fareast-language:#0400;
mso-bidi-language:#0400;}
</style>
<![endif]-->
<p class="MsoNormal"><strong><span style="font-size: 9pt; color: blue;" lang="EN-US">static</span></strong><strong><span style="font-size: 9pt; font-family: 宋体; color: blue;">全局变量与普通的全局变量有什么区别？</span></strong><strong><span style="font-size: 9pt; color: blue;" lang="EN-US">static</span></strong><strong><span style="font-size: 9pt; font-family: 宋体; color: blue;">局部变量和普通局部变量有什么区别？</span></strong><strong><span style="font-size: 9pt; color: blue;" lang="EN-US">static</span></strong><strong><span style="font-size: 9pt; font-family: 宋体; color: blue;">函数与普通函数有什么区别？</span></strong><strong><span style="font-size: 9pt; color: blue;" lang="EN-US"><o:p></o:p></span></strong></p>
<p class="MsoNormal"><span style="font-size: 9pt;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span style="font-size: 9pt; font-family: 宋体;">　　全局变量</span><span style="font-size: 9pt;" lang="EN-US">(</span><span style="font-size: 9pt; font-family: 宋体;">外部变量</span><span style="font-size: 9pt;" lang="EN-US">)</span><span style="font-size: 9pt; font-family: 宋体;">的说明之前再冠以</span><span style="font-size: 9pt;" lang="EN-US">static </span><span style="font-size: 9pt; font-family: 宋体;">就构成了静态的全局变量。全局变量本身就是静态存储方式，</span><span style="font-size: 9pt;"> </span><span style="font-size: 9pt; font-family: 宋体;">静态全局变量当然也是静态存储方式。</span><span style="font-size: 9pt;"> </span><span style="font-size: 9pt; font-family: 宋体;">这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序，</span><span style="font-size: 9pt;"> </span><span style="font-size: 9pt; font-family: 宋体;">当一个源程序由多个源文件组成时，非静态的全局变量在各个源文件中都是有效的。</span><span style="font-size: 9pt;"> </span><span style="font-size: 9pt; font-family: 宋体;">而静态全局变量则限制了其作用域，</span><span style="font-size: 9pt;"> </span><span style="font-size: 9pt; font-family: 宋体;">即只在定义该变量的源文件内有效，</span><span style="font-size: 9pt;"> </span><span style="font-size: 9pt; font-family: 宋体;">在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内，只能为该源文件内的函数公用，</span><span style="font-size: 9pt;"> </span><span style="font-size: 9pt; font-family: 宋体;">因此可以避免在其它源文件中引起错误。</span><span style="font-size: 9pt;" lang="EN-US"><o:p> <br />
</o:p></span></p>
<p class="MsoNormal"><span style="font-size: 9pt; font-family: 宋体;">　　从以上分析可以看出，</span><span style="font-size: 9pt;"> </span><span style="font-size: 9pt; font-family: 宋体;">把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域，</span><span style="font-size: 9pt;"> </span><span style="font-size: 9pt; font-family: 宋体;">限制了它的使用范围。</span><span style="font-size: 9pt;" lang="EN-US"><o:p> <br />
</o:p></span></p>
<p class="MsoNormal"><span style="font-size: 9pt; font-family: 宋体;">　　</span><span style="font-size: 9pt;" lang="EN-US">static</span><span style="font-size: 9pt; font-family: 宋体;">函数与普通函数作用域不同。仅在本文件。只在当前源文件中使用的函数应该说明为内部函数</span><span style="font-size: 9pt;" lang="EN-US">(static)</span><span style="font-size: 9pt; font-family: 宋体;">，内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数，应该在一个头文件中说明，要使用这些函数的源文件要包含这个头文件</span><span style="font-size: 9pt;" lang="EN-US"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size: 9pt; font-family: 宋体;">　　</span><span style="font-size: 9pt;" lang="EN-US">static</span><span style="font-size: 9pt; font-family: 宋体;">全局变量与普通的全局变量有什么区别：</span><span style="font-size: 9pt;" lang="EN-US">static</span><span style="font-size: 9pt; font-family: 宋体;">全局变量只初使化一次，防止在其他文件单元中被引用</span><span style="font-size: 9pt;" lang="EN-US">;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size: 9pt; font-family: 宋体;">　　</span><span style="font-size: 9pt;" lang="EN-US">static</span><span style="font-size: 9pt; font-family: 宋体;">局部变量和普通局部变量有什么区别：</span><span style="font-size: 9pt;" lang="EN-US">static</span><span style="font-size: 9pt; font-family: 宋体;">局部变量只被初始化一次，下一次依据上一次结果值；</span><span style="font-size: 9pt;" lang="EN-US"><o:p></o:p></span></p>
<span style="font-size: 9pt; font-family: 宋体;">　　</span><span style="font-size: 9pt; font-family: &quot;Times New Roman&quot;;" lang="EN-US">static</span><span style="font-size: 9pt; font-family: 宋体;">函数与普通函数有什么区别：</span><span style="font-size: 9pt; font-family: &quot;Times New Roman&quot;;" lang="EN-US">static</span><span style="font-size: 9pt; font-family: 宋体;">函数在内存中只有一份，普通函数在每个被调用中维持一份拷贝</span><span style="font-size: 9pt; font-family: &quot;Times New Roman&quot;;" lang="EN-US">. </span>
<img src ="http://www.blogjava.net/calvinlau/aggbug/294233.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/calvinlau/" target="_blank">calvinlau</a> 2009-09-07 23:37 <a href="http://www.blogjava.net/calvinlau/articles/294233.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>（zz） x&amp;(x-1)表达式的意义</title><link>http://www.blogjava.net/calvinlau/articles/287331.html</link><dc:creator>calvinlau</dc:creator><author>calvinlau</author><pubDate>Sun, 19 Jul 2009 07:27:00 GMT</pubDate><guid>http://www.blogjava.net/calvinlau/articles/287331.html</guid><wfw:comment>http://www.blogjava.net/calvinlau/comments/287331.html</wfw:comment><comments>http://www.blogjava.net/calvinlau/articles/287331.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/calvinlau/comments/commentRss/287331.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/calvinlau/services/trackbacks/287331.html</trackback:ping><description><![CDATA[http://hi.baidu.com/zengzhaonong/blog/item/7fb884509ee30c61853524c2.html<br />
<br />
<strong>x&amp;(x-1)表达式的意义</strong><br />
<br />
<strong>求下面函数的返回值(微软) -- 统计1的个数</strong><br />
-------------------------------------<br />
int func(int x)<br />
{<br />
&nbsp;&nbsp;&nbsp; int countx = 0;<br />
&nbsp;&nbsp;&nbsp; while(x)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; countx++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x = x&amp;(x-1);<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; return countx;<br />
}<br />
<br />
假定x = 9999<br />
10011100001111<br />
答案: 8<br />
<br />
思路: 将x转化为2进制，看含有的1的个数。<br />
注: 每执行一次x = x&amp;(x-1)，会将x用二进制表示时最右边的一个1变为0，因为x-1将会将该位(x用二进制表示时最右边的一个1)变为0。<br />
<br />
<br />
<br />
<br />
<strong>判断一个数(x)是否是2的n次方</strong><br />
-------------------------------------<br />
#include &lt;stdio.h&gt;<br />
<br />
int func(int x)<br />
{<br />
&nbsp;&nbsp;&nbsp; if( (x&amp;(x-1)) == 0 )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br />
&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br />
}<br />
<br />
int main()<br />
{<br />
&nbsp;&nbsp;&nbsp; int x = 8;<br />
&nbsp;&nbsp;&nbsp; printf("%d\n", func(x));<br />
}<br />
<br />
<br />
注:<br />
(1) 如果一个数是2的n次方，那么这个数用二进制表示时其最高位为1，其余位为0。<br />
<br />
(2) == 优先级高于 &amp;<br />
<img src ="http://www.blogjava.net/calvinlau/aggbug/287331.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/calvinlau/" target="_blank">calvinlau</a> 2009-07-19 15:27 <a href="http://www.blogjava.net/calvinlau/articles/287331.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(zz)IP校验和详解</title><link>http://www.blogjava.net/calvinlau/articles/286494.html</link><dc:creator>calvinlau</dc:creator><author>calvinlau</author><pubDate>Sun, 12 Jul 2009 15:42:00 GMT</pubDate><guid>http://www.blogjava.net/calvinlau/articles/286494.html</guid><wfw:comment>http://www.blogjava.net/calvinlau/comments/286494.html</wfw:comment><comments>http://www.blogjava.net/calvinlau/articles/286494.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/calvinlau/comments/commentRss/286494.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/calvinlau/services/trackbacks/286494.html</trackback:ping><description><![CDATA[<strong><span style="font-size: 14pt; font-family: 宋体; color: blue;" lang="EN-US"><span>一、<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span></strong><!--[endif]--><strong><span style="font-size: 14pt; font-family: 宋体; color: blue;">校验和算法<span lang="EN-US"><o:p></o:p></span></span></strong><span style="font-size: 12pt; font-family: 宋体;"><br />
</span>
<p class="MsoNormal" style="text-align: left; text-indent: 12pt;" align="left"><span style="font-size: 12pt; font-family: 宋体;">&nbsp; 之前一直只知道<span lang="EN-US">IP</span>校验和算法反码求和相关的<span lang="EN-US">,</span>但具体细节不清楚<span lang="EN-US">,</span>今天了解了下。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left; text-indent: 12pt;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">&nbsp; IP</span><span style="font-size: 12pt; font-family: 宋体;">校验和主要是用来保证数据<span lang="EN-US">(IP</span>包头<span lang="EN-US">)</span>的完整性的<span lang="EN-US">.</span>它用的算法非常简单<span lang="EN-US">,</span>就是反码求和<span lang="EN-US">校验.</span>需要注意的是反码求和又叫<span lang="EN-US">1</span>的补码<span lang="EN-US">(one's
complement),</span>而<span lang="EN-US">2</span>的补码就是我们通常说的补码求和了<span lang="EN-US">.</span>校验算法具体如下<span lang="EN-US">.<o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left; text-indent: 12pt;" align="left"><span style="font-size: 12pt; font-family: 宋体; color: #993366;" lang="EN-US">1</span><span style="font-size: 12pt; font-family: 宋体; color: #993366;">、发送方<span lang="EN-US"><o:p></o:p></span></span><br />
</p>
<p class="MsoNormal" style="text-align: left; text-indent: 12pt;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">&nbsp; i)</span><span style="font-size: 12pt; font-family: 宋体;">将校验和字段置为<span lang="EN-US">0,</span>然后将<span lang="EN-US">IP</span>包头按<span lang="EN-US">16</span>比特分成多个单元<span lang="EN-US">,</span>如包头长度不是<span lang="EN-US">16</span>比特的倍数<span lang="EN-US">,</span>则用<span lang="EN-US">0</span>比特填充到<span lang="EN-US">16</span>比特的倍数<span lang="EN-US">;<o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left; text-indent: 12pt;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">&nbsp;&nbsp;ii)</span><span style="font-size: 12pt; font-family: 宋体;">对各个单元采用反码加法运算<span lang="EN-US">(</span>即高位溢出位会加到低位<span lang="EN-US">,</span>通常的补码运算是直接丢掉溢出的高位<span lang="EN-US">),</span>将得到的和的反码填入校验和字段<span lang="EN-US">;<o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left; text-indent: 12pt;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">&nbsp;iii)</span><span style="font-size: 12pt; font-family: 宋体;">发送数据包<span lang="EN-US">;</span></span></p>
<p class="MsoNormal" style="text-align: left; text-indent: 12pt;" align="left"><br />
<span style="font-size: 12pt; font-family: 宋体;"><span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left; text-indent: 12pt;" align="left"><span style="font-size: 12pt; font-family: 宋体; color: #993366;" lang="EN-US">2</span><span style="font-size: 12pt; font-family: 宋体; color: #993366;">、接收方<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left; text-indent: 12pt;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">&nbsp;&nbsp;i)</span><span style="font-size: 12pt; font-family: 宋体;">将<span lang="EN-US">IP</span>包头按<span lang="EN-US">16</span>比特分成多个单元<span lang="EN-US">,</span>如包头长度不是<span lang="EN-US">16</span>比特的倍数<span lang="EN-US">,</span>则用<span lang="EN-US">0</span>比特填充到<span lang="EN-US">16</span>比特的倍数<span lang="EN-US">;<o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left; text-indent: 12pt;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">&nbsp; ii)</span><span style="font-size: 12pt; font-family: 宋体;">对各个单元采用反码加法运算<span lang="EN-US">,</span>检查得到的和是否符合是全<span lang="EN-US">1(</span>有的实现可能对得到的和会取反码<span lang="EN-US">,</span>然后判断最终值是不是全<span lang="EN-US">0);<o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left; text-indent: 12pt;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">&nbsp; iii)</span><span style="font-size: 12pt; font-family: 宋体;">如果是全<span lang="EN-US">1</span>则进行下步处理<span lang="EN-US">,</span>否则意味着包已变化从而丢弃之<span lang="EN-US">.<o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left; text-indent: 12pt;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p></o:p><br />
</span><span style="font-size: 12pt; font-family: 宋体;">&nbsp;&nbsp;&nbsp; 需要强调的是反码和是采用高位溢出加到低位的<span lang="EN-US">,</span>如<span lang="EN-US">3</span>比特的反码和运算<span lang="EN-US">:100b+101b=010b(</span>因为<span lang="EN-US">100b+101b=1001b,</span>高位溢出<span lang="EN-US">1,</span>其应该加到低位<span lang="EN-US">,</span>即<span lang="EN-US">001b+1b(</span>高位溢出位<span lang="EN-US">)=010b),</span>具体细节请参考文章<span lang="EN-US">:<a href="http://blog.chinaunix.net/u/20/showart_438418.html" target="_blank">http://blog.chinaunix.net/u/20/showart_438418.html</a><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left; text-indent: 12pt;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="margin-left: 0cm; text-align: left; text-indent: 0cm;" align="left"><!--[if !supportLists]--><strong><span style="font-size: 14pt; font-family: 宋体; color: blue;" lang="EN-US"><span>二、<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span></strong><!--[endif]--><strong><span style="font-size: 14pt; font-family: 宋体; color: blue;">校验和源码<span lang="EN-US"><o:p></o:p></span></span></strong></p>
<p class="MsoNormal" style="text-align: left; text-indent: 24pt;" align="left"><span style="font-size: 12pt; font-family: 宋体;">网上流传多组实现<span lang="EN-US">,</span>常见的有如下两种<span lang="EN-US">(</span>如追求效率可改写为汇编代码<span lang="EN-US">):<o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left; text-indent: 24pt;" align="left"><span style="font-size: 12pt; font-family: 宋体; color: #993366;" lang="EN-US">1</span><span style="font-size: 12pt; font-family: 宋体; color: #993366;">、<span lang="EN-US">RFC1071</span>源码</span></p>
<table style="border-collapse: collapse;" bgcolor="#f1f1f1" border="1" bordercolor="#999999" cellpadding="0" cellspacing="0" width="95%">
    <tbody>
        <tr>
            <td>
            <p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">short</span> csum<span style="color: #0000cc;">(</span><span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">char</span> <span style="color: #0000cc;">*</span>addr<span style="color: #0000cc;">,</span> <span style="color: #0000ff;">int</span> <span style="color: #ff0000;">count</span><span style="color: #0000cc;">)</span><br />
            <span style="color: #0000cc;">{</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #ff9900;">/* Compute Internet Checksum for "count" bytes<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; * beginning at location "addr".<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff;">register</span> <span style="color: #0000ff;">long</span> sum <span style="color: #0000cc;">=</span> 0<span style="color: #0000cc;">;</span><br />
            &nbsp;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff;">while</span><span style="color: #0000cc;">(</span> <span style="color: #ff0000;">count</span> <span style="color: #0000cc;">&gt;</span> 1 <span style="color: #0000cc;">)</span> <br />
            </span></code></p>
            <p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="color: #0000cc;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #ff9900;">/* This is the inner loop */</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sum <span style="color: #0000cc;">+</span><span style="color: #0000cc;">=</span> <span style="color: #0000cc;">*</span> <span style="color: #0000cc;">(</span><span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">short</span><span style="color: #0000cc;">)</span> addr<span style="color: #0000cc;">+</span><span style="color: #0000cc;">+</span><span style="color: #0000cc;">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #ff0000;">count</span> <span style="color: #0000cc;">-</span><span style="color: #0000cc;">=</span> 2<span style="color: #0000cc;">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000cc;">}</span><br />
            &nbsp;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #ff9900;">/* Add left-over byte, if any */</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff;">if</span><span style="color: #0000cc;">(</span> <span style="color: #ff0000;">count</span> <span style="color: #0000cc;">&gt;</span> 0 <span style="color: #0000cc;">)</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sum <span style="color: #0000cc;">+</span><span style="color: #0000cc;">=</span> <span style="color: #0000cc;">*</span> <span style="color: #0000cc;">(</span><span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">char</span> <span style="color: #0000cc;">*</span><span style="color: #0000cc;">)</span> addr<span style="color: #0000cc;">;</span><br />
            &nbsp;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #ff9900;">/* Fold 32-bit sum to 16 bits */</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff;">while</span> <span style="color: #0000cc;">(</span>sum<span style="color: #0000cc;">&gt;</span><span style="color: #0000cc;">&gt;</span>16<span style="color: #0000cc;">)</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sum <span style="color: #0000cc;">=</span> <span style="color: #0000cc;">(</span>sum <span style="color: #0000cc;">&amp;</span> 0xffff<span style="color: #0000cc;">)</span> <span style="color: #0000cc;">+</span> <span style="color: #0000cc;">(</span>sum <span style="color: #0000cc;">&gt;</span><span style="color: #0000cc;">&gt;</span> 16<span style="color: #0000cc;">)</span><span style="color: #0000cc;">;</span><br />
            &nbsp;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff;">return</span> <span style="color: #0000cc;">~</span>sum<span style="color: #0000cc;">;</span><br />
            <span style="color: #0000cc;">}</span></span></code></p>
            </td>
        </tr>
    </tbody>
</table>
<p class="MsoNormal" style="text-align: left; text-indent: 24pt;" align="left"><span style="font-size: 12pt; font-family: 宋体;">第一个<span lang="EN-US">while</span>循环是做普通加法<span lang="EN-US">(2</span>进制补码加法<span lang="EN-US">),</span>因为<span lang="EN-US">IP</span>包头和<span lang="EN-US">TCP</span>整个报文段比较短<span lang="EN-US">(</span>没达到<span lang="EN-US">2^17</span>数量级<span lang="EN-US">),</span>所以不可能导致<span lang="EN-US">4</span>字节的<span lang="EN-US">sum</span>溢出<span lang="EN-US">(unsigned long </span>一般至少为<span lang="EN-US">4</span>字节<span lang="EN-US">)).<br />
&nbsp;&nbsp;&nbsp; </span>紧接着的一个判断语句是为了能处理输入数据是奇数个字节的这种情况<span lang="EN-US">.<br />
&nbsp;&nbsp;&nbsp; </span>再接着的数据循环是实现反码算法<span lang="EN-US">(</span>在前面的普通加法得到的数据的基础上<span lang="EN-US">),</span>由反码和的高位溢出加到低位的性质<span lang="EN-US">,</span>可得到<span lang="EN-US">"3<span style="color: #ff01ff;">2</span></span><span style="color: #ff01ff;">位的数据的高位比特移位16比特,再加上原来的低16比特,不影响最终结果</span><span lang="EN-US">"</span>这个等价运算<span lang="EN-US">,</span>因为<span lang="EN-US">sum</span>的最初值<span lang="EN-US">(</span>刚开始循环时<span lang="EN-US">)</span>可能很大<span lang="EN-US">,</span>所以这个等价运算需循环进行<span lang="EN-US">,</span>直到<span lang="EN-US">sum</span>的高比特<span lang="EN-US">(16</span>比特以上<span lang="EN-US">)</span>全为<span lang="EN-US">0.</span>对于<span lang="EN-US">32</span>位的<span lang="EN-US">sum,</span>事实上这个运算循环至多只有两轮<span lang="EN-US">,</span>所以也有程序直接用两条<span lang="EN-US">"sum = (sum &amp; 0xffff) + (sum &gt;&gt; 16);"</span>代替了整个循环<span lang="EN-US">.<br />
&nbsp;&nbsp;&nbsp; </span>最后<span lang="EN-US">,</span>对和取反返回<span lang="EN-US">.</span></span></p>
<p class="MsoNormal" style="text-align: left; text-indent: 24pt;" align="left"><br />
<span style="font-size: 12pt; font-family: 宋体;"><span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体; color: #993366;" lang="EN-US">2</span><span style="font-size: 12pt; font-family: 宋体; color: #993366;">、对数据长度没限制的实现<span lang="EN-US"><o:p></o:p></span></span></p>
<table style="border-collapse: collapse;" bgcolor="#f1f1f1" border="1" bordercolor="#999999" cellpadding="0" cellspacing="0" width="95%">
    <tbody>
        <tr>
            <td>
            <p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">short</span> cksum <span style="color: #0000cc;">(</span><span style="color: #0000ff;">struct</span> ip <span style="color: #0000cc;">*</span>ip<span style="color: #0000cc;">,</span> <span style="color: #0000ff;">int</span> len<span style="color: #0000cc;">)</span><br />
            <span style="color: #0000cc;">{</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000ff;">long</span> sum <span style="color: #0000cc;">=</span> 0<span style="color: #0000cc;">;</span>                                <span style="color: #ff9900;">/* assume 32 bit long, 16 bit short */</span><br />
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000ff;">while</span> <span style="color: #0000cc;">(</span> len <span style="color: #0000cc;">&gt;</span>1 <span style="color: #0000cc;">)</span> <br />
            </span></code></p>
            <p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="color: #0000cc;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span><br />
            </span></code></p>
            <p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sum <span style="color: #0000cc;">+</span><span style="color: #0000cc;">=</span> <span style="color: #0000cc;">*</span><span style="color: #0000cc;">(</span><span style="color: #0000cc;">(</span><span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">short</span> <span style="color: #0000cc;">*</span><span style="color: #0000cc;">)</span> ip<span style="color: #0000cc;">)</span><span style="color: #0000cc;">+</span><span style="color: #0000cc;">+</span><span style="color: #0000cc;">;</span></span></code></p>
            <p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if</span> <span style="color: #0000cc;">(</span>sum <span style="color: #0000cc;">&amp;</span> 8x00000000<span style="color: #0000cc;">)</span>       <span style="color: #ff9900;">/* if high-order bit set, fold */</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sum <span style="color: #0000cc;">=</span> <span style="color: #0000cc;">(</span>sum <span style="color: #0000cc;">&amp;</span> 0xFFFF<span style="color: #0000cc;">)</span> <span style="color: #0000cc;">+</span> <span style="color: #0000cc;">(</span>sum<span style="color: #0000cc;">&gt;</span><span style="color: #0000cc;">&gt;</span> 16<span style="color: #0000cc;">)</span> <span style="color: #0000cc;">;</span><br />
            </span></code></p>
            <p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; len <span style="color: #0000cc;">-</span><span style="color: #0000cc;">=</span> 2<span style="color: #0000cc;">;</span></span></code></p>
            <p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="color: #0000cc;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br />
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000ff;">if</span> <span style="color: #0000cc;">(</span> len <span style="color: #0000cc;">)</span>                                      <span style="color: #ff9900;">/* take care of left over byte */</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sum <span style="color: #0000cc;">+</span><span style="color: #0000cc;">=</span> <span style="color: #0000cc;">(</span> <span style="color: #0000ff;">unsigned</span>  <span style="color: #0000ff;">short</span>  <span style="color: #0000cc;">)</span> <span style="color: #0000cc;">*</span> <span style="color: #0000cc;">(</span>unsignedl <span style="color: #0000ff;">char</span> <span style="color: #0000cc;">*</span><span style="color: #0000cc;">)</span> ip<span style="color: #0000cc;">;</span><br />
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000ff;">while</span> <span style="color: #0000cc;">(</span> sum <span style="color: #0000cc;">&gt;</span><span style="color: #0000cc;">&gt;</span> 16<span style="color: #0000cc;">)</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sum <span style="color: #0000cc;">=</span><span style="color: #0000cc;">(</span>sum <span style="color: #0000cc;">&amp;</span> 0xFFFF<span style="color: #0000cc;">)</span> <span style="color: #0000cc;">+</span> <span style="color: #0000cc;">(</span>sum<span style="color: #0000cc;">&gt;</span><span style="color: #0000cc;">&gt;</span> 16<span style="color: #0000cc;">)</span><span style="color: #0000cc;">;</span></span></code></p>
            <p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;">
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000ff;">return</span> <span style="color: #0000cc;">~</span>sum<span style="color: #0000cc;">;</span></span></code></p>
            <p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;">}
            <br />
            </span></code></p>
            </td>
        </tr>
    </tbody>
</table>
<p class="MsoNormal" style="text-align: left;" align="left">
</p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;"><span>&nbsp;</span>&nbsp;&nbsp; 这个实现与前面的一个的最大的不同是对数据的长度没什么限制了<span lang="EN-US">,</span>因为它在第一个循环的加法运算中实时检测<span lang="EN-US">sum</span>的高位的值<span lang="EN-US">,</span>一旦发现其有溢出的危险<span lang="EN-US">,</span>就及时运用等价运算关系消除了这个危险<span lang="EN-US">.</span></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><br />
<span style="font-size: 12pt; font-family: 宋体;"><span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="margin-left: 0cm; text-align: left; text-indent: 0cm;" align="left"><!--[if !supportLists]--><strong><span style="font-size: 14pt; font-family: 宋体; color: blue;" lang="EN-US"><span>三、<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span></strong><!--[endif]--><strong><span style="font-size: 14pt; font-family: 宋体; color: blue;">几个细节问题<span lang="EN-US"><o:p></o:p></span></span></strong></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">&nbsp;<span style="color: #993366;"> 1</span></span><span style="font-size: 12pt; font-family: 宋体; color: #993366;">、数据部分改变时的重校验</span><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><br />
&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 12pt; font-family: 宋体;">考虑这样的应用场景<span lang="EN-US">:</span>路由器转发<span lang="EN-US">IP</span>报文时<span lang="EN-US">,</span>有可能只更改了<span lang="EN-US">IP</span>数据包头的部分内容<span lang="EN-US">(</span>如更改了<span lang="EN-US">TTL,</span>分片了或<span lang="EN-US">SNAT</span>更改了源<span lang="EN-US">IP</span>等<span lang="EN-US">~~~),</span>却需要重校验的问题<span lang="EN-US">.</span>为提高转发效率<span lang="EN-US">,</span>要求重校验算法尽可能快<span lang="EN-US">,</span>故出现了如下的重校验算法<span lang="EN-US">: <br />
</span></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></p>
<table style="border-collapse: collapse;" bgcolor="#f1f1f1" border="1" bordercolor="#999999" cellpadding="0" cellspacing="0" width="95%">
    <tbody>
        <tr>
            <td>
            <p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;">UpdateTTL<span style="color: #0000cc;">(</span></span></code><code><span style="color: #000000;"><span style="color: #0000ff;">struct</span> ip_hdr <span style="color: #0000cc;">*</span>ipptr</span></code><code><span style="color: #000000;"><span style="color: #0000cc;">, </span></span></code><code><span style="color: #000000;"><span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">char</span> n</span></code><code><span style="color: #000000;"><span style="color: #0000cc;">)</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
            <span style="color: #0000cc;">{</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">long</span> sum<span style="color: #0000cc;">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">short</span> old<span style="color: #0000cc;">;</span><br />
            &nbsp;<br />
            &nbsp;&nbsp;&nbsp;&nbsp; old <span style="color: #0000cc;">=</span> <span style="color: #ff0000;">ntohs</span><span style="color: #0000cc;">(</span><span style="color: #0000cc;">*</span><span style="color: #0000cc;">(</span><span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">short</span> <span style="color: #0000cc;">*</span><span style="color: #0000cc;">)</span><span style="color: #0000cc;">&amp;</span>ipptr<span style="color: #0000cc;">-</span><span style="color: #0000cc;">&gt;</span>ttl<span style="color: #0000cc;">)</span><span style="color: #0000cc;">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp; ipptr<span style="color: #0000cc;">-</span><span style="color: #0000cc;">&gt;</span>ttl <span style="color: #0000cc;">-</span><span style="color: #0000cc;">=</span> n<span style="color: #0000cc;">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp; sum <span style="color: #0000cc;">=</span> old <span style="color: #0000cc;">+</span> <span style="color: #0000cc;">(</span><span style="color: #0000cc;">~</span><span style="color: #ff0000;">ntohs</span><span style="color: #0000cc;">(</span><span style="color: #0000cc;">*</span><span style="color: #0000cc;">(</span><span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">short</span> <span style="color: #0000cc;">*</span><span style="color: #0000cc;">)</span><span style="color: #0000cc;">&amp;</span>ipptr<span style="color: #0000cc;">-</span><span style="color: #0000cc;">&gt;</span>ttl<span style="color: #0000cc;">)</span> <span style="color: #0000cc;">&amp;</span> 0xffff<span style="color: #0000cc;">)</span><span style="color: #0000cc;">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp; sum <span style="color: #0000cc;">+</span><span style="color: #0000cc;">=</span> <span style="color: #ff0000;">ntohs</span><span style="color: #0000cc;">(</span>ipptr<span style="color: #0000cc;">-</span><span style="color: #0000cc;">&gt;</span>Checksum<span style="color: #0000cc;">)</span><span style="color: #0000cc;">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp; sum <span style="color: #0000cc;">=</span> <span style="color: #0000cc;">(</span>sum <span style="color: #0000cc;">&amp;</span> 0xffff<span style="color: #0000cc;">)</span> <span style="color: #0000cc;">+</span> <span style="color: #0000cc;">(</span>sum<span style="color: #0000cc;">&gt;</span><span style="color: #0000cc;">&gt;</span>16<span style="color: #0000cc;">)</span><span style="color: #0000cc;">;</span><br />
            &nbsp;&nbsp;&nbsp;&nbsp; ipptr<span style="color: #0000cc;">-</span><span style="color: #0000cc;">&gt;</span>Checksum <span style="color: #0000cc;">=</span> <span style="color: #ff0000;">htons</span><span style="color: #0000cc;">(</span>sum <span style="color: #0000cc;">+</span> <span style="color: #0000cc;">(</span>sum<span style="color: #0000cc;">&gt;</span><span style="color: #0000cc;">&gt;</span>16<span style="color: #0000cc;">)</span><span style="color: #0000cc;">)</span><span style="color: #0000cc;">;</span></span></code></p>
            <p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="color: #0000cc;">}</span><br />
            </span></code></p>
            </td>
        </tr>
    </tbody>
</table>
<p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体;">&nbsp;&nbsp; 算法的实现依据是这样的<span lang="EN-US">.</span>假设包头原校验和为<span lang="EN-US">~C,</span>改变的字段的原始值是<span lang="EN-US">m,</span>更改后的值是<span lang="EN-US">m',</span>设<span lang="EN-US">~C'</span>为重校验和<span lang="EN-US">,</span>则有<span lang="EN-US"> ~C' = ~(C+(-m)+m') = ~C+(m-m') = ~C+m+~m' <br />
&nbsp;&nbsp;&nbsp;
</span>等价关系的成立基于反码的运算性质<span lang="EN-US">:</span><span style="color: #ff01ff;">取反运算满足结合律,按位取反运算与符号取反(及相反数)是等价的(即</span><span lang="EN-US"><span style="color: #ff01ff;">~C=-C).</span><o:p></o:p></span></span></p>
<p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体; color: #993366;" lang="EN-US">2</span><span style="font-size: 12pt; font-family: 宋体; color: #993366;">、为什么采用反码和运算<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">&nbsp;&nbsp; IP</span><span style="font-size: 12pt; font-family: 宋体;">数据包校验要求速度快<span lang="EN-US">,</span>所以只采用了简单的和校验<span lang="EN-US">,</span>为什么采用反码和而不是补码和呢<span lang="EN-US">?<br />
&nbsp;&nbsp; i)</span><span style="color: #ff01ff;">反码和的溢出有后效性(蔓延性</span><span lang="EN-US"><span style="color: #ff01ff;">)</span><br />
&nbsp;&nbsp;&nbsp; </span>反码和将高位溢出加到低位<span lang="EN-US">,</span>导致这个溢出会对后面操作有永久影响<span lang="EN-US">,</span>有后效性<span lang="EN-US">;</span>而补码和直接将高位和溢出<span lang="EN-US">,</span>导致这个溢出对后面的操作再无影响<span lang="EN-US">,</span>因此无后效性<span lang="EN-US"><br />
&nbsp;&nbsp; ii)</span><span style="color: #ff01ff;">反码校验无需考虑字节序</span><span lang="EN-US"><br />
&nbsp;&nbsp;&nbsp; </span>正因为反码和的溢出有后效性<span lang="EN-US">,</span>导致大端字节序<span lang="EN-US">(big-endian)</span>和小端字节序<span lang="EN-US">(little-endian)</span>对同一数据序列<span lang="EN-US">(</span>如两个<span lang="EN-US">16</span>比特的序列<span lang="EN-US">)</span>产生的校验和也只是字节序相反，而补码和因为将溢出丢掉了<span lang="EN-US">,</span>不同字节序之间的校验大不相同且没什么联系。<span lang="EN-US"><br />
&nbsp;&nbsp; </span>基于以上的理由，校验和运算既可选择在数据被转换成网络字节序前，也可选择在之后。（<span style="color: #ff01ff;">这其实可以看作是负负得正，计算校验和与字节序有关，然后写校验和字段与字节序有关，然后直接计算校验和再写校验和字段则与字节序无关了</span><span lang="EN-US">~~</span>）<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="margin-left: 0cm; text-align: left; text-indent: 0cm;" align="left"><!--[if !supportLists]--><strong><span style="font-size: 14pt; font-family: 宋体; color: blue;" lang="EN-US"><span>四、<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span></strong><!--[endif]--><strong><span style="font-size: 14pt; font-family: 宋体; color: blue;">参考文章<span lang="EN-US"><o:p></o:p></span></span></strong></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">http://blog.chinaunix.net/u/20/showart_438512.html</span><span style="font-size: 12pt; font-family: 宋体;">，关于<span lang="EN-US">IP</span>校验和的<span lang="EN-US"><br />
http://blog.chinaunix.net/u/12313/showart_176114.html</span>，关于网络校验和的<span lang="EN-US"><br />
http://www.wesoho.com/article/Delphi/2143.htm</span>，关于<span lang="EN-US">IP</span>校验和的<span lang="EN-US"><br />
http://blog.chinaunix.net/u/20/showart_438418.html</span>，关于补码和反码的</span></p>
<img src ="http://www.blogjava.net/calvinlau/aggbug/286494.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/calvinlau/" target="_blank">calvinlau</a> 2009-07-12 23:42 <a href="http://www.blogjava.net/calvinlau/articles/286494.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>