<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_Ouzi的技术博客</title><subtitle type="text"/><id>http://feed.cnblogs.com/blog/u/38975/rss</id><updated>2011-05-14T06:46:42Z</updated><author><name>ouzi</name><uri>http://www.cnblogs.com/ouzi/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/ouzi/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/38975/rss"/><entry><id>http://www.cnblogs.com/ouzi/archive/2011/03/06/1972238.html</id><title type="text">本博客不再使用的声明</title><summary type="text">本人的现在的博客将不再使用，以后将使用http://www.cppblog.com/connoryan博客作为技术交流之用，欢迎大家一起去新的博客交流！！</summary><published>2011-03-06T05:08:00Z</published><updated>2011-03-06T05:08:00Z</updated><author><name>ouzi</name><uri>http://www.cnblogs.com/ouzi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/ouzi/archive/2011/03/06/1972238.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/ouzi/archive/2011/03/06/1972238.html"/><content type="html">&lt;div&gt;&lt;span style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; line-height: 19px; font-size: 13px; "&gt;本人的现在的博客将不再使用，以后将使用&lt;a href="http://www.cppblog.com/connoryan" title="http://www.cppblog.com/connoryan"&gt;http://www.cppblog.com/connoryan&lt;/a&gt;博客作为技术交流之用，欢迎大家一起去新的博客交流！！&lt;/span&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/ouzi/aggbug/1972238.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/ouzi/archive/2011/03/06/1972238.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/ouzi/archive/2011/03/05/1971395.html</id><title type="text">一个类只维护一张非虚函数表？？</title><summary type="text">class SomeClass { public: void Non_virtual_fun() { printf("Non_virtual_fun in SomeClass"); } virtual void Some_mem_fun(int x, char* p) { printf("In Some_mem_fun() SomeClass\n"); } }; int _tmain(int argc, _TCHAR* argv[]) { SomeClass* ps = NULL; ps-&gt;Non_virtual_fun(); //ps-&gt;S</summary><published>2011-03-05T00:55:00Z</published><updated>2011-03-05T00:55:00Z</updated><author><name>ouzi</name><uri>http://www.cnblogs.com/ouzi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/ouzi/archive/2011/03/05/1971395.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/ouzi/archive/2011/03/05/1971395.html"/><content type="html">&lt;div&gt;&lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style="font-size:10.0pt;font-family: Consolas;color:blue;"&gt;class&lt;/span&gt;&lt;span style="font-size:10.0pt;font-family:Consolas;"&gt; SomeClass&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style="font-size:10.0pt;font-family: Consolas;"&gt;{&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style="font-size:10.0pt;font-family: Consolas;color:blue;"&gt;public&lt;/span&gt;&lt;span style="font-size:10.0pt;font-family:Consolas;"&gt;:&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style="font-size:10.0pt;font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;void&lt;/span&gt; Non_virtual_fun()&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style="font-size:10.0pt;font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style="font-size:10.0pt;font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf(&lt;span style="color:#A31515"&gt;"Non_virtual_fun in SomeClass"&lt;/span&gt;);&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style="font-size:10.0pt;font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style="font-size:10.0pt;font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;virtual&lt;/span&gt; &lt;span style="color:blue"&gt;void&lt;/span&gt; Some_mem_fun(&lt;span style="color:blue"&gt;int&lt;/span&gt; x, &lt;span style="color:blue"&gt;char&lt;/span&gt;* p)&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style="font-size:10.0pt;font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style="font-size:10.0pt;font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf(&lt;span style="color:#A31515"&gt;"In Some_mem_fun() SomeClass\n"&lt;/span&gt;);&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style="font-size:10.0pt;font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-size:10.0pt;font-family:Consolas;"&gt;};&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style="font-size:10.0pt;font-family: Consolas;color:blue;"&gt;int&lt;/span&gt;&lt;span style="font-size:10.0pt;font-family:Consolas;"&gt; _tmain(&lt;span style="color:blue"&gt;int&lt;/span&gt; argc, _TCHAR* argv[])&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style="font-size:10.0pt;font-family: Consolas;"&gt;{&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style="font-size:10.0pt;font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SomeClass* ps = NULL;&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style="font-size:10.0pt;font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ps-&amp;gt;Non_virtual_fun();&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-size:10.0pt;font-family:Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;//ps-&amp;gt;Some_mem_fun(1, NULL);&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style="font-size:10.0pt;font-family: Consolas;"&gt;}&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&amp;nbsp;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style="font-family: 宋体;"&gt;今天在无意中发现了这样的一种调用居然是可以的，利用VC编译器显示出SomeClass类布局如下：&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style=" font-family:宋体;"&gt;class SomeClass size(4):&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style=" font-family:宋体;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; +---&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style=" font-family:宋体;"&gt;&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; | {vfptr}&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style=" font-family:宋体;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; +---&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&amp;nbsp;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style=" font-family:宋体;"&gt;SomeClass::$vftable@:&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style=" font-family:宋体;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; | &amp;amp;SomeClass_meta&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style=" font-family:宋体;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;0&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style=" font-family:宋体;"&gt;&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; | &amp;amp;SomeClass::Some_mem_fun&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&amp;nbsp;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style=" font-family:宋体;"&gt;SomeClass::Some_mem_fun this adjustor: 0&lt;/span&gt;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&amp;nbsp;&lt;/p&gt;  &lt;p align="left" style="text-align:left;text-autospace:none"&gt;&lt;span style="font-family: 宋体;"&gt;各位注意到没有，这里并没有关于&lt;/span&gt;&lt;span style="font-size:10.0pt;font-family:Consolas;"&gt;Non_virtual_fun&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的地址布局，也就是说非虚拟函数是不会保存在实例中的，一个类只维护一个非虚函数表，事后想了想，好像Inside the C++ &amp;nbsp;Object Model里面讲到过，但是忘记了。&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/ouzi/aggbug/1971395.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/ouzi/archive/2011/03/05/1971395.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/ouzi/archive/2011/02/14/1954220.html</id><title type="text">C++中的enum的名字空间</title><summary type="text">C++中的enum与C#中的非常的不同，最大的不同在于C++中的enum没有名字空间。 C# class Program { enum Motion { Start, Running, Stopping } static void Main(string[] args) { Motion m = Motion.Running; } } C++ enum Motion { Start, Running, Stopping }; int _tmain(int argc, _TCHAR* argv[]) { Motion m = Running; return 0; } 见上例，在C++中Moti.</summary><published>2011-02-14T04:31:00Z</published><updated>2011-02-14T04:31:00Z</updated><author><name>ouzi</name><uri>http://www.cnblogs.com/ouzi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/ouzi/archive/2011/02/14/1954220.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/ouzi/archive/2011/02/14/1954220.html"/><content type="html">&lt;div&gt;  &lt;p&gt;C++&lt;span style="font-family: 宋体;"&gt;中的&lt;/span&gt;enum&lt;span style="font-family: 宋体;"&gt;与&lt;/span&gt;C#&lt;span style="font-family: 宋体;"&gt;中的非常的不同，最大的不同在于&lt;/span&gt;C++&lt;span style="font-family: 宋体;"&gt;中的&lt;/span&gt;enum&lt;span style="font-family: 宋体;"&gt;没有名字空间。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;C#&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;class&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt; &lt;span style="color: #2b91af;"&gt;Program&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;enum&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Motion&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Start,&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Running,&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Stopping&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&amp;nbsp;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Main(&lt;span style="color: blue;"&gt;string&lt;/span&gt;[] args)&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;Motion&lt;/span&gt; m = &lt;span style="color: #2b91af;"&gt;Motion&lt;/span&gt;.&lt;span style="color: red;"&gt;Running&lt;/span&gt;;&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;}&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;C++&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;enum&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt; Motion&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;{&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Start,&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Running,&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Stopping&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;};&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&amp;nbsp;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;int&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt; _tmain(&lt;span style="color: blue;"&gt;int&lt;/span&gt; argc, _TCHAR* argv[])&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;{&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Motion m = &lt;span style="color: red;"&gt;Running&lt;/span&gt;;&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;return&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt; 0;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;}&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family: 宋体;"&gt;见上例，在&lt;/span&gt;C++&lt;span style="font-family: 宋体;"&gt;中&lt;/span&gt;Motion&lt;span style="font-family: 宋体;"&gt;并未起作用，使得&lt;/span&gt;enum&lt;span style="font-family: 宋体;"&gt;内的元素全局有效，容易造成符号冲突。如下面的情况&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;enum&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt; Motion&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;{&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Start,&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Running,&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Stopping&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;};&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&amp;nbsp;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;void&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt; Start()&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;{&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//...&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;}&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&amp;nbsp;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;int&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt; _tmain(&lt;span style="color: blue;"&gt;int&lt;/span&gt; argc, _TCHAR* argv[])&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;{&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Motion m = &lt;span style="color: red;"&gt;Running&lt;/span&gt;;&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;return&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt; 0;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;}&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family: 宋体;"&gt;这里就会报错误，提示&lt;/span&gt;Start&lt;span style="font-family: 宋体;"&gt;重复定义。还有一种情况也很常见，&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;class&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt; C&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;{&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;public&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;:&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;enum&lt;/span&gt; Motion&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Start,&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Running,&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Stopping&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&amp;nbsp;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;enum&lt;/span&gt; Status&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Go,&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Stopping&lt;/span&gt;&lt;/p&gt;  &lt;p align="left"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;};&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family: 宋体;"&gt;这里同样会提示错误，&lt;/span&gt;Stopping&lt;span style="font-family: 宋体;"&gt;重复定义，这两种情况都没有比较好的解决方法。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family: 宋体;"&gt;在&lt;/span&gt;Stackoverflow&lt;span style="font-family: 宋体;"&gt;里提供了一些解决方法，我们可以在以后的实际中选择一个适合的折中的解决办法。&lt;/span&gt;&lt;/p&gt;  &lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('94e8469e-e7a7-4efa-9e86-4dfb166e2569')"&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" class="code_img_closed" id="code_img_closed_94e8469e-e7a7-4efa-9e86-4dfb166e2569" alt="" /&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" class="code_img_opened" id="code_img_opened_94e8469e-e7a7-4efa-9e86-4dfb166e2569" onclick="cnblogs_code_hide('94e8469e-e7a7-4efa-9e86-4dfb166e2569',event)" style="display: none;"&gt;&lt;div id="cnblogs_code_open_94e8469e-e7a7-4efa-9e86-4dfb166e2569" class="cnblogs_code_hide"&gt;&lt;div&gt;&lt;!--&lt;br/&gt;&lt;br/&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/&gt;http://www.CodeHighlighter.com/&lt;br/&gt;&lt;br/&gt;--&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;oft&amp;nbsp;seen&amp;nbsp;hand-crafted&amp;nbsp;name&amp;nbsp;clash&amp;nbsp;solution&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;enum&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;eColors&amp;nbsp;{&amp;nbsp;cRed,&amp;nbsp;cColorBlue,&amp;nbsp;cGreen,&amp;nbsp;cYellow,&amp;nbsp;cColorsEnd&amp;nbsp;};&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;enum&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;eFeelings&amp;nbsp;{&amp;nbsp;cAngry,&amp;nbsp;cFeelingBlue,&amp;nbsp;cHappy,&amp;nbsp;cFeelingsEnd&amp;nbsp;};&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;setPenColor(&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;eColors&amp;nbsp;c&amp;nbsp;)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;switch&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(c)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&amp;nbsp;assert(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;cRed:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;...&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;cColorBlue:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;...&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;(ab)using&amp;nbsp;a&amp;nbsp;class&amp;nbsp;as&amp;nbsp;a&amp;nbsp;namespace&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;Colors&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;enum&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;e&amp;nbsp;{&amp;nbsp;cRed,&amp;nbsp;cBlue,&amp;nbsp;cGreen,&amp;nbsp;cYellow,&amp;nbsp;cEnd&amp;nbsp;};&amp;nbsp;};&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;Feelings&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;enum&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;e&amp;nbsp;{&amp;nbsp;cAngry,&amp;nbsp;cBlue,&amp;nbsp;cHappy,&amp;nbsp;cEnd&amp;nbsp;};&amp;nbsp;};&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;setPenColor(&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;Colors::e&amp;nbsp;c&amp;nbsp;)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;switch&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(c)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&amp;nbsp;assert(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;Colors::cRed:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;...&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;Colors::cBlue:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;...&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;a&amp;nbsp;real&amp;nbsp;namespace?&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;Colors&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;enum&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;e&amp;nbsp;{&amp;nbsp;cRed,&amp;nbsp;cBlue,&amp;nbsp;cGreen,&amp;nbsp;cYellow,&amp;nbsp;cEnd&amp;nbsp;};&amp;nbsp;};&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;Feelings&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;enum&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;e&amp;nbsp;{&amp;nbsp;cAngry,&amp;nbsp;cBlue,&amp;nbsp;cHappy,&amp;nbsp;cEnd&amp;nbsp;};&amp;nbsp;};&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;setPenColor(&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;Colors::e&amp;nbsp;c&amp;nbsp;)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;switch&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(c)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&amp;nbsp;assert(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;Colors::cRed:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;...&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;Colors::cBlue:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;...&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;原文见：&lt;/p&gt;&lt;div&gt;http://stackoverflow.com/questions/482745/namespaces-for-enum-types-best-practices&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;/div&gt;&lt;img src="http://www.cnblogs.com/ouzi/aggbug/1954220.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/ouzi/archive/2011/02/14/1954220.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/ouzi/archive/2010/09/18/1830016.html</id><title type="text">C#与C++之抉择见--我为什么抛弃C#</title><summary type="text">近几天博客园有一些关于C++的讨论，自己也有感而发，写一些我的想法，作为周末的消遣。可能我的这些想法不很成熟，欢迎讨论。这里同时认为C#=.net平台，虽然两者概念都不一样，本文主要从平台出发，语言上的对比较少，所以估且认为一样。可能看过我文章的，都知道我以前是做C#的，以前做的一些，像等值线的追踪和3D绘图，特别对于3D绘图，都是用的C#，后来工作，也是用的C#做winform，C#语言简洁，强...</summary><published>2010-09-18T02:29:00Z</published><updated>2010-09-18T02:29:00Z</updated><author><name>ouzi</name><uri>http://www.cnblogs.com/ouzi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/ouzi/archive/2010/09/18/1830016.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/ouzi/archive/2010/09/18/1830016.html"/><content type="html">&lt;p&gt;近几天博客园有一些关于C++的讨论，自己也有感而发，写一些我的想法，作为周末的消遣。可能我的这些想法不很成熟，欢迎讨论。这里同时认为C#=.net平台，虽然两者概念都不一样，本文主要从平台出发，语言上的对比较少，所以估且认为一样。&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;可能看过我文章的，都知道我以前是做C#的，以前做的一些，像等值线的追踪和3D绘图，特别对于3D绘图，都是用的C#，后来工作，也是用的C#做winform，C#语言简洁，强大，我的体会最深的，就是事件（委托）和闭包，&amp;nbsp;还有一个.net的反射，这三个特性加上VC#强大的智能提示给我带来的编程体验，是C++不能比拟的，其它的一些好的特性，不是很熟悉不做评论。&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;同样C++功能强大，凡是C#能做的，C++都能做，但是C++编程复杂，特别是其一些晦涩的语法，还有其在windows&amp;nbsp;下面众多的char, wchar等等这些都会让初学者却步。&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;其中前几天的&amp;nbsp;&lt;a href="http://www.cnblogs.com/miloyip/archive/2010/09/17/1828449.html"&gt;C++强大背后&lt;/a&gt;&amp;nbsp;讲解的非常好，大家可以去看，我这里主要讲一下我的认识。可能只试用于我个人，不适用于大家，大家各自权衡。&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;我为什么抛弃C#（更多的应该是.net平台）&lt;/p&gt;&lt;p&gt;1，&amp;nbsp;&amp;nbsp;应用领域不同&lt;/p&gt;&lt;p&gt;C#的应用领域，主要是大型的企业系统，不是说C#不能做其它的，而是很多时候选择一种语言或者说平台不是语言或者是平台本身这一个因素决定的，比如我现在做的服务器方面，项目主管就说过他也用C#做过，性能也还不错。大型的企业系统要求更多的不是语言，性能和一些底层的控制，其主要的是业务逻辑。C#语言用做这一类的开发，可以带来众多的好处，比较明显的开发效率高等等。&lt;/p&gt;&lt;p&gt;C#中还有一类应用相对较少的，做为门户类或者论坛类的网站，屈指可数，这里面比较知名的CSDN，博客园，还有myspace。做这一类型的网站，更多的已经似乎并不是C#或者.net平台的问题了，更多的是策略，比如缓存机制，负载均衡等等。&lt;/p&gt;&lt;p&gt;C++应用领域，主要在于现在我主攻的服务器（通信），实时系统，游戏和一些与硬件交互较多的系统。主要的并不是业务逻辑，更多的是相对独立于业务逻辑的底层层面，也就是策略，比如内存池，对象池等，还有那就是算法，算法也是一种策略。业务逻辑与策略的区别是，业务逻辑是有一个东西在那里，我来实现，其是业务的表现，而业务却由于其特性，变化频繁，而策略是一种权谋，就是我要怎么做。&lt;/p&gt;&lt;p&gt;2，&amp;nbsp;&amp;nbsp;更新速度的问题&lt;/p&gt;&lt;p&gt;大家知道C#从2001年到现在，已经由1.0到了4.0，到了4.0把C#进行了大换血，当然我不是说那些功能不好，而是这样的更新速度让我觉得无助，特别是WF，更是进行的全面的更新（更换？），在强势的引入的WF，WCF，WPF中，每一个的引入，都需要大量的时间来学习，虽然这些东西非常有用，可是却给人以不安全感，因为今天你学习的，明天可能就会淘汰或者被放弃，这样的例子在.net中大量存在，近来就有WF为先驱。而相对于C++而言，只从语法上讲，虽然语法晦涩难懂，掌握不易，但是发展却相对的缓慢，远没有C#那火箭般的速度。从应用的领域讲，从服务器到游戏，大多的流程固定，一旦成型，在几年内不会有大的变动，以服务器为例，做服务器虽然难，但是其主要的IOCP以及一些内存池，对象池，通信规则，多线程规则，基本上也有10年没有大的变动了，更甚者像算法，也是难，但难不在语言，难在策略，一旦成型，那是多少年也不会有大的变化，比如克里格算法，估计也有30年没有什么大的变动了，其前期主要是Fortran实现，后来改成了C++。&lt;/p&gt;&lt;p&gt;3，&amp;nbsp;&amp;nbsp;个人问题&amp;#8212;深入学习的态度&lt;/p&gt;&lt;p&gt;C#的学习量庞大，像4.0里面的，每个深入那都不是一日可成，就算你学会了，你能保证明天不会像WF一样，这样使我们疲于奔命，导致我没有学习的激励，记得以前用C#，常常下班后，很少来学习，是担心今天学了，明天就没用了，而C++不一样，深而有嚼劲，并且在短期内是不会被淘汰（或者是大的变动），学了就有积累，使自己不会永远是一个新人，前些日子面试，就遇到了不少做到40多的C++程序员，而在我面试C#的时候，基本都30以下。&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;所以，我决定，抛弃了C#，转了C++。&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000; "&gt;后记：&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000; "&gt;其实我选择的服务器的开发&lt;/span&gt;，其难度不会小于各位的各种系统的开发，其要学习的东西不要少于各位要学习的东西，就像现在星期六，我都还在调。语言或者平台的更新是好事，带来的更加高效，更加的方便 ，和编程理念的改变，关键是这一种更新，如果今天更新了，你跟上苦学几个月，好不容易入了个门了，可是哪天把你的东西全部了换了，就像WF，更甚者完全废弃，就像VJ#，诚然大家会说什么思维，什么能力等等内功修炼好了，其它的不攻自破，这对于那些大牛来说自然水到渠成，但是对于那些工作不久，倘没有不攻自破的能力的人，难道不是一种折磨。那我为什么不选择一个相对稳定的，凭什么给你做小白咧。跟着你闹腾。&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000; "&gt;关于学习&lt;/span&gt;，我可以这样说，在同龄人当中，除了那些天才，自恋的认为至少也算是中上水平，这些都是学习来的结果，有多少人在星期六的晚上12点还在调代码的。&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000; "&gt;关于抛弃&lt;/span&gt;这个词，可能用的不当，但是现在是你处于什么行业，大多情况下（不是绝对），你所选择的语言和平台也就是定下的，一般不会有大的改动，因为很多的公司会考虑自己公司原有的积累，对于我，如果在有选择的情况下，肯定会选择优先选择C++，次而考虑其它的。&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000; "&gt;关于大换血&lt;/span&gt;，这个用在C#是不对的，但是对于WF，用大换血一点错都没有。&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000; "&gt;行业（领域）的不同&lt;/span&gt;，对于软件开发的要求是不同的，比如我上家公司就是做GIS的，要求就是美观第一，所以为了做的炫，就不免要上WPF等等的这些，而现在这家公司，做服务器类的开发，对界面的要求就不那么高了，首先要求先做出来，性能还可以，然后再考虑其它的（这里要申明，我不是说美观等UI不重要，不要偷换概念），就比如做服务器开发领域，很多时候压根就不要界面，自然什么wpf的就可以完全的不需要考虑，对于服务器领域，技术相对成熟，模式比较固定，要学习的东西虽然难，并且深入也困难重重，但是，最起码，我可以像解决温饱问题一样，我不用担心明天我碗还在不在，我不用担心，要是明天他换了wdf, wff 怎么办，是跟上学习？我的选择可能只是一种退而求其次，我说的这些可能都不是其本质，本质的，还是要修炼内功，可是对于一个温饱都没有解决的人来说，等到内功到老赵那水平，人都不是饿死了，就是给微软三天一换血给累死了。&lt;/p&gt;&lt;p&gt;天下的技术多的出奇，你全部去学，学的完么，不要和我说内功，更多的时候，大家学东西都是被项目推着走的，项目要什么就学什么，如果既然要有所选择，为什么不能选择一个比较稳定的，先解决温饱的，不用担心明天饭碗还有没有的，这样难道不好？&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000; "&gt;综上撰述：&lt;/span&gt;我选择C++，主要是因为我的主攻方向的转变，由原来的winform的桌面转向服务器，在此基础上，也有C++与C#两种选择，首先现有大多数服务器产品均用C++开发（这里包括什么性能，参考资料齐全等等），其次在就是我上面那扯的一堆东西了。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/ouzi/aggbug/1830016.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/ouzi/archive/2010/09/18/1830016.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/ouzi/archive/2010/09/16/1828348.html</id><title type="text">绘图小工具0.0.1版本发布--vc版本</title><summary type="text">最近遇到了一些要绘图的，找了一下，发现要绘图的地方还是蛮多的，但往往绘制的图形都比较的简单，比如做一些简单的统计，常常都只要一个图，画一个x-y轴再加一条拆线，而网上找到的要么无比复杂，要么无比简单，达不到要求，所以做这个这样的绘图程序还有很有用处的。绘图程序比较好的开源的：①对于C#，就是大名鼎鼎的 DrawTools 了，如果想学习一些绘图的，以及一些简单的面向对象编程的，可以自行...</summary><published>2010-09-16T10:59:00Z</published><updated>2010-09-16T10:59:00Z</updated><author><name>ouzi</name><uri>http://www.cnblogs.com/ouzi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/ouzi/archive/2010/09/16/1828348.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/ouzi/archive/2010/09/16/1828348.html"/><content type="html">&lt;p&gt;最近遇到了一些要绘图的，找了一下，发现要绘图的地方还是蛮多的，但往往绘制的图形都比较的简单，比如做一些简单的统计，&lt;/p&gt;&lt;p&gt;常常都只要一个图，画一个x-y轴再加一条拆线，而网上找到的要么无比复杂，要么无比简单，达不到要求，所以做这个这样的绘图&lt;/p&gt;&lt;p&gt;程序还有很有用处的。&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;绘图程序比较好的开源的：&lt;/p&gt;&lt;p&gt;&amp;#9312;对于C#，就是大名鼎鼎的 DrawTools 了，如果想学习一些绘图的，以及一些简单的面向对象编程的，可以自行google。&lt;/p&gt;&lt;p&gt;&amp;#9313;对于C++，那就是drawcli了，可是我去codeproject上看了一下，源码好像就有1M多，怕了，就到google上找，找到了&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: Verdana, Helvetica, Arial; line-height: 18px; font-size: 12px; "&gt;&lt;span style="font-size: 10pt; "&gt;&lt;a href="http://www.cppblog.com/cugdj/archive/2008/01/29/42140.html"&gt;海市蜃楼&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&amp;nbsp;的这篇文章，是模仿的drawcli，但是简化了很多，可是他的东西在设计上有点问题，上下层耦合紧密，不利于分开来用。下面这篇文章讲一下这几天的改造过程和一些遇到的问题，我将现在的版本定义为0.0.1，是因为这个版本还有很多问题，以后我会持续的更新。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;类图&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;img src="http://images.cnblogs.com/cnblogs_com/ouzi/cplusplus/oddraw/ODDraw.jpg" width="536" height="384" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;类的继承关系比较简单，CODShape是所有图元的基类，CODShapeTool是所有图元的操作的基类，是一一对应关系&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;所做和一些分离操作&lt;/p&gt;&lt;p&gt;在原源码中，甚至在CODShapeTool这样的基类里面都存在着对上层的调用，这是不合理的，我在改造的过程中，引入了CMetas和CMetaContext这两个类，CMetas相当于图元的集合，以及对图元的操作，CMetaContext如其名，主要负责保存一些上下文信息，这样就将在原程序中的是层的对图元的操作全部放到CMetas中来。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;循环引用&lt;/p&gt;&lt;p&gt;这在C#中好像从来都不是问题，但是对于C++，比如CMetaContext类要用到CODShapeTool，而CODShapeTool为了与上层解耦，就需要引用CMetaContext这样就形成了循环引用，对于C++中的循环引用，我研究的不多，对于我遇到的这种情况，可以采用在.h文件中用前置申明，在.cpp中include的办法来解决。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;其它问题&lt;/p&gt;&lt;p&gt;源码之前，了无秘密，有什么疑问，可以提问，或者等待下一个版本的发布。&lt;/p&gt;&lt;p&gt;关于版权，本源码可以随意复制，修改或者用于商业用途，但请保留作者申明。同时不知道海市蜃楼他的版权申明是怎样的，如果有任何版权问题，可以与我联系，我会马上处理。&lt;/p&gt;&lt;p&gt;嗯，这个IntraduceToPrint我会持续更新下去，记得以前想找一些面向对象编程的源码时，总是找到的，要么太简单，泛泛而谈，要么无比复杂，让人望而却步，所以我会把从0.0.1到以后的版本都保存起来，这样有利于和原来的我一样的初学者。&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;源码点击&lt;a href="http://files.cnblogs.com/ouzi/IntraduceToPrintv01-0.0.1-20100915.rar"&gt;这里&lt;/a&gt;。 如果要密码，可以试一下：ouziprint&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/ouzi/aggbug/1828348.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/ouzi/archive/2010/09/16/1828348.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/ouzi/archive/2010/09/13/1825208.html</id><title type="text">C++类内存布局---d1reportSingleClassLayout小记</title><summary type="text">C++中的类内存的分布是非常麻烦的，微软提供了一个编译选项来实现内存的布局查看， 这样只要有不知道的内存布局，写个小例子，用这个命令就可以了。1cl[source.cpp]/d1reportSingleClassLayout[classname]这样就不需要记住那些复杂的继承关系内存布局了。</summary><published>2010-09-13T10:15:00Z</published><updated>2010-09-13T10:15:00Z</updated><author><name>ouzi</name><uri>http://www.cnblogs.com/ouzi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/ouzi/archive/2010/09/13/1825208.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/ouzi/archive/2010/09/13/1825208.html"/><content type="html">&lt;p&gt;C++中的类内存的分布是非常麻烦的，微软提供了一个编译选项来实现内存的布局查看， 这样只要有不知道的&lt;/p&gt;&lt;p&gt;内存布局，写个小例子，用这个命令就可以了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New'; font-size: 13px; "&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;cl&amp;nbsp;[source.cpp]&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;d1reportSingleClassLayout[classname]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;这样就不需要记住那些复杂的继承关系内存布局了。&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/ouzi/aggbug/1825208.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/ouzi/archive/2010/09/13/1825208.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/ouzi/archive/2010/07/20/1781370.html</id><title type="text">服务器开发系列—系统构架</title><summary type="text">这一篇主要介绍一下我们公司的分布式监控系统的构架。这里就要先讲一下，这个系统是做什么用的，我们的系统就是一个GIS监控系统，用来实时的监控车辆的，可以结合地图，实时的知道车在什么地方，车内的基本情况，因为有监听与拍照功能。其大致的结构如下所示：因为这个系统涉及到多个不同的个体，个体与个体之间的关联性是相对较小的，唯一的关联就是通过通信来实现的，这样通信的协议就变得非常的重要，在我觉得，通信系统最重...</summary><published>2010-07-20T06:10:00Z</published><updated>2010-07-20T06:10:00Z</updated><author><name>ouzi</name><uri>http://www.cnblogs.com/ouzi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/ouzi/archive/2010/07/20/1781370.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/ouzi/archive/2010/07/20/1781370.html"/><content type="html">&lt;p class="MsoNormal"&gt;&lt;font class="Apple-style-span" face="宋体"&gt;&lt;/font&gt;&lt;/p&gt;&lt;font class="Apple-style-span" face="宋体"&gt;&lt;p class="MsoNormal"&gt;这一篇主要介绍一下我们公司的分布式监控系统的构架。这里就要先讲一下，这个系统是做什么用的，我们的系统就是一个GIS监控系统，用来实时的监控车辆的，可以结合地图，实时的知道车在什么地方，车内的基本情况，因为有监听与拍照功能。其大致的结构如下所示：&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/ouzi/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%89%E5%B1%82.jpg" width="265" height="287" alt="" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;因为这个系统涉及到多个不同的个体，个体与个体之间的关联性是相对较小的，唯一的关联就是通过通信来实现的，这样通信的协议就变得非常的重要，在我觉得，通信系统最重要的内容就是协议。对于设备这个涉及到硬件，我不是很了解，但正是协议，让这三层之间的个体可以各自独立的开发，都按照协议来做就可以了，这里我主要讲下我们系统的服务器的构架。&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;服务器因为要涉及到设备，各种监控系统（比如webgis，监控中心GIS等）和数据库，为了整个系统的性能，健壮性等方面的考虑，我们的服务器分成了三个子系统APP服务器，网关服务器，数据服务器，&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/ouzi/%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%9E%84%E6%9E%B6.jpg" width="460" height="193" alt="" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;APP服务器：可以处理各种不同的客户端的连接，可以起到隔离各种客户端种种情况对整个服务器的影响&lt;/p&gt;&lt;p class="MsoNormal"&gt;网关服务器：面对的主要是设备的连接，网关服务器，可以做不同的设备将设备的协议转换成内部的协议，这里的转换是非常重要的一个内容。&lt;/p&gt;&lt;p class="MsoNormal"&gt;数据服务器：主要是将APP或者网关的数据写入到数据库&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;这个就是我们服务器的构架，最后来说一下，这样分成三个子系统的目的，我的理解是这样的：&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;#9312;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;/span&gt;健壮性：外部网络环境千变万化，而对于内部网络而言，基本可以认为是本机与本机通信，没有众多的不确定性因素。分成三个，一个子系统出问题了，可以不影响其它的子系统来运行&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;#9313;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;/span&gt;性能：对于分成三个服务器，我们可以把这三个子系统，部署到三台不同的机器上，这样可以运用多台机器的优势来提高整个系统的性能。&lt;/p&gt;&lt;/font&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/ouzi/aggbug/1781370.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/ouzi/archive/2010/07/20/1781370.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/ouzi/archive/2010/07/18/1780225.html</id><title type="text">及时监测连接被动关闭</title><summary type="text">原文链接：http://topic.csdn.net/u/20070816/10/8F73CD33-23D4-4449-A686-01EFD81876CD.html 除非有特别要求，否则你应该总是对每个连接保持一个挂起的接收pending io(使用WSARecv投递）。如果用户主动关闭连接，你的GetQueuedCompletionStatus调用将返回成功，但接收到的数据长度为0，你能根据...</summary><published>2010-07-18T08:35:00Z</published><updated>2010-07-18T08:35:00Z</updated><author><name>ouzi</name><uri>http://www.cnblogs.com/ouzi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/ouzi/archive/2010/07/18/1780225.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/ouzi/archive/2010/07/18/1780225.html"/><content type="html">&lt;p&gt;原文链接：&lt;/p&gt;&lt;p&gt;&lt;a href="http://topic.csdn.net/u/20070816/10/8F73CD33-23D4-4449-A686-01EFD81876CD.html"&gt;http://topic.csdn.net/u/20070816/10/8F73CD33-23D4-4449-A686-01EFD81876CD.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;/p&gt;&lt;p&gt; 除非有特别要求，否则你应该总是对每个连接保持一个挂起的接收pending io(使用WSARecv投递）。如果用户主动关闭连接，你的GetQueuedCompletionStatus调用将返回成功，但接收到的数据长度为0，你能根据这点检测连接是否已被对方关闭。如果连接被重置或者io被取消（如果你调用了CancelIo的话），GetQueuedCompletionStatus将返回失败，注意这时还应该判断GetQueuedCompletionStatus调用返回的lpOverlapped值，如果该值不为NULL，说明iocp已经检测到一个连接已经中断。 &lt;/p&gt;&lt;br /&gt;安全的关闭连接 &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;很多人写的服务器网络库有一个难以接受的缺陷（包括我曾就职公司的一些同事），当服务器程序主动关闭连接时，刚发往客户端的包有时出现丢失，这时他们推荐的方式往往是发送数据后等待几秒再关闭连接。豪无疑问，这是一种笨拙的实现方式，他们遇到的问题根源是什么呢？ &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;在非IOCP模式网络程序中，你只要简单的调用closesocket函数就可以确保数据在操作系统释放socket之前安全到达对方，但在IOCP模式下，如果调用closesocket时有未决的pending&amp;nbsp;&amp;nbsp; IO将导致socket被重置，所以有时会出现数据丢失。正统的解决方式是使用shutdown函数（指定SD_SEND标志），注意这时可能有未完成的发送pengding&amp;nbsp;&amp;nbsp; IO，所以你应该监测是否该连接的所有是否已完成（也许你要用一个计数器来跟踪这些pending&amp;nbsp;&amp;nbsp; IO），仅在所有send&amp;nbsp;&amp;nbsp; pending&amp;nbsp;&amp;nbsp; IO完成后调用shutdown。 &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;当你调用shutdown时，也许数据仍然停留在操作系统的缓冲，操作系统将在数据发送完后发出一个FIN包来启动关闭进程，客户端接收完数据后，将接受到一个0长度的包，以此判断连接已关闭（你写的客户端肯定有检测连接关闭，不是吗？），然后调用closesocket，这时服务器的GetQueuedCompletionStatus将接收到一个数据长度为0的包，这时你就可以调用closesocket，并释放相关连接资源。 &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;在绝大部分情况下上述的过程连接能完美的关闭。如果你特别注重服务器的安全性和健壮性，可能你还需要做一个&amp;#8220;连接关闭队列&amp;#8221;，对每个已调用shutdown的连接放到这个队列，然后定时的对这个队列扫描，如果一个连接5秒（你也可以自己调整）还不能关闭，那么就强制关闭它。 &lt;br /&gt;&lt;p&gt;&lt;span style="font-family: simsun; font-size: 14px; line-height: 23px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/ouzi/aggbug/1780225.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/ouzi/archive/2010/07/18/1780225.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/ouzi/archive/2010/07/17/1779798.html</id><title type="text">服务器软件开发系列--开篇</title><summary type="text">从毕业到现在一年的时间里，都在做通信方面的东西，因为通信往往涉及到高并发和大数据的处理，所以谁的代码只要有一丁点的问题，都会在服务器上显露无疑，所以并不能像很多的什么什么管理系统一样，效率差点没关系，反正也是企业内部使用。前事链接说到服务器这方面的，因为园子里面讨论的人也不多或者我关注的不够，所以在此链接以前的一些与服务器通信方面的讨论：① 经过一年时间的沉淀 再次回首 TCP Socket服务器编程这里有一些讨论，大家可以去看一下②浅谈线程池系列 ，正确使用异步操作这里有比较重要的IOCP与线程池相关的一些知识，大家都可以用看一下这里说明一下链接这些的原因，服务器的编程，或者说通信模块的套路</summary><published>2010-07-17T10:36:00Z</published><updated>2010-07-17T10:36:00Z</updated><author><name>ouzi</name><uri>http://www.cnblogs.com/ouzi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/ouzi/archive/2010/07/17/1779798.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/ouzi/archive/2010/07/17/1779798.html"/><content type="html">&lt;p class="MsoNormal"&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;从毕业到现在一年的时间里，都在做通信方面的东西，因为通信往往涉及到高并发和大数据的处理，所以谁的代码只要有一丁点的问题，都会在服务器上显露无疑，所以并不能像很多的什么什么管理系统一样，效率差点没关系，反正也是企业内部使用。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Cambria;mso-ascii-theme-font:major-latin;mso-fareast-font-family:宋体;mso-fareast-theme-font:major-fareast;mso-hansi-font-family:Cambria;mso-hansi-theme-font:major-latin"&gt;前事链接&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;说到服务器这方面的，因为园子里面讨论的人也不多或者我关注的不够，所以在此链接以前的一些与服务器通信方面的讨论：&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin-left:18.0pt;text-indent:-18.0pt;mso-list:l1 level1 lfo1"&gt;&lt;span class="apple-style-span"&gt;&lt;span lang="EN-US" style="mso-fareast-font-family:Calibri;mso-bidi-font-family:Calibri"&gt;&lt;span style="mso-list:Ignore"&gt;&amp;#9312;&lt;span style="font:7.0pt &amp;quot;Times New Roman&amp;quot;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="apple-style-span"&gt;&lt;span lang="EN-US" style="font-size:9.0pt;font-family:&amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;;color:#333333"&gt;&lt;a href="http://www.cnblogs.com/zc22/archive/2010/06/27/1766007.html#1858326"&gt;&lt;span lang="EN-US" style="font-family:宋体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:Arial;color:black"&gt;&lt;span lang="EN-US"&gt;经过一年时间的沉淀&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-family:&amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;;color:black"&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-family:宋体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:Arial;color:black"&gt;&lt;span lang="EN-US"&gt;再次回首&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:&amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;;color:black"&gt; TCP Socket&lt;/span&gt;&lt;span lang="EN-US" style="font-family:宋体;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:Arial;color:black"&gt;&lt;span lang="EN-US"&gt;服务器编程&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin-left:18.0pt"&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;这里有一些讨论，大家可以去看一下&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin-left:18.0pt;text-indent:-18.0pt;mso-list:l1 level1 lfo1"&gt;&lt;span lang="EN-US" style="mso-fareast-font-family:Calibri;mso-bidi-font-family:Calibri"&gt;&lt;span style="mso-list:Ignore"&gt;&amp;#9313;&lt;span style="font:7.0pt &amp;quot;Times New Roman&amp;quot;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;a href="http://www.cnblogs.com/JeffreyZhao/archive/2009/07/22/thread-pool-1-the-goal-and-the-clr-thread-pool.html"&gt;&lt;span lang="EN-US" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;color:windowtext"&gt;&lt;span lang="EN-US"&gt;浅谈线程池系列&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; &lt;/span&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;a href="http://www.cnblogs.com/JeffreyZhao/archive/2008/02/24/1079778.html"&gt;&lt;span lang="EN-US" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;color:windowtext"&gt;&lt;span lang="EN-US"&gt;正确使用异步操作&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin-left:18.0pt"&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;这里有比较重要的&lt;/span&gt;&lt;span lang="EN-US"&gt;IOCP&lt;/span&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;与线程池相关的一些知识，大家都可以用看一下&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;这里说明一下链接这些的原因，服务器的编程，或者说通信模块的套路也只有那么几种，对于采用&lt;/span&gt;&lt;span lang="EN-US"&gt;TCP&lt;/span&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;而言，为了取得好的性能，我个人感觉有以下只有以下几个点要处理，只要把这几个点处理好了，服务器的编程就没什么了（这里的观点欢迎讨论）：&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin-left:18.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo2"&gt;&lt;span lang="EN-US" style="mso-fareast-font-family:Calibri;mso-bidi-font-family:Calibri"&gt;&lt;span style="mso-list:Ignore"&gt;1，&lt;span style="font:7.0pt &amp;quot;Times New Roman&amp;quot;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;内存池（对&lt;/span&gt;&lt;span lang="EN-US"&gt;C++&lt;/span&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;而言）&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin-left:18.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo2"&gt;&lt;span lang="EN-US" style="mso-fareast-font-family:Calibri;mso-bidi-font-family:Calibri"&gt;&lt;span style="mso-list:Ignore"&gt;2，&lt;span style="font:7.0pt &amp;quot;Times New Roman&amp;quot;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;使用&lt;/span&gt;&lt;span lang="EN-US"&gt;IOCP&lt;/span&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;的&lt;/span&gt;&lt;span lang="EN-US"&gt;Socket&lt;span style="mso-spacerun:yes"&gt;&amp;nbsp; &lt;/span&gt;IO&lt;/span&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;模型（对&lt;/span&gt;&lt;span lang="EN-US"&gt;.net&lt;/span&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;而言，还不知道&lt;/span&gt;&lt;span lang="EN-US"&gt;.net&lt;/span&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;下的&lt;/span&gt;&lt;span lang="EN-US"&gt;iocp&lt;/span&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;怎么用）&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin-left:18.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo2"&gt;&lt;span lang="EN-US" style="mso-fareast-font-family:Calibri;mso-bidi-font-family:Calibri"&gt;&lt;span style="mso-list:Ignore"&gt;3，&lt;span style="font:7.0pt &amp;quot;Times New Roman&amp;quot;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;线程池（这里说的线程池其实用&lt;/span&gt;&lt;span lang="EN-US"&gt;iocp&lt;/span&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;已经解决了，提一下）&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin-left:18.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo2"&gt;&lt;span lang="EN-US" style="mso-fareast-font-family:Calibri;mso-bidi-font-family:Calibri"&gt;&lt;span style="mso-list:Ignore"&gt;4，&lt;span style="font:7.0pt &amp;quot;Times New Roman&amp;quot;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;Socket&lt;/span&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;连接池&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin-left:18.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo2"&gt;&lt;span lang="EN-US" style="mso-fareast-font-family:Calibri;mso-bidi-font-family:Calibri"&gt;&lt;span style="mso-list:Ignore"&gt;5，&lt;span style="font:7.0pt &amp;quot;Times New Roman&amp;quot;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;其它的一些策略问题，比如&lt;/span&gt;&lt;span lang="EN-US"&gt;UDP&lt;/span&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;模拟&lt;/span&gt;&lt;span lang="EN-US"&gt;TCP&lt;/span&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;的重发机制，防&lt;/span&gt;&lt;span lang="EN-US"&gt;DDOS&lt;/span&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;攻击，还有经常遇到的一些聚焦在&lt;/span&gt; &lt;span lang="EN-US"&gt;&lt;a href="http://www.cnblogs.com/zc22/archive/2010/06/27/1766007.html#1858209"&gt;&lt;span lang="EN-US" style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;&lt;span lang="EN-US"&gt;链接&lt;span lang="EN-US"&gt;&amp;#9312;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; &lt;/span&gt;&lt;span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri"&gt;中的讨论的客户端瞬间改送大量数据的问题，这里我没有多少经验，欢迎讨论。&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/ouzi/aggbug/1779798.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/ouzi/archive/2010/07/17/1779798.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/ouzi/archive/2010/07/13/1776690.html</id><title type="text">IOCP中在WSASend以及WSARecv的时候出现WSA_IO_PENDING情况的说明</title><summary type="text">原文链接：http://www.xixis.net/doserver.net//read.php/2063.htm应该是windows网络编程第二版里面提到过。现在整理一下。 1：在IOCP中投递WSASend返回WSA_IO_PENDING的时候，表示异步投递已经成功，但是稍后发送才会完成。这其中涉及到了三个缓冲区。网卡缓冲区，TCP/IP层缓冲区，程序缓冲区。情况一：调用WSASend发送正确...</summary><published>2010-07-13T10:23:00Z</published><updated>2010-07-13T10:23:00Z</updated><author><name>ouzi</name><uri>http://www.cnblogs.com/ouzi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/ouzi/archive/2010/07/13/1776690.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/ouzi/archive/2010/07/13/1776690.html"/><content type="html">&lt;p&gt;原文链接：&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.xixis.net/doserver.net//read.php/2063.htm" target="_blank"&gt;http://www.xixis.net/doserver.net//read.php/2063.htm&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;应该是windows网络编程第二版里面提到过。现在整理一下。&lt;/p&gt; &lt;span style="font-family: Tahoma, Arial; "&gt;&lt;strong&gt;1：在IOCP中投递WSASend返回WSA_IO_PENDING的时候，表示异步投递已经成功，但是稍后发送才会完成。这其中涉及到了三个缓冲区。&lt;br /&gt;网卡缓冲区，TCP/IP层缓冲区，程序缓冲区。&lt;br /&gt;&lt;span style="color: #0000ff; "&gt;情况一：调用WSASend发送正确的时候（即立即返回，且没有错误），TCP/IP将数据从程序缓冲区中拷贝到TCP/IP层缓冲区中，然后不锁定该程序缓冲区，由上层程序自己处理。TCP/IP层缓冲区在网络合适的时候，将其数据拷贝到网卡缓冲区，进行真正的发送。&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff0000; "&gt;情况二：调用WSASend发送错误，但是错误码是WSA_IO_PENDING的时候，表示此时TCP/IP层缓冲区已满，暂时没有剩余的空间将程序缓冲区的数据拷贝出来，这时系统将锁定用户的程序缓冲区，按照书上说的WSASend指定的缓冲区将会被锁定到系统的非分页内存中。直到TCP/IP层缓冲区有空余的地方来接受拷贝我们的程序缓冲区数据才拷贝走，并将给IOCP一个完成消息。&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000; "&gt;情况三：调用WSASend发送错误，但是错误码不是WSA_IO_PENDING，此时应该是发送错误，应该释放该SOCKET对应的所有资源。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;2：在IOCP中投递WSARecv的时候，情况相似。&lt;br /&gt;&lt;span style="color: #0000ff; "&gt;情况一：调用WSARecv正确，TCP/IP将数据从TCP/IP层缓冲区拷贝到缓冲区，然后由我们的程序自行处理了。清除TCP/IP层缓冲区数据。&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff0000; "&gt;情况二：调用WSARecv错误，但是返回值是WSA_IO_PENDING，此时是因为TCP/IP层缓冲区中没有数据可取，系统将会锁定我们投递的WSARecv的buffer，直到TCP/IP层缓冲区中有新的数据到来。&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000; "&gt;情况三：调用WSARecv错误，错误值不是WSA_IO_PENDING，此时是接收出错，应该释放该SOCKET对应的所有资源。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;在以上情况中有几个非常要注意的事情：&lt;br /&gt;&lt;span style="color: #ff0000; "&gt;系统锁定非分页内存的时候，最小的锁定大小是4K(当然，这个取决于您系统的设置，也可以设置小一些，在注册表里面可以改，当然我想这些数值微软应该比我们更知道什么合适了)，所以当我们投递了很多WSARecv或者WSASend的时候，不管我们投递的Buffer有多大（0除外），系统在出现IO_PENGDING的时候，都会锁定我们4K的内存。这也就是经常有开发者出现WSANOBUF的情况原因了。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;我们在解决这个问题的时候，要针对WSASend和WSARecv做处理&lt;br /&gt;&lt;span style="color: #ff0000; "&gt;1：投递WSARecv的时候，可以采用一个巧妙的设计，先投递0大小Buf的WSARecv，如果返回，表示有数据可以接收，我们开启真正的recv将数据从TCP/IP层缓冲区取出来，直到WSA_IO_PENGDING.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff0000; "&gt;2：对投递的WSARecv以及WSASend进行计数统计，如果超过了我们预定义的值，就不进行WSASend或者WSARecv投递了。&lt;/span&gt;&lt;br /&gt;3:现在我们应该就可以明白为什么WSASend会返回小于我们投递的buffer空间数据值了，是因为TCP/IP层缓冲区小于我们要发送的缓冲区，TCP/IP只会拷贝他剩余可被Copy的缓冲区大小的数据走，然后给我们的WSASend的已发送缓冲区设置为移走的大小，下一次投递的时候，如果TCP/IP层还未被发送，将返回WSA_IO_PENGDING。&lt;br /&gt;4：在很多地方有提到，可以关闭TCP/IP层缓冲区，可以提高一些效率和性能，这个从上面的分析来看，有这个可能，要实际的网络情况去实际分析了。&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;img src="http://www.cnblogs.com/ouzi/aggbug/1776690.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/ouzi/archive/2010/07/13/1776690.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
