<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>idea&#039;s blog &#187; C语言编程</title>
	<atom:link href="http://www.ideawu.net/blog/category/c-programming/feed" rel="self" type="application/rss+xml" />
	<link>http://www.ideawu.net/blog</link>
	<description>网络服务器架构, Linux C/C++服务器端开发, TCP/IP网络协议, PHP Web后端和Web前端开发, 网站架构.</description>
	<lastBuildDate>Wed, 08 Feb 2012 10:02:48 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Linus又骂人stupid</title>
		<link>http://www.ideawu.net/blog/archives/570.html</link>
		<comments>http://www.ideawu.net/blog/archives/570.html#comments</comments>
		<pubDate>Sat, 13 Nov 2010 08:00:08 +0000</pubDate>
		<dc:creator>ideawu</dc:creator>
				<category><![CDATA[C语言编程]]></category>
		<category><![CDATA[IT技术和评论]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.ideawu.net/blog/archives/570.html</guid>
		<description><![CDATA[<p><a href="http://www.ideawu.net/blog/wp-content/uploads/2010/11/glibc-flash.jpg"><img src="http://www.ideawu.net/blog/wp-content/uploads/2010/11/glibc-flash.jpg" alt="" title="glibc-flash" width="225" height="225" class="alignright size-full wp-image-569" /></a></p>
<p>最近, 有位用户向 bugzilla.redhat.com <a href="https://bugzilla.redhat.com/show_bug.cgi?id=638477">报告</a>他用 Fedora Linux 上网听 MP3 音乐时, 会播放出奇怪的声音. <a href="http://www.ideawu.net/blog/category/linux">Linux</a> 之父 Linus Torvalds 参与了讨论, 并最终找出原因, 竟然是 glibc 升级了 memcpy() 函数, 导致浏览器的 Abobe Flash Player 插件出现问题.</p>
<p>这真是太强大了, 竟然能从上网听音乐追查到几乎是软件最底层基础的 memcpy() 函数! 如果你想知道他是如何一步一步找出 BUG 的原因的, 可以自己去<a href="https://bugzilla.redhat.com/show_bug.cgi?id=638477">看贴</a>. (我个人不得不表示非常佩服他们敏锐的技术嗅觉和科学精神!)</p>
<p>这个 BUG 的原因是, 某位 <a href="http://article.gmane.org/gmane.comp.lib.glibc.alpha/15278">glibc 贡献者</a>(看邮件地址应该是 Intel 公司的某华裔工程师)提交了一个速度更快的 memcpy() 函数的实现并被采纳. 但是, 这个速度更快的 memcpy() 并没有像它的前一个版本一样对源内存和目的内存重叠的情况做兼容, 所以导致了 Flash 插件出问题.</p>
<p><span id="more-570"></span>Glibc 认为, memcpy() 函数的<a href="http://www.kernel.org/doc/man-pages/online/pages/man3/memcpy.3.html">手册</a>清楚的说明, memcpy() 所操作的两块内存不能重叠:</p>
<pre>
MEMCPY(3)                  Linux Programmer's Manual                 MEMCPY(3)

NAME
       memcpy - copy memory area

SYNOPSIS
       #include <string.h>

       void *memcpy(void *dest, const void *src, size_t n);

DESCRIPTION
       The  memcpy()  function  copies  n bytes from memory area src to memory
       area dest.  The memory areas should not overlap.  Use memmove(3) if the
       memory areas do overlap.
</pre>
<p>新版本的 memcpy() 完全遵守标准, 没有任何问题, 完全是 Adobe 的程序员没有编写正确的代码导致了 BUG, 应该算在 Adobe 的头上, 所以把这个报告标记为&#8221;NOTABUG(不是 BUG)&#8221;.</p>
<p>Linus 老大不屑地说, 在 Linux 内核里我们就用了我们自己的非常漂亮的 memcpy(), 而且经过简单测试, 还比所谓的 glibc 的新版本 memcpy() 还要快呢, glibc 的那个速度更快的新版本 memcpy() 根本就是愚蠢至极(&#8220;There&#8217;s no real reason to do the copy backwards that I can see, so doing it that way is just stupid.&#8221;). 毕竟是在 glibc 升级之后才导致了 BUG 的出现, 简单地推卸责任会让用户非常失望.</p>
<p>事情似乎告了一段落, 但是这些个国外的<a href="http://www.udpwork.com/">大牛人</a>们的争论, 让我们看到了做技术的人所应该具有的科学态度, 他们据理力争, 反驳有理有据的争论(讨论)方式值得我们学习. 特别是他们敏锐的观察和思考&#8221;领域外&#8221;的技术细节的精神 &#8211; 谁能想到浏览器放音乐出现破音竟然是 glibc 的升级后导致的? &#8211; 往往是我们缺少的.</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
<b>做个调查: 你支持 Linus 从用户角度考虑? 还是支持 glibc 从标准角度考虑?</b><br />
Note: There is a poll embedded within this post, please visit the site to participate in this post's poll.</p>


<h3>Related posts:</h3><ol><li><a href='http://www.ideawu.net/blog/archives/483.html' rel='bookmark' title='Permanent Link: 苹果乔布斯撰文说明为何拒绝Flash'>苹果乔布斯撰文说明为何拒绝Flash</a></li>
<li><a href='http://www.ideawu.net/blog/archives/307.html' rel='bookmark' title='Permanent Link: 关于 C++ 中的函数指针'>关于 C++ 中的函数指针</a></li>
<li><a href='http://www.ideawu.net/blog/archives/232.html' rel='bookmark' title='Permanent Link: 把Firefox的播放背景音乐功能去掉'>把Firefox的播放背景音乐功能去掉</a></li>
<li><a href='http://www.ideawu.net/blog/archives/141.html' rel='bookmark' title='Permanent Link: Linux发行版的选择'>Linux发行版的选择</a></li>
<li><a href='http://www.ideawu.net/blog/archives/365.html' rel='bookmark' title='Permanent Link: C#环形缓冲'>C#环形缓冲</a></li>
</ol><div><p><img src="http://www.ideawu.net/favicon.ico" /> 你现在看的文章是: <a href="http://www.ideawu.net/blog/archives/570.html" title="Linus又骂人stupid">Linus又骂人stupid</a></p>

<div>
	<a href="http://www.benegg.com/linode-ad.php">
		Linode VPS - 美国虚拟主机
	</a>
	|
	<a href="http://www.udpwork.com/">
		IT牛人博客聚合网站
	</a>
</div></div>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ideawu.net/blog/wp-content/uploads/2010/11/glibc-flash.jpg"><img src="http://www.ideawu.net/blog/wp-content/uploads/2010/11/glibc-flash.jpg" alt="" title="glibc-flash" width="225" height="225" class="alignright size-full wp-image-569" /></a></p>
<p>最近, 有位用户向 bugzilla.redhat.com <a href="https://bugzilla.redhat.com/show_bug.cgi?id=638477">报告</a>他用 Fedora Linux 上网听 MP3 音乐时, 会播放出奇怪的声音. <a href="http://www.ideawu.net/blog/category/linux">Linux</a> 之父 Linus Torvalds 参与了讨论, 并最终找出原因, 竟然是 glibc 升级了 memcpy() 函数, 导致浏览器的 Abobe Flash Player 插件出现问题.</p>
<p>这真是太强大了, 竟然能从上网听音乐追查到几乎是软件最底层基础的 memcpy() 函数! 如果你想知道他是如何一步一步找出 BUG 的原因的, 可以自己去<a href="https://bugzilla.redhat.com/show_bug.cgi?id=638477">看贴</a>. (我个人不得不表示非常佩服他们敏锐的技术嗅觉和科学精神!)</p>
<p>这个 BUG 的原因是, 某位 <a href="http://article.gmane.org/gmane.comp.lib.glibc.alpha/15278">glibc 贡献者</a>(看邮件地址应该是 Intel 公司的某华裔工程师)提交了一个速度更快的 memcpy() 函数的实现并被采纳. 但是, 这个速度更快的 memcpy() 并没有像它的前一个版本一样对源内存和目的内存重叠的情况做兼容, 所以导致了 Flash 插件出问题.</p>
<p><span id="more-570"></span>Glibc 认为, memcpy() 函数的<a href="http://www.kernel.org/doc/man-pages/online/pages/man3/memcpy.3.html">手册</a>清楚的说明, memcpy() 所操作的两块内存不能重叠:</p>
<pre>
MEMCPY(3)                  Linux Programmer's Manual                 MEMCPY(3)

NAME
       memcpy - copy memory area

SYNOPSIS
       #include <string.h>

       void *memcpy(void *dest, const void *src, size_t n);

DESCRIPTION
       The  memcpy()  function  copies  n bytes from memory area src to memory
       area dest.  The memory areas should not overlap.  Use memmove(3) if the
       memory areas do overlap.
</pre>
<p>新版本的 memcpy() 完全遵守标准, 没有任何问题, 完全是 Adobe 的程序员没有编写正确的代码导致了 BUG, 应该算在 Adobe 的头上, 所以把这个报告标记为&#8221;NOTABUG(不是 BUG)&#8221;.</p>
<p>Linus 老大不屑地说, 在 Linux 内核里我们就用了我们自己的非常漂亮的 memcpy(), 而且经过简单测试, 还比所谓的 glibc 的新版本 memcpy() 还要快呢, glibc 的那个速度更快的新版本 memcpy() 根本就是愚蠢至极(&#8220;There&#8217;s no real reason to do the copy backwards that I can see, so doing it that way is just stupid.&#8221;). 毕竟是在 glibc 升级之后才导致了 BUG 的出现, 简单地推卸责任会让用户非常失望.</p>
<p>事情似乎告了一段落, 但是这些个国外的<a href="http://www.udpwork.com/">大牛人</a>们的争论, 让我们看到了做技术的人所应该具有的科学态度, 他们据理力争, 反驳有理有据的争论(讨论)方式值得我们学习. 特别是他们敏锐的观察和思考&#8221;领域外&#8221;的技术细节的精神 &#8211; 谁能想到浏览器放音乐出现破音竟然是 glibc 的升级后导致的? &#8211; 往往是我们缺少的.</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
<b>做个调查: 你支持 Linus 从用户角度考虑? 还是支持 glibc 从标准角度考虑?</b><br />
Note: There is a poll embedded within this post, please visit the site to participate in this post's poll.</p>


<h3>Related posts:</h3><ol><li><a href='http://www.ideawu.net/blog/archives/483.html' rel='bookmark' title='Permanent Link: 苹果乔布斯撰文说明为何拒绝Flash'>苹果乔布斯撰文说明为何拒绝Flash</a></li>
<li><a href='http://www.ideawu.net/blog/archives/307.html' rel='bookmark' title='Permanent Link: 关于 C++ 中的函数指针'>关于 C++ 中的函数指针</a></li>
<li><a href='http://www.ideawu.net/blog/archives/232.html' rel='bookmark' title='Permanent Link: 把Firefox的播放背景音乐功能去掉'>把Firefox的播放背景音乐功能去掉</a></li>
<li><a href='http://www.ideawu.net/blog/archives/141.html' rel='bookmark' title='Permanent Link: Linux发行版的选择'>Linux发行版的选择</a></li>
<li><a href='http://www.ideawu.net/blog/archives/365.html' rel='bookmark' title='Permanent Link: C#环形缓冲'>C#环形缓冲</a></li>
</ol><div><p><img src="http://www.ideawu.net/favicon.ico" /> 你现在看的文章是: <a href="http://www.ideawu.net/blog/archives/570.html" title="Linus又骂人stupid">Linus又骂人stupid</a></p>

<div>
	<a href="http://www.benegg.com/linode-ad.php">
		Linode VPS - 美国虚拟主机
	</a>
	|
	<a href="http://www.udpwork.com/">
		IT牛人博客聚合网站
	</a>
</div></div>]]></content:encoded>
			<wfw:commentRss>http://www.ideawu.net/blog/archives/570.html/feed</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>C语言解析JSON</title>
		<link>http://www.ideawu.net/blog/archives/534.html</link>
		<comments>http://www.ideawu.net/blog/archives/534.html#comments</comments>
		<pubDate>Sat, 21 Aug 2010 13:45:56 +0000</pubDate>
		<dc:creator>ideawu</dc:creator>
				<category><![CDATA[C语言编程]]></category>

		<guid isPermaLink="false">http://www.ideawu.net/blog/archives/534.html</guid>
		<description><![CDATA[<p>最近一个 C/C++ 项目要用到 JSON, 所以选用了 <a href="http://oss.metaparadigm.com/json-c/">json-c</a> 库. C 语言不像 PHP/Python 等动态语言, 可以无缝地将 JSON 数据结构转为自身的数据结构, 所以操作起来会有些麻烦.</p>
<p>首先是数据结构. 在 json-c 里, 所有的 JSON 数据结构都是 json_object 类型, 然后这个 json_object 结构有一个 type 字段, 表明当前的对象是什么类型, 比如整数, 数组, 字符串等等. 没错, 大多数动态语言都是用类似的方法处理动态类型.</p>
<p>json-c 有自己的引用计数的内存管理机制, json_object_get() 函数用于手动地增加对象的引用计数, 相对地, json_object_put() 用于手动地减少引用计数. 要使用 json-c 必须非常明白每一个函数, 是否会增加或者减少对象的引用计数, 以避免内存泄露.</p>
<p><span id="more-534"></span>比较特殊的是, 将某个通过 xxx_new_xxx 方法创建的新对象加到另一个对象(对象容器)中(作为另一个对象的一个字段的值, 或者另一个数组的一个元素), 都不会增加新对象的引用计数. 所以, 虽然你 &#8220;new&#8221; 了一个对象, 但这时, 你却不能把它 &#8220;delete&#8221; 掉. 当你 &#8220;delete&#8221; 掉那个对象容器时, 它会自动的减少自己子节点的引用计数.</p>
<p>为了方便操作, 我写了一些辅助方法. 如, 通过点号(或者斜杠)分隔的路径获取属性:</p>
<pre>
json_object *json_util_get(json_object *obj, const char *path);
</pre>
<p>路径可以用数字来表示数组的下标. 比如 json_util_get(obj, &#8220;result.0.name&#8221;), 或者获取 obj 对象的 result 字段, 而 result 是一个数组, 读取该数组的下标为 0 的元素, 这个元素又是一个对象, 最终返回该对象的 name 属性. 因为有时候, 我们并不需要一级一级地关心中间的路径是否存在, 而只关心我们想要的最终结果是否存在. 这个方法非常有用.</p>
<p>另外, 就是数字和表示数字的字符串的问题. 在 PHP 等动态语言中, 表示数字的字符串很多情况下就是数字, 所以很难假设对方会严格地按要求且不会疏忽地把应该是 string 对象当作 int 对象传过来, 所以要在 C 语言里把这两者都当作是 int. 这又是另一个方法:</p>
<pre>
int json_util_get_int(json_object *obj, const char *path, int defval);
</pre>
<p>如果指定的字段不是整数而是字符串, 则是尝试把它转为整数返回来.</p>


<h3>Related posts:</h3><ol><li><a href='http://www.ideawu.net/blog/archives/517.html' rel='bookmark' title='Permanent Link: HTTP POST using PHP cURL'>HTTP POST using PHP cURL</a></li>
<li><a href='http://www.ideawu.net/blog/archives/388.html' rel='bookmark' title='Permanent Link: 基于列的数据库'>基于列的数据库</a></li>
<li><a href='http://www.ideawu.net/blog/archives/351.html' rel='bookmark' title='Permanent Link: 史上最强大的PHP MySQL操作类'>史上最强大的PHP MySQL操作类</a></li>
<li><a href='http://www.ideawu.net/blog/archives/494.html' rel='bookmark' title='Permanent Link: 链接包含&#8221;%2F&#8221;导致mod_rewrite失效'>链接包含&#8221;%2F&#8221;导致mod_rewrite失效</a></li>
<li><a href='http://www.ideawu.net/blog/archives/338.html' rel='bookmark' title='Permanent Link: Prado 中解决 Ajax 中文乱码问题'>Prado 中解决 Ajax 中文乱码问题</a></li>
</ol><div><p><img src="http://www.ideawu.net/favicon.ico" /> 你现在看的文章是: <a href="http://www.ideawu.net/blog/archives/534.html" title="C语言解析JSON">C语言解析JSON</a></p>

<div>
	<a href="http://www.benegg.com/linode-ad.php">
		Linode VPS - 美国虚拟主机
	</a>
	|
	<a href="http://www.udpwork.com/">
		IT牛人博客聚合网站
	</a>
</div></div>]]></description>
			<content:encoded><![CDATA[<p>最近一个 C/C++ 项目要用到 JSON, 所以选用了 <a href="http://oss.metaparadigm.com/json-c/">json-c</a> 库. C 语言不像 PHP/Python 等动态语言, 可以无缝地将 JSON 数据结构转为自身的数据结构, 所以操作起来会有些麻烦.</p>
<p>首先是数据结构. 在 json-c 里, 所有的 JSON 数据结构都是 json_object 类型, 然后这个 json_object 结构有一个 type 字段, 表明当前的对象是什么类型, 比如整数, 数组, 字符串等等. 没错, 大多数动态语言都是用类似的方法处理动态类型.</p>
<p>json-c 有自己的引用计数的内存管理机制, json_object_get() 函数用于手动地增加对象的引用计数, 相对地, json_object_put() 用于手动地减少引用计数. 要使用 json-c 必须非常明白每一个函数, 是否会增加或者减少对象的引用计数, 以避免内存泄露.</p>
<p><span id="more-534"></span>比较特殊的是, 将某个通过 xxx_new_xxx 方法创建的新对象加到另一个对象(对象容器)中(作为另一个对象的一个字段的值, 或者另一个数组的一个元素), 都不会增加新对象的引用计数. 所以, 虽然你 &#8220;new&#8221; 了一个对象, 但这时, 你却不能把它 &#8220;delete&#8221; 掉. 当你 &#8220;delete&#8221; 掉那个对象容器时, 它会自动的减少自己子节点的引用计数.</p>
<p>为了方便操作, 我写了一些辅助方法. 如, 通过点号(或者斜杠)分隔的路径获取属性:</p>
<pre>
json_object *json_util_get(json_object *obj, const char *path);
</pre>
<p>路径可以用数字来表示数组的下标. 比如 json_util_get(obj, &#8220;result.0.name&#8221;), 或者获取 obj 对象的 result 字段, 而 result 是一个数组, 读取该数组的下标为 0 的元素, 这个元素又是一个对象, 最终返回该对象的 name 属性. 因为有时候, 我们并不需要一级一级地关心中间的路径是否存在, 而只关心我们想要的最终结果是否存在. 这个方法非常有用.</p>
<p>另外, 就是数字和表示数字的字符串的问题. 在 PHP 等动态语言中, 表示数字的字符串很多情况下就是数字, 所以很难假设对方会严格地按要求且不会疏忽地把应该是 string 对象当作 int 对象传过来, 所以要在 C 语言里把这两者都当作是 int. 这又是另一个方法:</p>
<pre>
int json_util_get_int(json_object *obj, const char *path, int defval);
</pre>
<p>如果指定的字段不是整数而是字符串, 则是尝试把它转为整数返回来.</p>


<h3>Related posts:</h3><ol><li><a href='http://www.ideawu.net/blog/archives/517.html' rel='bookmark' title='Permanent Link: HTTP POST using PHP cURL'>HTTP POST using PHP cURL</a></li>
<li><a href='http://www.ideawu.net/blog/archives/388.html' rel='bookmark' title='Permanent Link: 基于列的数据库'>基于列的数据库</a></li>
<li><a href='http://www.ideawu.net/blog/archives/351.html' rel='bookmark' title='Permanent Link: 史上最强大的PHP MySQL操作类'>史上最强大的PHP MySQL操作类</a></li>
<li><a href='http://www.ideawu.net/blog/archives/494.html' rel='bookmark' title='Permanent Link: 链接包含&#8221;%2F&#8221;导致mod_rewrite失效'>链接包含&#8221;%2F&#8221;导致mod_rewrite失效</a></li>
<li><a href='http://www.ideawu.net/blog/archives/338.html' rel='bookmark' title='Permanent Link: Prado 中解决 Ajax 中文乱码问题'>Prado 中解决 Ajax 中文乱码问题</a></li>
</ol><div><p><img src="http://www.ideawu.net/favicon.ico" /> 你现在看的文章是: <a href="http://www.ideawu.net/blog/archives/534.html" title="C语言解析JSON">C语言解析JSON</a></p>

<div>
	<a href="http://www.benegg.com/linode-ad.php">
		Linode VPS - 美国虚拟主机
	</a>
	|
	<a href="http://www.udpwork.com/">
		IT牛人博客聚合网站
	</a>
</div></div>]]></content:encoded>
			<wfw:commentRss>http://www.ideawu.net/blog/archives/534.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>经典的&#8221;服务器最多65536个连接&#8221;误解</title>
		<link>http://www.ideawu.net/blog/archives/533.html</link>
		<comments>http://www.ideawu.net/blog/archives/533.html#comments</comments>
		<pubDate>Fri, 16 Jul 2010 08:44:50 +0000</pubDate>
		<dc:creator>ideawu</dc:creator>
				<category><![CDATA[C语言编程]]></category>
		<category><![CDATA[P2P/Network]]></category>

		<guid isPermaLink="false">http://www.ideawu.net/blog/archives/533.html</guid>
		<description><![CDATA[<p>&#8220;因为TCP端口号是16位无符号整数, 最大65535, 所以一台服务器最多支持65536个TCP socket连接.&#8221; &#8211; 一个非常经典的误解! 即使是有多年网络编程经验的人, 也会持有这个错误结论.</p>
<p>要戳破这个错误结论, 可以从理论和实践两方面来.</p>
<h3>理论</h3>
<p>系统通过一个四元组来唯一标识一条TCP连接. 这个四元组的结构是{local ip, local port, remote ip, remote port}, 对于IPv4, 系统理论上最多可以管理2^(32+16+32+16), 2的96次方个连接. 如果不仅仅考虑TCP, 则是一个五元组, 加上协议号(TCP, UDP或者其它).<span id="more-533"></span></p>
<h3>实践</h3>
<p>服务器绑定一个ip:port, 然后accept连接, 所有accept的连接使用的本地地址也是同样的ip:port.</p>
<h3>扩展内容</h3>
<p>如果某个客户端向同一个TCP端点(ip:port)发起主动连接, 那么每一条连接都必须使用不同的本地TCP端点, 如果客户端只有一个IP则是使用不同的本地端口, 该端口的范围在*nix系统上的一个例子是32768到61000, 可以通过如下命令查看:</p>
<pre>
[root@<a href="http://www.benegg.com/">benegg.com</a> ~]# cat /proc/sys/net/ipv4/ip_local_port_range
32768   61000
</pre>
<p>也就是说, 一个客户端连接同一个服务器(比如进行压力测试), 最多可以发起30000个左右的连接.</p>
<p>TCP客户端(TCP的主动发起者)可以在同一ip:port上向不同的服务器发起主动连接, 只需在bind之前对socket设置SO_REUSEADDR选项.</p>
<p>系统支持的最大打开文件描述符数(包括socket连接):</p>
<pre>
[root@<a href="http://www.benegg.com/">benegg.com</a> ~]# cat /proc/sys/fs/file-max
580382
</pre>
<p>单个进程所能打开的最大文件描述符数:</p>
<pre>
[root@<a href="http://www.benegg.com/">benegg.com</a> ~]# ulimit -n
1024
</pre>
<h3>结论</h3>
<p>无论是对于服务器还是客户端, 认为&#8221;一台机器最多建立65536个TCP连接&#8221;是没有根据的, 理论上远远超过这个值.</p>


<h3>Related posts:</h3><ol><li><a href='http://www.ideawu.net/blog/archives/516.html' rel='bookmark' title='Permanent Link: 连连看游戏开发实践(1) &#8211; 算法'>连连看游戏开发实践(1) &#8211; 算法</a></li>
<li><a href='http://www.ideawu.net/blog/archives/246.html' rel='bookmark' title='Permanent Link: 对P2P应用不友好的NAT'>对P2P应用不友好的NAT</a></li>
<li><a href='http://www.ideawu.net/blog/archives/169.html' rel='bookmark' title='Permanent Link: Tomcat网站server.xml设置'>Tomcat网站server.xml设置</a></li>
<li><a href='http://www.ideawu.net/blog/archives/229.html' rel='bookmark' title='Permanent Link: P2P穿透NAT的思路'>P2P穿透NAT的思路</a></li>
<li><a href='http://www.ideawu.net/blog/archives/173.html' rel='bookmark' title='Permanent Link: 在Linux安装Eclipse'>在Linux安装Eclipse</a></li>
</ol><div><p><img src="http://www.ideawu.net/favicon.ico" /> 你现在看的文章是: <a href="http://www.ideawu.net/blog/archives/533.html" title="经典的&#8221;服务器最多65536个连接&#8221;误解">经典的&#8221;服务器最多65536个连接&#8221;误解</a></p>

<div>
	<a href="http://www.benegg.com/linode-ad.php">
		Linode VPS - 美国虚拟主机
	</a>
	|
	<a href="http://www.udpwork.com/">
		IT牛人博客聚合网站
	</a>
</div></div>]]></description>
			<content:encoded><![CDATA[<p>&#8220;因为TCP端口号是16位无符号整数, 最大65535, 所以一台服务器最多支持65536个TCP socket连接.&#8221; &#8211; 一个非常经典的误解! 即使是有多年网络编程经验的人, 也会持有这个错误结论.</p>
<p>要戳破这个错误结论, 可以从理论和实践两方面来.</p>
<h3>理论</h3>
<p>系统通过一个四元组来唯一标识一条TCP连接. 这个四元组的结构是{local ip, local port, remote ip, remote port}, 对于IPv4, 系统理论上最多可以管理2^(32+16+32+16), 2的96次方个连接. 如果不仅仅考虑TCP, 则是一个五元组, 加上协议号(TCP, UDP或者其它).<span id="more-533"></span></p>
<h3>实践</h3>
<p>服务器绑定一个ip:port, 然后accept连接, 所有accept的连接使用的本地地址也是同样的ip:port.</p>
<h3>扩展内容</h3>
<p>如果某个客户端向同一个TCP端点(ip:port)发起主动连接, 那么每一条连接都必须使用不同的本地TCP端点, 如果客户端只有一个IP则是使用不同的本地端口, 该端口的范围在*nix系统上的一个例子是32768到61000, 可以通过如下命令查看:</p>
<pre>
[root@<a href="http://www.benegg.com/">benegg.com</a> ~]# cat /proc/sys/net/ipv4/ip_local_port_range
32768   61000
</pre>
<p>也就是说, 一个客户端连接同一个服务器(比如进行压力测试), 最多可以发起30000个左右的连接.</p>
<p>TCP客户端(TCP的主动发起者)可以在同一ip:port上向不同的服务器发起主动连接, 只需在bind之前对socket设置SO_REUSEADDR选项.</p>
<p>系统支持的最大打开文件描述符数(包括socket连接):</p>
<pre>
[root@<a href="http://www.benegg.com/">benegg.com</a> ~]# cat /proc/sys/fs/file-max
580382
</pre>
<p>单个进程所能打开的最大文件描述符数:</p>
<pre>
[root@<a href="http://www.benegg.com/">benegg.com</a> ~]# ulimit -n
1024
</pre>
<h3>结论</h3>
<p>无论是对于服务器还是客户端, 认为&#8221;一台机器最多建立65536个TCP连接&#8221;是没有根据的, 理论上远远超过这个值.</p>


<h3>Related posts:</h3><ol><li><a href='http://www.ideawu.net/blog/archives/516.html' rel='bookmark' title='Permanent Link: 连连看游戏开发实践(1) &#8211; 算法'>连连看游戏开发实践(1) &#8211; 算法</a></li>
<li><a href='http://www.ideawu.net/blog/archives/246.html' rel='bookmark' title='Permanent Link: 对P2P应用不友好的NAT'>对P2P应用不友好的NAT</a></li>
<li><a href='http://www.ideawu.net/blog/archives/169.html' rel='bookmark' title='Permanent Link: Tomcat网站server.xml设置'>Tomcat网站server.xml设置</a></li>
<li><a href='http://www.ideawu.net/blog/archives/229.html' rel='bookmark' title='Permanent Link: P2P穿透NAT的思路'>P2P穿透NAT的思路</a></li>
<li><a href='http://www.ideawu.net/blog/archives/173.html' rel='bookmark' title='Permanent Link: 在Linux安装Eclipse'>在Linux安装Eclipse</a></li>
</ol><div><p><img src="http://www.ideawu.net/favicon.ico" /> 你现在看的文章是: <a href="http://www.ideawu.net/blog/archives/533.html" title="经典的&#8221;服务器最多65536个连接&#8221;误解">经典的&#8221;服务器最多65536个连接&#8221;误解</a></p>

<div>
	<a href="http://www.benegg.com/linode-ad.php">
		Linode VPS - 美国虚拟主机
	</a>
	|
	<a href="http://www.udpwork.com/">
		IT牛人博客聚合网站
	</a>
</div></div>]]></content:encoded>
			<wfw:commentRss>http://www.ideawu.net/blog/archives/533.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>连连看游戏开发实践(1) &#8211; 算法</title>
		<link>http://www.ideawu.net/blog/archives/516.html</link>
		<comments>http://www.ideawu.net/blog/archives/516.html#comments</comments>
		<pubDate>Fri, 11 Jun 2010 09:01:13 +0000</pubDate>
		<dc:creator>ideawu</dc:creator>
				<category><![CDATA[C语言编程]]></category>

		<guid isPermaLink="false">http://www.ideawu.net/blog/archives/516.html</guid>
		<description><![CDATA[<p>从本篇文章开始, 我将写一序列游戏开发的文章, 讲述做一个连连看游戏的例子, 既锻炼自己, 也帮助别人. 最终, 游戏会加上网络功能.</p>
<h2>连连看算法</h2>
<p><a href="http://www.benegg.com/game/wp-content/uploads/2009/05/e8bf9ee8bf9ee79c8be7ae97e6b395.jpg"><img src="http://www.benegg.com/game/wp-content/uploads/2009/05/e8bf9ee8bf9ee79c8be7ae97e6b395-300x179.jpg" alt="" title="连连看算法" width="300" height="179" class="alignnone size-medium wp-image-35" /></a></p>
<p>如图, 为了找出A, B两点之间的连接路径, 首先过这两点作4条线段, 线段的两端便是地图边缘, 两条与横坐标轴平行, 另两条与纵坐标轴平行. 先考虑与横坐标轴平行的两条.</p>
<p>在两条线段上各取一点C和D, 此两点处在一条与纵坐标轴平行的直线上. 那么, ACDB这条路径便是一条可能的A, B两点的连通路径.</p>
<p><span id="more-516"></span>C, D两点在两条线段上移动, 直到找出一条有效的连通路径, 或者最终得出结论不存在这样的路径.</p>
<p>按同样的方式在与纵坐标轴平行的两条线段上查找.</p>
<h2>算法优化</h2>
<p>两点的连通路径应该是最短的, 所以, 查找从A, B所处的矩形的中线开始, 同时从上下左右4个方面查找, 可以找到看起来最短的连通路径.</p>
<p><a href="http://www.benegg.com/game/wp-content/uploads/2009/05/e8bf9ee8bf9ee79c8be7ae97e6b3952.jpg"><img src="http://www.benegg.com/game/wp-content/uploads/2009/05/e8bf9ee8bf9ee79c8be7ae97e6b3952-300x179.jpg" alt="" title="连连看算法图形演示" width="300" height="179" class="alignnone size-medium wp-image-36" /></a></p>
<h2>连连看算法的编程语言实现</h2>
<p>程序创建一个方形的格子地图, 并随机在格子上生成障碍. 用户输入想要连接的A, B两点, 然后系统输出两点的连通线(A, C, D, B).</p>
<p>算法作如下几个判断:</p>
<p>* A, B不是同一点.<br />
* A, B两点的图形相同.<br />
* AC, CD, DB 3条线段连通, 检查时不包括线段端点.<br />
* 如果C, D不是与A, B重合, C, D必须无障碍.</p>
<p>判断停止条件:</p>
<p>* C, D任意一点到达屏幕边界.</p>
<p>程序执行效果图:</p>
<pre>
    0  1  2  3  4
  +---------------+
0 | 1  1     3  2 | 0
1 | 3        1  1 | 1
2 | 3           3 | 2
3 | 3        1    | 3
4 |    1        1 | 4
  +---------------+
    0  1  2  3  4
input point(x1,y1 x2,y2): <b>3,0 0,3</b>
path: (3,0) - (3,2) - (0,2) - (0,3)
    0  1  2  3  4
  +---------------+
0 | 1  1  *  <b>@</b>  2 | 0
1 | 3     *  1  1 | 1
2 | 3     *     3 | 2
3 | <b>@</b>  *  *  1    | 3
4 |    1        1 | 4
  +---------------+
    0  1  2  3  4
</pre>
<p>本篇文章介绍了一个命令行下的连连看游戏程序, 下一篇文章将给连连看做一个图形外壳, 用鼠标来选择两点.</p>
<p>示例源码下载: <a href='http://www.benegg.com/game/wp-content/uploads/2009/05/llk.zip'>llk.zip: 命令行下的连连看游戏源码</a>, 包含Windows下的可执行程序.</p>
<p>原发在: <a href="http://www.benegg.com/game/archives/34.html">http://www.benegg.com/game/archives/34.html</a></p>


<h3>Related posts:</h3><ol><li><a href='http://www.ideawu.net/blog/archives/116.html' rel='bookmark' title='Permanent Link: 告诉我应该选择哪一个Linux发行版'>告诉我应该选择哪一个Linux发行版</a></li>
<li><a href='http://www.ideawu.net/blog/archives/263.html' rel='bookmark' title='Permanent Link: PHP str_replace 函数的参数设计不合理之处'>PHP str_replace 函数的参数设计不合理之处</a></li>
<li><a href='http://www.ideawu.net/blog/archives/495.html' rel='bookmark' title='Permanent Link: 开发搜索引擎 &#8211; PHP中文分词'>开发搜索引擎 &#8211; PHP中文分词</a></li>
<li><a href='http://www.ideawu.net/blog/archives/534.html' rel='bookmark' title='Permanent Link: C语言解析JSON'>C语言解析JSON</a></li>
<li><a href='http://www.ideawu.net/blog/archives/87.html' rel='bookmark' title='Permanent Link: Debian Linux 系统提速'>Debian Linux 系统提速</a></li>
</ol><div><p><img src="http://www.ideawu.net/favicon.ico" /> 你现在看的文章是: <a href="http://www.ideawu.net/blog/archives/516.html" title="连连看游戏开发实践(1) &#8211; 算法">连连看游戏开发实践(1) &#8211; 算法</a></p>

<div>
	<a href="http://www.benegg.com/linode-ad.php">
		Linode VPS - 美国虚拟主机
	</a>
	|
	<a href="http://www.udpwork.com/">
		IT牛人博客聚合网站
	</a>
</div></div>]]></description>
			<content:encoded><![CDATA[<p>从本篇文章开始, 我将写一序列游戏开发的文章, 讲述做一个连连看游戏的例子, 既锻炼自己, 也帮助别人. 最终, 游戏会加上网络功能.</p>
<h2>连连看算法</h2>
<p><a href="http://www.benegg.com/game/wp-content/uploads/2009/05/e8bf9ee8bf9ee79c8be7ae97e6b395.jpg"><img src="http://www.benegg.com/game/wp-content/uploads/2009/05/e8bf9ee8bf9ee79c8be7ae97e6b395-300x179.jpg" alt="" title="连连看算法" width="300" height="179" class="alignnone size-medium wp-image-35" /></a></p>
<p>如图, 为了找出A, B两点之间的连接路径, 首先过这两点作4条线段, 线段的两端便是地图边缘, 两条与横坐标轴平行, 另两条与纵坐标轴平行. 先考虑与横坐标轴平行的两条.</p>
<p>在两条线段上各取一点C和D, 此两点处在一条与纵坐标轴平行的直线上. 那么, ACDB这条路径便是一条可能的A, B两点的连通路径.</p>
<p><span id="more-516"></span>C, D两点在两条线段上移动, 直到找出一条有效的连通路径, 或者最终得出结论不存在这样的路径.</p>
<p>按同样的方式在与纵坐标轴平行的两条线段上查找.</p>
<h2>算法优化</h2>
<p>两点的连通路径应该是最短的, 所以, 查找从A, B所处的矩形的中线开始, 同时从上下左右4个方面查找, 可以找到看起来最短的连通路径.</p>
<p><a href="http://www.benegg.com/game/wp-content/uploads/2009/05/e8bf9ee8bf9ee79c8be7ae97e6b3952.jpg"><img src="http://www.benegg.com/game/wp-content/uploads/2009/05/e8bf9ee8bf9ee79c8be7ae97e6b3952-300x179.jpg" alt="" title="连连看算法图形演示" width="300" height="179" class="alignnone size-medium wp-image-36" /></a></p>
<h2>连连看算法的编程语言实现</h2>
<p>程序创建一个方形的格子地图, 并随机在格子上生成障碍. 用户输入想要连接的A, B两点, 然后系统输出两点的连通线(A, C, D, B).</p>
<p>算法作如下几个判断:</p>
<p>* A, B不是同一点.<br />
* A, B两点的图形相同.<br />
* AC, CD, DB 3条线段连通, 检查时不包括线段端点.<br />
* 如果C, D不是与A, B重合, C, D必须无障碍.</p>
<p>判断停止条件:</p>
<p>* C, D任意一点到达屏幕边界.</p>
<p>程序执行效果图:</p>
<pre>
    0  1  2  3  4
  +---------------+
0 | 1  1     3  2 | 0
1 | 3        1  1 | 1
2 | 3           3 | 2
3 | 3        1    | 3
4 |    1        1 | 4
  +---------------+
    0  1  2  3  4
input point(x1,y1 x2,y2): <b>3,0 0,3</b>
path: (3,0) - (3,2) - (0,2) - (0,3)
    0  1  2  3  4
  +---------------+
0 | 1  1  *  <b>@</b>  2 | 0
1 | 3     *  1  1 | 1
2 | 3     *     3 | 2
3 | <b>@</b>  *  *  1    | 3
4 |    1        1 | 4
  +---------------+
    0  1  2  3  4
</pre>
<p>本篇文章介绍了一个命令行下的连连看游戏程序, 下一篇文章将给连连看做一个图形外壳, 用鼠标来选择两点.</p>
<p>示例源码下载: <a href='http://www.benegg.com/game/wp-content/uploads/2009/05/llk.zip'>llk.zip: 命令行下的连连看游戏源码</a>, 包含Windows下的可执行程序.</p>
<p>原发在: <a href="http://www.benegg.com/game/archives/34.html">http://www.benegg.com/game/archives/34.html</a></p>


<h3>Related posts:</h3><ol><li><a href='http://www.ideawu.net/blog/archives/116.html' rel='bookmark' title='Permanent Link: 告诉我应该选择哪一个Linux发行版'>告诉我应该选择哪一个Linux发行版</a></li>
<li><a href='http://www.ideawu.net/blog/archives/263.html' rel='bookmark' title='Permanent Link: PHP str_replace 函数的参数设计不合理之处'>PHP str_replace 函数的参数设计不合理之处</a></li>
<li><a href='http://www.ideawu.net/blog/archives/495.html' rel='bookmark' title='Permanent Link: 开发搜索引擎 &#8211; PHP中文分词'>开发搜索引擎 &#8211; PHP中文分词</a></li>
<li><a href='http://www.ideawu.net/blog/archives/534.html' rel='bookmark' title='Permanent Link: C语言解析JSON'>C语言解析JSON</a></li>
<li><a href='http://www.ideawu.net/blog/archives/87.html' rel='bookmark' title='Permanent Link: Debian Linux 系统提速'>Debian Linux 系统提速</a></li>
</ol><div><p><img src="http://www.ideawu.net/favicon.ico" /> 你现在看的文章是: <a href="http://www.ideawu.net/blog/archives/516.html" title="连连看游戏开发实践(1) &#8211; 算法">连连看游戏开发实践(1) &#8211; 算法</a></p>

<div>
	<a href="http://www.benegg.com/linode-ad.php">
		Linode VPS - 美国虚拟主机
	</a>
	|
	<a href="http://www.udpwork.com/">
		IT牛人博客聚合网站
	</a>
</div></div>]]></content:encoded>
			<wfw:commentRss>http://www.ideawu.net/blog/archives/516.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>编写基于TCP的应用程序</title>
		<link>http://www.ideawu.net/blog/archives/429.html</link>
		<comments>http://www.ideawu.net/blog/archives/429.html#comments</comments>
		<pubDate>Mon, 12 Oct 2009 07:15:52 +0000</pubDate>
		<dc:creator>ideawu</dc:creator>
				<category><![CDATA[C语言编程]]></category>
		<category><![CDATA[P2P/Network]]></category>

		<guid isPermaLink="false">http://www.ideawu.net/blog/?p=429</guid>
		<description><![CDATA[<p>这似乎是一个非常简单的话题, 就跟&#8221;是个人就能做网站&#8221;一样, 你可能也认为&#8221;是个人就能写使用TCP socket的网络程序&#8221;. 不过, 下面介绍的几个基本的原理的做法, 你可能并没有理解.</p>
<p>TCP是一种流式的协议, 简单的说, TCP不检查数据的语义, 更不会检查数据的边界. 而应用层一般使用的是报文协议. 为此, 产生了一些特定的用法和模式.</p>
<p>有几种方式可用来实现报文协议:</p>
<p>1. 明确声明报文数据的长度.<br />
2. 使用分隔符.<br />
3. 发送方发送完数据后关闭连接.</p>
<p>第3种是socket的特定用法.</p>
<p><span id="more-429"></span>很难被理解的常用的TCP应用程序惯用法:</p>
<h3>1. 必须使用循环来发送数据</h3>
<p>对于原始的socket, 发送数据的函数是write:</p>
<p>ssize_t write(int fd, const void *buf, size_t count);</p>
<p>但write可能只发送你请求的数据的前面一部分, 也就是说, write返回值(表示已发送的的字节数)可能小于参数中的count. 所以, 你应该在循环中调用 write, 并检查返回值. 请认真的看看 APUE(Advanced Programming in the UNIX)的相关内容.</p>
<h3>2. 必须使用循环来接收数据</h3>
<p>读取数据的接口函数:</p>
<p>ssize_t read(int fd, void *buf, size_t count);</p>
<p>我常常见到有些人, 因为没有完整地接收到的发送方发送的数据, 而报怨发送方调用了多次write方法. 这是一种错误的报怨, 基于对TCP的错误理解. <strong>*无论对方调用多少次write, 你都不能只调用一次read! 即使你把接收缓冲设置为1GB也不行!*</strong></p>
<p>首先, 发送方调用write, 把数据拷贝到发送方的发送缓冲区, 然后发送方的网络子系统一段(fragment)一段地发送缓冲区中的数据. 接收方的网络子系统将这些数据片段按顺序组装到接收缓冲区中, 一旦进入接收缓冲, 就不存在片段的说法. 接收方调用read方法, 可能读取部分或者全部缓冲区中的数据后返回, 如果只是部分, 这部分的数据和分段没有任何联系 &#8211; 记住这一点!</p>
<h3>3. 标准IO接口只调用一次fgets/fputs</h3>
<p>标准IO的gets/puts向上提供了基于报文的接口, 它们检查缓冲区中数据的分隔符&#8217;\n&#8217;, 以便分隔出报文. 所以, 当你只调用一次gets就能读取对方调用一次puts发送的数据时, 不要感到惊讶. 标准IO帮你封装了循环读和写.</p>
<h3>4. 总是在字符串的结尾加上&#8217;\0&#8242;</h3>
<p>如果你想把某一段字节数组当作C字符串来处理, 那么你必须手动地在字符串应该是&#8217;\0&#8242;的地方加上&#8217;\0&#8242;. 例如, 如果你认为ptr[0-5](共6个字节的数据, 最后一个字节的值应该是&#8217;\0&#8242;)是一个字符串, 那么, 在进行处理之前, 应该执行ptr[5] = &#8216;\0&#8242;; 注意, 千万不要执行ptr[strlen(ptr)] = &#8216;\0&#8242;! 这样, 才能保证无论对方是无意或者恶意地没有包含&#8217;\0&#8242;, 你都能安全地进行处理. 另外, 不必在接收前执行类似memset(ptr, 0, BUFLEN)的语句, 这样会浪费一丁点的性能, 只修改一个字节总比修改6个或者更多的字节速度更快.</p>


<h3>Related posts:</h3><ol><li><a href='http://www.ideawu.net/blog/archives/307.html' rel='bookmark' title='Permanent Link: 关于 C++ 中的函数指针'>关于 C++ 中的函数指针</a></li>
<li><a href='http://www.ideawu.net/blog/archives/497.html' rel='bookmark' title='Permanent Link: 用脚本语言开发网游 &#8211; C整合Python'>用脚本语言开发网游 &#8211; C整合Python</a></li>
<li><a href='http://www.ideawu.net/blog/archives/570.html' rel='bookmark' title='Permanent Link: Linus又骂人stupid'>Linus又骂人stupid</a></li>
<li><a href='http://www.ideawu.net/blog/archives/267.html' rel='bookmark' title='Permanent Link: 软件体系结构模式-层'>软件体系结构模式-层</a></li>
<li><a href='http://www.ideawu.net/blog/archives/590.html' rel='bookmark' title='Permanent Link: MySQL&#8221;海量数据&#8221;查询性能分析'>MySQL&#8221;海量数据&#8221;查询性能分析</a></li>
</ol><div><p><img src="http://www.ideawu.net/favicon.ico" /> 你现在看的文章是: <a href="http://www.ideawu.net/blog/archives/429.html" title="编写基于TCP的应用程序">编写基于TCP的应用程序</a></p>

<div>
	<a href="http://www.benegg.com/linode-ad.php">
		Linode VPS - 美国虚拟主机
	</a>
	|
	<a href="http://www.udpwork.com/">
		IT牛人博客聚合网站
	</a>
</div></div>]]></description>
			<content:encoded><![CDATA[<p>这似乎是一个非常简单的话题, 就跟&#8221;是个人就能做网站&#8221;一样, 你可能也认为&#8221;是个人就能写使用TCP socket的网络程序&#8221;. 不过, 下面介绍的几个基本的原理的做法, 你可能并没有理解.</p>
<p>TCP是一种流式的协议, 简单的说, TCP不检查数据的语义, 更不会检查数据的边界. 而应用层一般使用的是报文协议. 为此, 产生了一些特定的用法和模式.</p>
<p>有几种方式可用来实现报文协议:</p>
<p>1. 明确声明报文数据的长度.<br />
2. 使用分隔符.<br />
3. 发送方发送完数据后关闭连接.</p>
<p>第3种是socket的特定用法.</p>
<p><span id="more-429"></span>很难被理解的常用的TCP应用程序惯用法:</p>
<h3>1. 必须使用循环来发送数据</h3>
<p>对于原始的socket, 发送数据的函数是write:</p>
<p>ssize_t write(int fd, const void *buf, size_t count);</p>
<p>但write可能只发送你请求的数据的前面一部分, 也就是说, write返回值(表示已发送的的字节数)可能小于参数中的count. 所以, 你应该在循环中调用 write, 并检查返回值. 请认真的看看 APUE(Advanced Programming in the UNIX)的相关内容.</p>
<h3>2. 必须使用循环来接收数据</h3>
<p>读取数据的接口函数:</p>
<p>ssize_t read(int fd, void *buf, size_t count);</p>
<p>我常常见到有些人, 因为没有完整地接收到的发送方发送的数据, 而报怨发送方调用了多次write方法. 这是一种错误的报怨, 基于对TCP的错误理解. <strong>*无论对方调用多少次write, 你都不能只调用一次read! 即使你把接收缓冲设置为1GB也不行!*</strong></p>
<p>首先, 发送方调用write, 把数据拷贝到发送方的发送缓冲区, 然后发送方的网络子系统一段(fragment)一段地发送缓冲区中的数据. 接收方的网络子系统将这些数据片段按顺序组装到接收缓冲区中, 一旦进入接收缓冲, 就不存在片段的说法. 接收方调用read方法, 可能读取部分或者全部缓冲区中的数据后返回, 如果只是部分, 这部分的数据和分段没有任何联系 &#8211; 记住这一点!</p>
<h3>3. 标准IO接口只调用一次fgets/fputs</h3>
<p>标准IO的gets/puts向上提供了基于报文的接口, 它们检查缓冲区中数据的分隔符&#8217;\n&#8217;, 以便分隔出报文. 所以, 当你只调用一次gets就能读取对方调用一次puts发送的数据时, 不要感到惊讶. 标准IO帮你封装了循环读和写.</p>
<h3>4. 总是在字符串的结尾加上&#8217;\0&#8242;</h3>
<p>如果你想把某一段字节数组当作C字符串来处理, 那么你必须手动地在字符串应该是&#8217;\0&#8242;的地方加上&#8217;\0&#8242;. 例如, 如果你认为ptr[0-5](共6个字节的数据, 最后一个字节的值应该是&#8217;\0&#8242;)是一个字符串, 那么, 在进行处理之前, 应该执行ptr[5] = &#8216;\0&#8242;; 注意, 千万不要执行ptr[strlen(ptr)] = &#8216;\0&#8242;! 这样, 才能保证无论对方是无意或者恶意地没有包含&#8217;\0&#8242;, 你都能安全地进行处理. 另外, 不必在接收前执行类似memset(ptr, 0, BUFLEN)的语句, 这样会浪费一丁点的性能, 只修改一个字节总比修改6个或者更多的字节速度更快.</p>


<h3>Related posts:</h3><ol><li><a href='http://www.ideawu.net/blog/archives/307.html' rel='bookmark' title='Permanent Link: 关于 C++ 中的函数指针'>关于 C++ 中的函数指针</a></li>
<li><a href='http://www.ideawu.net/blog/archives/497.html' rel='bookmark' title='Permanent Link: 用脚本语言开发网游 &#8211; C整合Python'>用脚本语言开发网游 &#8211; C整合Python</a></li>
<li><a href='http://www.ideawu.net/blog/archives/570.html' rel='bookmark' title='Permanent Link: Linus又骂人stupid'>Linus又骂人stupid</a></li>
<li><a href='http://www.ideawu.net/blog/archives/267.html' rel='bookmark' title='Permanent Link: 软件体系结构模式-层'>软件体系结构模式-层</a></li>
<li><a href='http://www.ideawu.net/blog/archives/590.html' rel='bookmark' title='Permanent Link: MySQL&#8221;海量数据&#8221;查询性能分析'>MySQL&#8221;海量数据&#8221;查询性能分析</a></li>
</ol><div><p><img src="http://www.ideawu.net/favicon.ico" /> 你现在看的文章是: <a href="http://www.ideawu.net/blog/archives/429.html" title="编写基于TCP的应用程序">编写基于TCP的应用程序</a></p>

<div>
	<a href="http://www.benegg.com/linode-ad.php">
		Linode VPS - 美国虚拟主机
	</a>
	|
	<a href="http://www.udpwork.com/">
		IT牛人博客聚合网站
	</a>
</div></div>]]></content:encoded>
			<wfw:commentRss>http://www.ideawu.net/blog/archives/429.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>C语言类函数宏的参数</title>
		<link>http://www.ideawu.net/blog/archives/416.html</link>
		<comments>http://www.ideawu.net/blog/archives/416.html#comments</comments>
		<pubDate>Sat, 22 Aug 2009 05:47:33 +0000</pubDate>
		<dc:creator>ideawu</dc:creator>
				<category><![CDATA[C语言编程]]></category>

		<guid isPermaLink="false">http://www.ideawu.net/blog/?p=416</guid>
		<description><![CDATA[<p>宏很有用, 小心别上瘾.</p>
<p>1. Stringification, 把参数作为C字符串, &#8220;#&#8221;.</p>
<p>#define M(a) #a</p>
<p>M(hello) => &#8220;hello&#8221;</p>
<p>2. Concatenation, 字面替换和拼接, &#8220;##&#8221;.</p>
<p>#define M(a) a ## _b</p>
<p>M(hello) => hello_b</p>
<p>## 两边可以放空白字符和注释.</p>
<p>参考: <a href="http://www.redhat.com/docs/manuals/enterprise/RHEL-3-Manual/cpp/macros.html">Red Hat Enterprise Linux 3: Using cpp, the C Preprocessor</a></p>


<h3>Related posts:</h3><ol><li><a href='http://www.ideawu.net/blog/archives/465.html' rel='bookmark' title='Permanent Link: Wordpress开发指南'>Wordpress开发指南</a></li>
<li><a href='http://www.ideawu.net/blog/archives/230.html' rel='bookmark' title='Permanent Link: 我要转到 Windows 平台了'>我要转到 Windows 平台了</a></li>
<li><a href='http://www.ideawu.net/blog/archives/141.html' rel='bookmark' title='Permanent Link: Linux发行版的选择'>Linux发行版的选择</a></li>
<li><a href='http://www.ideawu.net/blog/archives/432.html' rel='bookmark' title='Permanent Link: 如何为Linux生成和打上patch'>如何为Linux生成和打上patch</a></li>
<li><a href='http://www.ideawu.net/blog/archives/382.html' rel='bookmark' title='Permanent Link: C 语言常见问题集 (中文)'>C 语言常见问题集 (中文)</a></li>
</ol><div><p><img src="http://www.ideawu.net/favicon.ico" /> 你现在看的文章是: <a href="http://www.ideawu.net/blog/archives/416.html" title="C语言类函数宏的参数">C语言类函数宏的参数</a></p>

<div>
	<a href="http://www.benegg.com/linode-ad.php">
		Linode VPS - 美国虚拟主机
	</a>
	|
	<a href="http://www.udpwork.com/">
		IT牛人博客聚合网站
	</a>
</div></div>]]></description>
			<content:encoded><![CDATA[<p>宏很有用, 小心别上瘾.</p>
<p>1. Stringification, 把参数作为C字符串, &#8220;#&#8221;.</p>
<p>#define M(a) #a</p>
<p>M(hello) => &#8220;hello&#8221;</p>
<p>2. Concatenation, 字面替换和拼接, &#8220;##&#8221;.</p>
<p>#define M(a) a ## _b</p>
<p>M(hello) => hello_b</p>
<p>## 两边可以放空白字符和注释.</p>
<p>参考: <a href="http://www.redhat.com/docs/manuals/enterprise/RHEL-3-Manual/cpp/macros.html">Red Hat Enterprise Linux 3: Using cpp, the C Preprocessor</a></p>


<h3>Related posts:</h3><ol><li><a href='http://www.ideawu.net/blog/archives/465.html' rel='bookmark' title='Permanent Link: Wordpress开发指南'>Wordpress开发指南</a></li>
<li><a href='http://www.ideawu.net/blog/archives/230.html' rel='bookmark' title='Permanent Link: 我要转到 Windows 平台了'>我要转到 Windows 平台了</a></li>
<li><a href='http://www.ideawu.net/blog/archives/141.html' rel='bookmark' title='Permanent Link: Linux发行版的选择'>Linux发行版的选择</a></li>
<li><a href='http://www.ideawu.net/blog/archives/432.html' rel='bookmark' title='Permanent Link: 如何为Linux生成和打上patch'>如何为Linux生成和打上patch</a></li>
<li><a href='http://www.ideawu.net/blog/archives/382.html' rel='bookmark' title='Permanent Link: C 语言常见问题集 (中文)'>C 语言常见问题集 (中文)</a></li>
</ol><div><p><img src="http://www.ideawu.net/favicon.ico" /> 你现在看的文章是: <a href="http://www.ideawu.net/blog/archives/416.html" title="C语言类函数宏的参数">C语言类函数宏的参数</a></p>

<div>
	<a href="http://www.benegg.com/linode-ad.php">
		Linode VPS - 美国虚拟主机
	</a>
	|
	<a href="http://www.udpwork.com/">
		IT牛人博客聚合网站
	</a>
</div></div>]]></content:encoded>
			<wfw:commentRss>http://www.ideawu.net/blog/archives/416.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>fdevent &#8211; 方便的跨平台IO多路复用接口</title>
		<link>http://www.ideawu.net/blog/archives/395.html</link>
		<comments>http://www.ideawu.net/blog/archives/395.html#comments</comments>
		<pubDate>Thu, 25 Jun 2009 08:21:28 +0000</pubDate>
		<dc:creator>ideawu</dc:creator>
				<category><![CDATA[C语言编程]]></category>
		<category><![CDATA[P2P/Network]]></category>

		<guid isPermaLink="false">http://www.ideawu.net/blog/?p=395</guid>
		<description><![CDATA[<p>fdevent是一套方便的跨平台IO多路复用C语言接口, 主要想法来自 epoll 和 lighttpd 的 fdevent, 接口的使用几乎和 epoll 一样.</p>
<h3>示例</h3>
<pre lang="c" line="1">
while(1) {
    nfds = fdevents_wait(evs, 1000);
    if(nfds == 0){
        //printf("timeout\n");
        continue;
    }

    for(i = 0; i &lt; nfds; i++) {
        fde = evs-&gt;events[i];

        if(fde->flags &#038; FDEVENT_IN){
            // ...
        }

        if(fde->flags &#038; FDEVENT_OUT){
            // ...
        }
    }
}
</pre>
<p>项目主页: <a href="http://www.ideawu.net/person/fdevent/">http://www.ideawu.net/person/fdevent/</a></p>


<h3>Related posts:</h3><ol><li><a href='http://www.ideawu.net/blog/archives/535.html' rel='bookmark' title='Permanent Link: Master-Workers 模式处理高负载'>Master-Workers 模式处理高负载</a></li>
<li><a href='http://www.ideawu.net/blog/archives/240.html' rel='bookmark' title='Permanent Link: 文件共享协议'>文件共享协议</a></li>
<li><a href='http://www.ideawu.net/blog/archives/556.html' rel='bookmark' title='Permanent Link: lighttpd配置HTTPS(SSL)'>lighttpd配置HTTPS(SSL)</a></li>
<li><a href='http://www.ideawu.net/blog/archives/554.html' rel='bookmark' title='Permanent Link: tableview新增单选功能'>tableview新增单选功能</a></li>
<li><a href='http://www.ideawu.net/blog/archives/502.html' rel='bookmark' title='Permanent Link: tableview新版本发布'>tableview新版本发布</a></li>
</ol><div><p><img src="http://www.ideawu.net/favicon.ico" /> 你现在看的文章是: <a href="http://www.ideawu.net/blog/archives/395.html" title="fdevent &#8211; 方便的跨平台IO多路复用接口">fdevent &#8211; 方便的跨平台IO多路复用接口</a></p>

<div>
	<a href="http://www.benegg.com/linode-ad.php">
		Linode VPS - 美国虚拟主机
	</a>
	|
	<a href="http://www.udpwork.com/">
		IT牛人博客聚合网站
	</a>
</div></div>]]></description>
			<content:encoded><![CDATA[<p>fdevent是一套方便的跨平台IO多路复用C语言接口, 主要想法来自 epoll 和 lighttpd 的 fdevent, 接口的使用几乎和 epoll 一样.</p>
<h3>示例</h3>
<pre lang="c" line="1">
while(1) {
    nfds = fdevents_wait(evs, 1000);
    if(nfds == 0){
        //printf("timeout\n");
        continue;
    }

    for(i = 0; i &lt; nfds; i++) {
        fde = evs-&gt;events[i];

        if(fde->flags &#038; FDEVENT_IN){
            // ...
        }

        if(fde->flags &#038; FDEVENT_OUT){
            // ...
        }
    }
}
</pre>
<p>项目主页: <a href="http://www.ideawu.net/person/fdevent/">http://www.ideawu.net/person/fdevent/</a></p>


<h3>Related posts:</h3><ol><li><a href='http://www.ideawu.net/blog/archives/535.html' rel='bookmark' title='Permanent Link: Master-Workers 模式处理高负载'>Master-Workers 模式处理高负载</a></li>
<li><a href='http://www.ideawu.net/blog/archives/240.html' rel='bookmark' title='Permanent Link: 文件共享协议'>文件共享协议</a></li>
<li><a href='http://www.ideawu.net/blog/archives/556.html' rel='bookmark' title='Permanent Link: lighttpd配置HTTPS(SSL)'>lighttpd配置HTTPS(SSL)</a></li>
<li><a href='http://www.ideawu.net/blog/archives/554.html' rel='bookmark' title='Permanent Link: tableview新增单选功能'>tableview新增单选功能</a></li>
<li><a href='http://www.ideawu.net/blog/archives/502.html' rel='bookmark' title='Permanent Link: tableview新版本发布'>tableview新版本发布</a></li>
</ol><div><p><img src="http://www.ideawu.net/favicon.ico" /> 你现在看的文章是: <a href="http://www.ideawu.net/blog/archives/395.html" title="fdevent &#8211; 方便的跨平台IO多路复用接口">fdevent &#8211; 方便的跨平台IO多路复用接口</a></p>

<div>
	<a href="http://www.benegg.com/linode-ad.php">
		Linode VPS - 美国虚拟主机
	</a>
	|
	<a href="http://www.udpwork.com/">
		IT牛人博客聚合网站
	</a>
</div></div>]]></content:encoded>
			<wfw:commentRss>http://www.ideawu.net/blog/archives/395.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C 语言常见问题集 (中文)</title>
		<link>http://www.ideawu.net/blog/archives/382.html</link>
		<comments>http://www.ideawu.net/blog/archives/382.html#comments</comments>
		<pubDate>Tue, 12 May 2009 02:52:16 +0000</pubDate>
		<dc:creator>ideawu</dc:creator>
				<category><![CDATA[C语言编程]]></category>

		<guid isPermaLink="false">http://www.ideawu.net/blog/?p=382</guid>
		<description><![CDATA[<p>c-faq可以说是全世界c程序员的结晶, 无论对c初学者还是高手, 都非常有帮助, 是需要常备身边的手册. 中文版由孙云(sunyun.s@gmail.com, 1-12章)和朱群英(zhu.qunying@gmail.com, 13-20章、LaTeX 文件编辑)翻译.</p>
<h3>中文版</h3>
<p><a href="http://c-faq-chn.sourceforge.net/">网站: http://c-faq-chn.sourceforge.net/</a><br />
<a href="http://c-faq-chn.sourceforge.net/ccfaq/index.html">C 语言常见问题集 HTML 版本(在线阅读）</a><br />
<a href="http://prdownloads.sourceforge.net/c-faq-chn/ccfaq-html-0.9.4.tgz?download">HTML 版本下载</a><br />
<a href="http://prdownloads.sourceforge.net/c-faq-chn/ccfaq-0.9.4.pdf.gz?download">PDF 版本下载 </a></p>
<p><strong>目录</strong><br />
1. 前言<br />
2. 声明和初始化<br />
3. 结构、联合和枚举<br />
4. 表达式<br />
5. 指针<br />
6. 空 (null) 指针<br />
7. 数组和指针<br />
8. 内存分配<br />
9. 字符和字符串<br />
10. 布尔表达式和变量<br />
11. C 预处理器<br />
12. ANSI/ISO 标准 C<br />
13. 标准输入输出库<br />
14. 库函数<br />
15. 浮点运算<br />
16. 可变参数<br />
17. 奇怪的问题<br />
18. 风格<br />
19. 工具和资源<br />
20. 系统依赖<br />
21. 杂项<br />
22. 感谢<br />
文献</p>
<h3>英文版的目录:</h3>
<p><a href="http://c-faq.com/">网站: http://c-faq.com/</a></p>
<p><strong>目录</strong><br />
1. Declarations and Initializations<br />
2. Structures, Unions, and Enumerations<br />
3. Expressions<br />
4. Pointers<br />
5. Null Pointers<br />
6. Arrays and Pointers<br />
7. Memory Allocation<br />
8. Characters and Strings<br />
9. Boolean Expressions and Variables<br />
10. C Preprocessor<br />
11. ANSI/ISO Standard C<br />
12. Stdio<br />
13. Library Functions<br />
14. Floating Point<br />
15. Variable-Length Argument Lists<br />
16. Strange Problems<br />
17. Style<br />
18. Tools and Resources<br />
19. System Dependencies<br />
20. Miscellaneous<br />
Glossary<br />
Bibliography<br />
Acknowledgements</p>


<h3>Related posts:</h3><ol><li><a href='http://www.ideawu.net/blog/archives/155.html' rel='bookmark' title='Permanent Link: 如何使用ServletContextListener'>如何使用ServletContextListener</a></li>
<li><a href='http://www.ideawu.net/blog/archives/591.html' rel='bookmark' title='Permanent Link: jQuery延时绑定事件(lazy-bind)'>jQuery延时绑定事件(lazy-bind)</a></li>
<li><a href='http://www.ideawu.net/blog/archives/417.html' rel='bookmark' title='Permanent Link: MySQL 建立外键约束'>MySQL 建立外键约束</a></li>
<li><a href='http://www.ideawu.net/blog/archives/357.html' rel='bookmark' title='Permanent Link: MySQL 查询使用 Group By 的注意点'>MySQL 查询使用 Group By 的注意点</a></li>
<li><a href='http://www.ideawu.net/blog/archives/607.html' rel='bookmark' title='Permanent Link: 获取动态加载的图片大小的正确方法'>获取动态加载的图片大小的正确方法</a></li>
</ol><div><p><img src="http://www.ideawu.net/favicon.ico" /> 你现在看的文章是: <a href="http://www.ideawu.net/blog/archives/382.html" title="C 语言常见问题集 (中文)">C 语言常见问题集 (中文)</a></p>

<div>
	<a href="http://www.benegg.com/linode-ad.php">
		Linode VPS - 美国虚拟主机
	</a>
	|
	<a href="http://www.udpwork.com/">
		IT牛人博客聚合网站
	</a>
</div></div>]]></description>
			<content:encoded><![CDATA[<p>c-faq可以说是全世界c程序员的结晶, 无论对c初学者还是高手, 都非常有帮助, 是需要常备身边的手册. 中文版由孙云(sunyun.s@gmail.com, 1-12章)和朱群英(zhu.qunying@gmail.com, 13-20章、LaTeX 文件编辑)翻译.</p>
<h3>中文版</h3>
<p><a href="http://c-faq-chn.sourceforge.net/">网站: http://c-faq-chn.sourceforge.net/</a><br />
<a href="http://c-faq-chn.sourceforge.net/ccfaq/index.html">C 语言常见问题集 HTML 版本(在线阅读）</a><br />
<a href="http://prdownloads.sourceforge.net/c-faq-chn/ccfaq-html-0.9.4.tgz?download">HTML 版本下载</a><br />
<a href="http://prdownloads.sourceforge.net/c-faq-chn/ccfaq-0.9.4.pdf.gz?download">PDF 版本下载 </a></p>
<p><strong>目录</strong><br />
1. 前言<br />
2. 声明和初始化<br />
3. 结构、联合和枚举<br />
4. 表达式<br />
5. 指针<br />
6. 空 (null) 指针<br />
7. 数组和指针<br />
8. 内存分配<br />
9. 字符和字符串<br />
10. 布尔表达式和变量<br />
11. C 预处理器<br />
12. ANSI/ISO 标准 C<br />
13. 标准输入输出库<br />
14. 库函数<br />
15. 浮点运算<br />
16. 可变参数<br />
17. 奇怪的问题<br />
18. 风格<br />
19. 工具和资源<br />
20. 系统依赖<br />
21. 杂项<br />
22. 感谢<br />
文献</p>
<h3>英文版的目录:</h3>
<p><a href="http://c-faq.com/">网站: http://c-faq.com/</a></p>
<p><strong>目录</strong><br />
1. Declarations and Initializations<br />
2. Structures, Unions, and Enumerations<br />
3. Expressions<br />
4. Pointers<br />
5. Null Pointers<br />
6. Arrays and Pointers<br />
7. Memory Allocation<br />
8. Characters and Strings<br />
9. Boolean Expressions and Variables<br />
10. C Preprocessor<br />
11. ANSI/ISO Standard C<br />
12. Stdio<br />
13. Library Functions<br />
14. Floating Point<br />
15. Variable-Length Argument Lists<br />
16. Strange Problems<br />
17. Style<br />
18. Tools and Resources<br />
19. System Dependencies<br />
20. Miscellaneous<br />
Glossary<br />
Bibliography<br />
Acknowledgements</p>


<h3>Related posts:</h3><ol><li><a href='http://www.ideawu.net/blog/archives/155.html' rel='bookmark' title='Permanent Link: 如何使用ServletContextListener'>如何使用ServletContextListener</a></li>
<li><a href='http://www.ideawu.net/blog/archives/591.html' rel='bookmark' title='Permanent Link: jQuery延时绑定事件(lazy-bind)'>jQuery延时绑定事件(lazy-bind)</a></li>
<li><a href='http://www.ideawu.net/blog/archives/417.html' rel='bookmark' title='Permanent Link: MySQL 建立外键约束'>MySQL 建立外键约束</a></li>
<li><a href='http://www.ideawu.net/blog/archives/357.html' rel='bookmark' title='Permanent Link: MySQL 查询使用 Group By 的注意点'>MySQL 查询使用 Group By 的注意点</a></li>
<li><a href='http://www.ideawu.net/blog/archives/607.html' rel='bookmark' title='Permanent Link: 获取动态加载的图片大小的正确方法'>获取动态加载的图片大小的正确方法</a></li>
</ol><div><p><img src="http://www.ideawu.net/favicon.ico" /> 你现在看的文章是: <a href="http://www.ideawu.net/blog/archives/382.html" title="C 语言常见问题集 (中文)">C 语言常见问题集 (中文)</a></p>

<div>
	<a href="http://www.benegg.com/linode-ad.php">
		Linode VPS - 美国虚拟主机
	</a>
	|
	<a href="http://www.udpwork.com/">
		IT牛人博客聚合网站
	</a>
</div></div>]]></content:encoded>
			<wfw:commentRss>http://www.ideawu.net/blog/archives/382.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>关于 C++ 中的函数指针</title>
		<link>http://www.ideawu.net/blog/archives/307.html</link>
		<comments>http://www.ideawu.net/blog/archives/307.html#comments</comments>
		<pubDate>Tue, 29 Jan 2008 09:25:00 +0000</pubDate>
		<dc:creator>ideawu</dc:creator>
				<category><![CDATA[C语言编程]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[<p>(只是个人的感情喜好, 可能不适合某些人, 特别是对 C++ 比较有感情的人.) 我终于知道 Linus 为什么会骂 C++ 是狗屎了, 因为它把简单的东西变得复杂了(当然, 它也把某些复杂的东西变简单了).
</p>
<pre lang="cpp" line="1">
#include<stdio.h>

class A{
public:
    void fun();
};

void A::fun(){
    printf("fun\n");
}

int main(int argc, char *argv[]){
    A a;
    void (A::*p)() = &#038;A::fun;
    (a.*p)();
    return 0;
}
</pre>
<p>
这是什么狗屎? 如果这样的话, 函数指针还有实用意义吗? &#8212; 为了调用类中的一个方法, 你竟然需要知道该方法的名称, 所处的类的名称, 以及它的实例的名称, 而且调用的时候还要加上实例的名称(4 个条件)! 这就是真正的狗屎!
</p>
<p>
我希望是下面的形式(只需要两个条件: 类实例的名称, 方法的名称):
</p>
<pre lang="cpp" line="1">
void (*p)() = a.fun;
p();
</pre>
<p>
是的, C# 做到了, 所以 C# 被人称为语法优美的语言.</p>


<h3>Related posts:</h3><ol><li><a href='http://www.ideawu.net/blog/archives/290.html' rel='bookmark' title='Permanent Link: Ideawu.P2P API 简介'>Ideawu.P2P API 简介</a></li>
<li><a href='http://www.ideawu.net/blog/archives/429.html' rel='bookmark' title='Permanent Link: 编写基于TCP的应用程序'>编写基于TCP的应用程序</a></li>
<li><a href='http://www.ideawu.net/blog/archives/303.html' rel='bookmark' title='Permanent Link: TCP/IP 指数增长和线性增长的编程实现'>TCP/IP 指数增长和线性增长的编程实现</a></li>
<li><a href='http://www.ideawu.net/blog/archives/426.html' rel='bookmark' title='Permanent Link: C#封装log4net'>C#封装log4net</a></li>
<li><a href='http://www.ideawu.net/blog/archives/570.html' rel='bookmark' title='Permanent Link: Linus又骂人stupid'>Linus又骂人stupid</a></li>
</ol><div><p><img src="http://www.ideawu.net/favicon.ico" /> 你现在看的文章是: <a href="http://www.ideawu.net/blog/archives/307.html" title="关于 C++ 中的函数指针">关于 C++ 中的函数指针</a></p>

<div>
	<a href="http://www.benegg.com/linode-ad.php">
		Linode VPS - 美国虚拟主机
	</a>
	|
	<a href="http://www.udpwork.com/">
		IT牛人博客聚合网站
	</a>
</div></div>]]></description>
			<content:encoded><![CDATA[<p>(只是个人的感情喜好, 可能不适合某些人, 特别是对 C++ 比较有感情的人.) 我终于知道 Linus 为什么会骂 C++ 是狗屎了, 因为它把简单的东西变得复杂了(当然, 它也把某些复杂的东西变简单了).
</p>
<pre lang="cpp" line="1">
#include<stdio.h>

class A{
public:
    void fun();
};

void A::fun(){
    printf("fun\n");
}

int main(int argc, char *argv[]){
    A a;
    void (A::*p)() = &#038;A::fun;
    (a.*p)();
    return 0;
}
</pre>
<p>
这是什么狗屎? 如果这样的话, 函数指针还有实用意义吗? &#8212; 为了调用类中的一个方法, 你竟然需要知道该方法的名称, 所处的类的名称, 以及它的实例的名称, 而且调用的时候还要加上实例的名称(4 个条件)! 这就是真正的狗屎!
</p>
<p>
我希望是下面的形式(只需要两个条件: 类实例的名称, 方法的名称):
</p>
<pre lang="cpp" line="1">
void (*p)() = a.fun;
p();
</pre>
<p>
是的, C# 做到了, 所以 C# 被人称为语法优美的语言.</p>


<h3>Related posts:</h3><ol><li><a href='http://www.ideawu.net/blog/archives/290.html' rel='bookmark' title='Permanent Link: Ideawu.P2P API 简介'>Ideawu.P2P API 简介</a></li>
<li><a href='http://www.ideawu.net/blog/archives/429.html' rel='bookmark' title='Permanent Link: 编写基于TCP的应用程序'>编写基于TCP的应用程序</a></li>
<li><a href='http://www.ideawu.net/blog/archives/303.html' rel='bookmark' title='Permanent Link: TCP/IP 指数增长和线性增长的编程实现'>TCP/IP 指数增长和线性增长的编程实现</a></li>
<li><a href='http://www.ideawu.net/blog/archives/426.html' rel='bookmark' title='Permanent Link: C#封装log4net'>C#封装log4net</a></li>
<li><a href='http://www.ideawu.net/blog/archives/570.html' rel='bookmark' title='Permanent Link: Linus又骂人stupid'>Linus又骂人stupid</a></li>
</ol><div><p><img src="http://www.ideawu.net/favicon.ico" /> 你现在看的文章是: <a href="http://www.ideawu.net/blog/archives/307.html" title="关于 C++ 中的函数指针">关于 C++ 中的函数指针</a></p>

<div>
	<a href="http://www.benegg.com/linode-ad.php">
		Linode VPS - 美国虚拟主机
	</a>
	|
	<a href="http://www.udpwork.com/">
		IT牛人博客聚合网站
	</a>
</div></div>]]></content:encoded>
			<wfw:commentRss>http://www.ideawu.net/blog/archives/307.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>tftpx &#8211; TFTP的实现和扩展</title>
		<link>http://www.ideawu.net/blog/archives/252.html</link>
		<comments>http://www.ideawu.net/blog/archives/252.html#comments</comments>
		<pubDate>Sat, 16 Jun 2007 06:36:54 +0000</pubDate>
		<dc:creator>ideawu</dc:creator>
				<category><![CDATA[C语言编程]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[<p>停止等待机制作为数据传输的基本机制, 是网络编程必须的掌握的技能. TFTP 协议使用基于UDP的停止等待机制来实现文件的可靠传输.</p>
<p><a href="http://www.ideawu.net/person/tftpx/">tftpx 实现和扩展了 TFTP 协议</a>.</p>


<h3>Related posts:</h3><ol><li><a href='http://www.ideawu.net/blog/archives/534.html' rel='bookmark' title='Permanent Link: C语言解析JSON'>C语言解析JSON</a></li>
<li><a href='http://www.ideawu.net/blog/archives/516.html' rel='bookmark' title='Permanent Link: 连连看游戏开发实践(1) &#8211; 算法'>连连看游戏开发实践(1) &#8211; 算法</a></li>
<li><a href='http://www.ideawu.net/blog/archives/416.html' rel='bookmark' title='Permanent Link: C语言类函数宏的参数'>C语言类函数宏的参数</a></li>
<li><a href='http://www.ideawu.net/blog/archives/239.html' rel='bookmark' title='Permanent Link: 编译C语言代码'>编译C语言代码</a></li>
</ol><div><p><img src="http://www.ideawu.net/favicon.ico" /> 你现在看的文章是: <a href="http://www.ideawu.net/blog/archives/252.html" title="tftpx &#8211; TFTP的实现和扩展">tftpx &#8211; TFTP的实现和扩展</a></p>

<div>
	<a href="http://www.benegg.com/linode-ad.php">
		Linode VPS - 美国虚拟主机
	</a>
	|
	<a href="http://www.udpwork.com/">
		IT牛人博客聚合网站
	</a>
</div></div>]]></description>
			<content:encoded><![CDATA[<p>停止等待机制作为数据传输的基本机制, 是网络编程必须的掌握的技能. TFTP 协议使用基于UDP的停止等待机制来实现文件的可靠传输.</p>
<p><a href="http://www.ideawu.net/person/tftpx/">tftpx 实现和扩展了 TFTP 协议</a>.</p>


<h3>Related posts:</h3><ol><li><a href='http://www.ideawu.net/blog/archives/534.html' rel='bookmark' title='Permanent Link: C语言解析JSON'>C语言解析JSON</a></li>
<li><a href='http://www.ideawu.net/blog/archives/516.html' rel='bookmark' title='Permanent Link: 连连看游戏开发实践(1) &#8211; 算法'>连连看游戏开发实践(1) &#8211; 算法</a></li>
<li><a href='http://www.ideawu.net/blog/archives/416.html' rel='bookmark' title='Permanent Link: C语言类函数宏的参数'>C语言类函数宏的参数</a></li>
<li><a href='http://www.ideawu.net/blog/archives/239.html' rel='bookmark' title='Permanent Link: 编译C语言代码'>编译C语言代码</a></li>
</ol><div><p><img src="http://www.ideawu.net/favicon.ico" /> 你现在看的文章是: <a href="http://www.ideawu.net/blog/archives/252.html" title="tftpx &#8211; TFTP的实现和扩展">tftpx &#8211; TFTP的实现和扩展</a></p>

<div>
	<a href="http://www.benegg.com/linode-ad.php">
		Linode VPS - 美国虚拟主机
	</a>
	|
	<a href="http://www.udpwork.com/">
		IT牛人博客聚合网站
	</a>
</div></div>]]></content:encoded>
			<wfw:commentRss>http://www.ideawu.net/blog/archives/252.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>编译C语言代码</title>
		<link>http://www.ideawu.net/blog/archives/239.html</link>
		<comments>http://www.ideawu.net/blog/archives/239.html#comments</comments>
		<pubDate>Sun, 25 Mar 2007 14:12:31 +0000</pubDate>
		<dc:creator>ideawu</dc:creator>
				<category><![CDATA[C语言编程]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[<p>一般我们会在某个C语言源码文件(如a.c)中使用&quot;include&quot;指令包含其它的文件(如b.h或者b.c).</p>
<p>这样设想:<br />
// file: a.c<br />
include &quot;b.h&quot;<br />
//可能有include &quot;b.c&quot;<br />
//main()</p>
<p>// file: b.h<br />
// 函数声明等</p>
<p>// file: b.c<br />
include &quot;b.h&quot;<br />
// 函数定义<br />
我们可以先把b.c编译为模块b.o<br />
gcc -c b.c</p>
<p>然后编译a.c<br />
gcc a.c b.o</p>
<p>或者我们在a.c文件中直接包含b.c那么就可以这样编译:<br />
gcc a.c</p>


<h3>Related posts:</h3><ol><li><a href='http://www.ideawu.net/blog/archives/216.html' rel='bookmark' title='Permanent Link: 用mplayer,toolame提取rmvb等视频文件中的音频为mp3'>用mplayer,toolame提取rmvb等视频文件中的音频为mp3</a></li>
<li><a href='http://www.ideawu.net/blog/archives/307.html' rel='bookmark' title='Permanent Link: 关于 C++ 中的函数指针'>关于 C++ 中的函数指针</a></li>
<li><a href='http://www.ideawu.net/blog/archives/468.html' rel='bookmark' title='Permanent Link: 后端开发工程师的DIV+CSS两栏布局入门'>后端开发工程师的DIV+CSS两栏布局入门</a></li>
<li><a href='http://www.ideawu.net/blog/archives/621.html' rel='bookmark' title='Permanent Link: Shell循环'>Shell循环</a></li>
<li><a href='http://www.ideawu.net/blog/archives/497.html' rel='bookmark' title='Permanent Link: 用脚本语言开发网游 &#8211; C整合Python'>用脚本语言开发网游 &#8211; C整合Python</a></li>
</ol><div><p><img src="http://www.ideawu.net/favicon.ico" /> 你现在看的文章是: <a href="http://www.ideawu.net/blog/archives/239.html" title="编译C语言代码">编译C语言代码</a></p>

<div>
	<a href="http://www.benegg.com/linode-ad.php">
		Linode VPS - 美国虚拟主机
	</a>
	|
	<a href="http://www.udpwork.com/">
		IT牛人博客聚合网站
	</a>
</div></div>]]></description>
			<content:encoded><![CDATA[<p>一般我们会在某个C语言源码文件(如a.c)中使用&quot;include&quot;指令包含其它的文件(如b.h或者b.c).</p>
<p>这样设想:<br />
// file: a.c<br />
include &quot;b.h&quot;<br />
//可能有include &quot;b.c&quot;<br />
//main()</p>
<p>// file: b.h<br />
// 函数声明等</p>
<p>// file: b.c<br />
include &quot;b.h&quot;<br />
// 函数定义<br />
我们可以先把b.c编译为模块b.o<br />
gcc -c b.c</p>
<p>然后编译a.c<br />
gcc a.c b.o</p>
<p>或者我们在a.c文件中直接包含b.c那么就可以这样编译:<br />
gcc a.c</p>


<h3>Related posts:</h3><ol><li><a href='http://www.ideawu.net/blog/archives/216.html' rel='bookmark' title='Permanent Link: 用mplayer,toolame提取rmvb等视频文件中的音频为mp3'>用mplayer,toolame提取rmvb等视频文件中的音频为mp3</a></li>
<li><a href='http://www.ideawu.net/blog/archives/307.html' rel='bookmark' title='Permanent Link: 关于 C++ 中的函数指针'>关于 C++ 中的函数指针</a></li>
<li><a href='http://www.ideawu.net/blog/archives/468.html' rel='bookmark' title='Permanent Link: 后端开发工程师的DIV+CSS两栏布局入门'>后端开发工程师的DIV+CSS两栏布局入门</a></li>
<li><a href='http://www.ideawu.net/blog/archives/621.html' rel='bookmark' title='Permanent Link: Shell循环'>Shell循环</a></li>
<li><a href='http://www.ideawu.net/blog/archives/497.html' rel='bookmark' title='Permanent Link: 用脚本语言开发网游 &#8211; C整合Python'>用脚本语言开发网游 &#8211; C整合Python</a></li>
</ol><div><p><img src="http://www.ideawu.net/favicon.ico" /> 你现在看的文章是: <a href="http://www.ideawu.net/blog/archives/239.html" title="编译C语言代码">编译C语言代码</a></p>

<div>
	<a href="http://www.benegg.com/linode-ad.php">
		Linode VPS - 美国虚拟主机
	</a>
	|
	<a href="http://www.udpwork.com/">
		IT牛人博客聚合网站
	</a>
</div></div>]]></content:encoded>
			<wfw:commentRss>http://www.ideawu.net/blog/archives/239.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

