﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-wgcno7</title><link>http://www.cppblog.com/wgcno7/</link><description /><language>zh-cn</language><lastBuildDate>Tue, 14 Apr 2026 23:29:31 GMT</lastBuildDate><pubDate>Tue, 14 Apr 2026 23:29:31 GMT</pubDate><ttl>60</ttl><item><title>内存和对象内存池技术在网游开发中的注意点和应用</title><link>http://www.cppblog.com/wgcno7/archive/2010/05/21/116006.html</link><dc:creator>wgcno7</dc:creator><author>wgcno7</author><pubDate>Fri, 21 May 2010 02:17:00 GMT</pubDate><guid>http://www.cppblog.com/wgcno7/archive/2010/05/21/116006.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/wgcno7/archive/2010/05/21/116006.html'>阅读全文</a><img src ="http://www.cppblog.com/wgcno7/aggbug/116006.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wgcno7/" target="_blank">wgcno7</a> 2010-05-21 10:17 <a href="http://www.cppblog.com/wgcno7/archive/2010/05/21/116006.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>epoll实现的net_echo程序</title><link>http://www.cppblog.com/wgcno7/archive/2010/05/20/115910.html</link><dc:creator>wgcno7</dc:creator><author>wgcno7</author><pubDate>Thu, 20 May 2010 05:54:00 GMT</pubDate><guid>http://www.cppblog.com/wgcno7/archive/2010/05/20/115910.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/wgcno7/archive/2010/05/20/115910.html'>阅读全文</a><img src ="http://www.cppblog.com/wgcno7/aggbug/115910.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wgcno7/" target="_blank">wgcno7</a> 2010-05-20 13:54 <a href="http://www.cppblog.com/wgcno7/archive/2010/05/20/115910.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>高负载高并发应用 参考索引</title><link>http://www.cppblog.com/wgcno7/archive/2010/05/17/115615.html</link><dc:creator>wgcno7</dc:creator><author>wgcno7</author><pubDate>Mon, 17 May 2010 09:54:00 GMT</pubDate><guid>http://www.cppblog.com/wgcno7/archive/2010/05/17/115615.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/wgcno7/archive/2010/05/17/115615.html'>阅读全文</a><img src ="http://www.cppblog.com/wgcno7/aggbug/115615.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wgcno7/" target="_blank">wgcno7</a> 2010-05-17 17:54 <a href="http://www.cppblog.com/wgcno7/archive/2010/05/17/115615.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]http://code.google.com/p/solidground/</title><link>http://www.cppblog.com/wgcno7/archive/2010/05/17/115951.html</link><dc:creator>wgcno7</dc:creator><author>wgcno7</author><pubDate>Mon, 17 May 2010 08:49:00 GMT</pubDate><guid>http://www.cppblog.com/wgcno7/archive/2010/05/17/115951.html</guid><wfw:comment>http://www.cppblog.com/wgcno7/comments/115951.html</wfw:comment><comments>http://www.cppblog.com/wgcno7/archive/2010/05/17/115951.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wgcno7/comments/commentRss/115951.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wgcno7/services/trackbacks/115951.html</trackback:ping><description><![CDATA[
		
		<a href="http://code.google.com/p/solidground/" target="_blank">http://code.google.com/p/solidground/</a> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/wgcno7/blog/category/%C4%AC%C8%CF%B7%D6%C0%E0">默认分类</a>&nbsp;<a href="http://hi.baidu.com/wgcno7/blog/item/3003385778e054c8b645ae5f.html#comment">查看评论</a><br>文章来源:<a href='http://hi.baidu.com/wgcno7/blog/item/3003385778e054c8b645ae5f.html'>http://hi.baidu.com/wgcno7/blog/item/3003385778e054c8b645ae5f.html</a><img src ="http://www.cppblog.com/wgcno7/aggbug/115951.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wgcno7/" target="_blank">wgcno7</a> 2010-05-17 16:49 <a href="http://www.cppblog.com/wgcno7/archive/2010/05/17/115951.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>tcp要点学习-建立连接</title><link>http://www.cppblog.com/wgcno7/archive/2010/05/16/115506.html</link><dc:creator>wgcno7</dc:creator><author>wgcno7</author><pubDate>Sun, 16 May 2010 03:18:00 GMT</pubDate><guid>http://www.cppblog.com/wgcno7/archive/2010/05/16/115506.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/wgcno7/archive/2010/05/16/115506.html'>阅读全文</a><img src ="http://www.cppblog.com/wgcno7/aggbug/115506.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wgcno7/" target="_blank">wgcno7</a> 2010-05-16 11:18 <a href="http://www.cppblog.com/wgcno7/archive/2010/05/16/115506.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]ISTQB国际软件测试工程师认证</title><link>http://www.cppblog.com/wgcno7/archive/2010/05/12/115952.html</link><dc:creator>wgcno7</dc:creator><author>wgcno7</author><pubDate>Wed, 12 May 2010 09:42:00 GMT</pubDate><guid>http://www.cppblog.com/wgcno7/archive/2010/05/12/115952.html</guid><wfw:comment>http://www.cppblog.com/wgcno7/comments/115952.html</wfw:comment><comments>http://www.cppblog.com/wgcno7/archive/2010/05/12/115952.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wgcno7/comments/commentRss/115952.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wgcno7/services/trackbacks/115952.html</trackback:ping><description><![CDATA[
		
		<br>
【认证简介】<br>
ISTQB (International Software Testing Qualifications Board)是国际唯一权威的软件测试资质认证机构，现有包括美国、德国、英国、法国、日本等超过40个成员国。中国于2006年5月26日在美国奥兰多 举行的ISTQB2006年年会上得到正式批准，中国软件测试认证委员会 (CSTQB) 成为ISTQB的正式成员。<br>
<br>
<br>
<br>
CSTQB 是ISTQB在中国的唯一授权机构，由上海滔瑞信息技术有限公司、同济大学，中国软件评测中心、上海市软件评测中心、广东赛宝认证中心等国内软件测试业权 威机构共同组织，旨在推广ISTQB的认证体系，使中国软件测试体系与国际接轨；同时，配合国家行业主管部门，制定和颁布符合国际标准的测试行业规范；加 强国际交流与合作，推动国际软件测试人才流动和技术交流等。<br>
<br>
<br>
<br>
ISTQB-Certified Tester培训及认证体系分为三个级别：基础级/Foundation Level、高级/Advanced Level、专家级/Expert Level。培训者获得基础级证书后，可申请参加更高级别的培训和认证考试，并获得相应证书。至2008年10月，全球已有超过 100,000 IT 专业人士持有ISTQB-Certified Tester的认证证书。&#160; <br>
<br>
软件测试已经成为IT市场需求最大的职业，获得ISTQB 资格认证成为迈向知名外企的全球通行证，据了解，IBM、惠普、西门子、诺基亚、三星等公司已经要求软件测试人员需要获得ISTQB认证。随着国内软件测 试行业的快速发展，获得国际软件测试认证已经成为从事软件测试的“上岗证”。<br>
<br>
<br>
<br>
<br>
<br>
<br>
------------------<br>
<br>
<br>
在此，我们对您的合作与支持表示衷心的感谢!<br>
———————————————————————<br>
上海滔瑞信息技术有限公司<br>
<br>
认证培训部：朱老师<br>
<br>
咨询热线：15921515202<br>
<br>
在线咨询：MSN:zhuyunna2006@hotmail.com; QQ:157859065          &#160; <br>
<br>
电子邮箱：ISTQB@163.com 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/wgcno7/blog/category/%C4%AC%C8%CF%B7%D6%C0%E0">默认分类</a>&nbsp;<a href="http://hi.baidu.com/wgcno7/blog/item/2c0a3ed5db1f38d1a144df19.html#comment">查看评论</a><br>文章来源:<a href='http://hi.baidu.com/wgcno7/blog/item/2c0a3ed5db1f38d1a144df19.html'>http://hi.baidu.com/wgcno7/blog/item/2c0a3ed5db1f38d1a144df19.html</a><img src ="http://www.cppblog.com/wgcno7/aggbug/115952.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wgcno7/" target="_blank">wgcno7</a> 2010-05-12 17:42 <a href="http://www.cppblog.com/wgcno7/archive/2010/05/12/115952.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]使用 GDB 调试多进程程序</title><link>http://www.cppblog.com/wgcno7/archive/2010/05/06/115953.html</link><dc:creator>wgcno7</dc:creator><author>wgcno7</author><pubDate>Thu, 06 May 2010 06:03:00 GMT</pubDate><guid>http://www.cppblog.com/wgcno7/archive/2010/05/06/115953.html</guid><wfw:comment>http://www.cppblog.com/wgcno7/comments/115953.html</wfw:comment><comments>http://www.cppblog.com/wgcno7/archive/2010/05/06/115953.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wgcno7/comments/commentRss/115953.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wgcno7/services/trackbacks/115953.html</trackback:ping><description><![CDATA[
		
		<p><a href="http://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/index.html#author">田 强</a> (<a href="mailto:tianq@cn.ibm.com?subject=%E4%BD%BF%E7%94%A8%20GDB%20%E8%B0%83%E8%AF%95%E5%A4%9A%E8%BF%9B%E7%A8%8B%E7%A8%8B%E5%BA%8F">tianq@cn.ibm.com</a>), 软件工程师, IBM中国软件开发中心</p>
<p>2007 年  7 月  30 日</p>
<blockquote>GDB 是 linux 系统上常用的调试工具，本文介绍了使用 GDB 调试多进程程序的几种方法，并对各种方法进行比较。</blockquote>  
<p>GDB 是 linux 系统上常用的 c/c++ 调试工具，功能十分强大。对于较为复杂的系统，比如多进程系统，如何使用 GDB 调试呢？考虑下面这个三进程系统：</p>
<br>
<a name="N10044"><strong>进程</strong></a><br>
<img width="504" height="214" src="http://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/threeprocesses.jpg" alt="进程">             <br>
<p>Proc2 是 Proc1 的子进程，Proc3 又是 Proc2 的子进程。如何使用 GDB 调试 proc2 或者 proc3 呢？</p>
<p>实 际上，GDB 没有对多进程程序调试提供直接支持。例如，使用GDB调试某个进程，如果该进程fork了子进程，GDB会继续调试该进程，子进程会不受干扰地运行下去。 如果你事先在子进程代码里设定了断点，子进程会收到SIGTRAP信号并终止。那么该如何调试子进程呢？其实我们可以利用GDB的特点或者其他一些辅助手 段来达到目的。此外，GDB 也在较新内核上加入一些多进程调试支持。</p>
<p>接下来我们详细介绍几种方法，分别是 follow-fork-mode 方法，attach 子进程方法和 GDB wrapper 方法。</p>
<p><a name="N1005A"><span class="atitle">                 <strong>follow-fork-mode</strong>             </span></a></p>
<p>在2.5.60版Linux内核及以后，GDB对使用fork/vfork创建子进程的程序提供了follow-fork-mode选项来支持多进程调试。</p>
<p>follow-fork-mode的用法为：</p>
<p><code>set follow-fork-mode [parent|child]</code></p>
<ul>
    <li>parent: fork之后继续调试父进程，子进程不受影响。</li>
    <li>child: fork之后调试子进程，父进程不受影响。</li>
</ul>
<p>因此如果需要调试子进程，在启动gdb后：</p>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">(gdb) set follow-fork-mode child</pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>并在子进程代码设置断点。</p>
<p>此外还有detach-on-fork参数，指示GDB在fork之后是否断开（detach）某个进程的调试，或者都交由GDB控制：</p>
<p><code>set detach-on-fork [on|off]</code></p>
<ul>
    <li>on: 断开调试follow-fork-mode指定的进程。</li>
    <li>off: gdb将控制父进程和子进程。follow-fork-mode指定的进程将被调试，另一个进程置于暂停（suspended）状态。</li>
</ul>
<p>注意，最好使用GDB 6.6或以上版本，如果你使用的是GDB6.4，就只有follow-fork-mode模式。</p>
<p>follow- fork-mode/detach-on-fork的使用还是比较简单的，但由于其系统内核/gdb版本限制，我们只能在符合要求的系统上才能使用。而 且，由于follow-fork-mode的调试必然是从父进程开始的，对于fork多次，以至于出现孙进程或曾孙进程的系统，例如上图3进程系统，调试 起来并不方便。</p>
<p><a name="N1009E"><span class="atitle">                 <strong>Attach子进程</strong>             </span></a></p>
<p>众所周知，GDB有附着（attach）到正在运行的进程的功能，即attach &lt;pid&gt;命令。因此我们可以利用该命令attach到子进程然后进行调试。</p>
<p>例如我们要调试某个进程RIM_Oracle_Agent.9i，首先得到该进程的pid</p>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">[root@tivf09 tianq]# ps -ef|grep RIM_Oracle_Agent.9i<br>nobody    6722  6721  0 05:57 ?        00:00:00 RIM_Oracle_Agent.9i<br>root      7541 27816  0 06:10 pts/3    00:00:00 grep -i rim_oracle_agent.9i</pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>通过pstree可以看到，这是一个三进程系统，oserv是RIM_Oracle_prog的父进程，RIM_Oracle_prog又是RIM_Oracle_Agent.9i的父进程。</p>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">[root@tivf09 root]# pstree -H 6722</pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<br>
<a name="N100BD"><strong>通过 pstree 察看进程</strong></a><br>
<img width="572" height="214" src="http://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/pstree.jpg" alt="通过 pstree 察看进程">             <br>
<p>启动GDB，attach到该进程</p>
<br>
<a name="N100CF"><strong>用 GDB 连接进程</strong></a><br>
<img width="572" height="288" src="http://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/attach.jpg" alt="用 GDB 连接进程">             <br>
<p>现在就可以调试了。一个新的问题是，子进程一直在运行，attach上去后都不知道运行到哪里了。有没有办法解决呢？</p>
<p>一个办法是，在要调试的子进程初始代码中，比如main函数开始处，加入一段特殊代码，使子进程在某个条件成立时便循环睡眠等待，attach到进程后在该代码段后设上断点，再把成立的条件取消，使代码可以继续执行下去。</p>
<p>至于这段代码所采用的条件，看你的偏好了。比如我们可以检查一个指定的环境变量的值，或者检查一个特定的文件存不存在。以文件为例，其形式可以如下：</p>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">void debug_wait(char *tag_file)<br>{<br>    while(1)<br>    {<br>        if (tag_file存在)<br>            睡眠一段时间;<br>        else<br>            break;<br>    }<br>}</pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>当attach到进程后，在该段代码之后设上断点，再把该文件删除就OK了。当然你也可以采用其他的条件或形式，只要这个条件可以设置/检测即可。</p>
<p>Attach进程方法还是很方便的，它能够应付各种各样复杂的进程系统，比如孙子/曾孙进程，比如守护进程（daemon process），唯一需要的就是加入一小段代码。</p>
<p><a name="N100F0"><span class="atitle">                 <strong>GDB wrapper</strong>             </span></a></p>
<p>很多时候，父进程 fork 出子进程，子进程会紧接着调用 exec族函数来执行新的代码。对于这种情况，我们也可以使用gdb wrapper 方法。它的优点是不用添加额外代码。</p>
<p>其基本原理是以gdb调用待执行代码作为一个新的整体来被exec函数执行，使得待执行代码始终处于gdb的控制中，这样我们自然能够调试该子进程代码。</p>
<p>还 是上面那个例子，RIM_Oracle_prog fork出子进程后将紧接着执行RIM_Oracle_Agent.9i的二进制代码文件。我们将该文件重命名为 RIM_Oracle_Agent.9i.binary，并新建一个名为RIM_Oracle_Agent.9i的shell脚本文件，其内容如下：</p>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">[root@tivf09 bin]# mv RIM_Oracle_Agent.9i RIM_Oracle_Agent.9i.binary<br>[root@tivf09 bin]# cat RIM_Oracle_Agent.9i<br>#!/bin/sh<br>gdb RIM_Oracle_Agent.binary</pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>当fork的子进程执行名为RIM_Oracle_Agent.9i的文件时，gdb会被首先启动，使得要调试的代码处于gdb控制之下。</p>
<p>新的问题来了。子进程是在gdb的控制下了，但还是不能调试：如何与gdb交互呢？我们必须以某种方式启动gdb，以便能在某个窗口/终端与gdb交互。具体来说，可以使用xterm生成这个窗口。</p>
<p>xterm是X window系统下的模拟终端程序。比如我们在Linux桌面环境GNOME中敲入xterm命令：</p>
<br>
<a name="N10113"><strong>xterm</strong></a><br>
<img width="375" height="190" src="http://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/runxterm.jpg" alt="xterm">             <br>
<p>就会跳出一个终端窗口：</p>
<br>
<a name="N10125"><strong>终端</strong></a><br>
<img width="500" height="338" src="http://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/xterm.jpg" alt="终端">             <br>
<p>如 果你是在一台远程linux服务器上调试，那么可以使用VNC(Virtual Network Computing) viewer从本地机器连接到服务器上使用xterm。在此之前，需要在你的本地机器上安装VNC viewer，在服务器上安装并启动VNC server。大多数linux发行版都预装了vnc-server软件包，所以我们可以直接运行vncserver命令。注意，第一次运行 vncserver时会提示输入密码，用作VNC viewer从客户端连接时的密码。可以在VNC server机器上使用vncpasswd命令修改密码。</p>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">[root@tivf09 root]# vncserver <br><br>New 'tivf09:1 (root)' desktop is tivf09:1<br><br>Starting applications specified in /root/.vnc/xstartup<br>Log file is /root/.vnc/tivf09:1.log<br><br>[root@tivf09 root]#<br>[root@tivf09 root]# ps -ef|grep -i vnc<br>root     19609     1  0 Jun05 ?        00:08:46 Xvnc :1 -desktop tivf09:1 (root) <br>  -httpd /usr/share/vnc/classes -auth /root/.Xauthority -geometry 1024x768 <br>  -depth 16 -rfbwait 30000 -rfbauth /root/.vnc/passwd -rfbport 5901 -pn<br>root     19627     1  0 Jun05 ?        00:00:00 vncconfig -iconic<br>root     12714 10599  0 01:23 pts/0    00:00:00 grep -i vnc<br>[root@tivf09 root]#</pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>Vncserver 是一个Perl脚本，用来启动Xvnc（X VNC server）。X client应用，比如xterm，VNC viewer都是和它通信的。如上所示，我们可以使用的DISPLAY值为tivf09:1。现在就可以从本地机器使用VNC viewer连接过去：</p>
<br>
<a name="N1013F"><strong>VNC viewer：输入服务器</strong></a><br>
<img width="343" height="127" src="http://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/vncviewer1.jpg" alt="VNC viewer:输入服务器">             <br>
<p>输入密码：</p>
<br>
<a name="N10151"><strong>VNC viewer：输入密码</strong></a><br>
<img width="374" height="98" src="http://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/vncviewer2.jpg" alt="VNC viewer:输入密码">             <br>
<p>登录成功，界面和服务器本地桌面上一样：</p>
<br>
<a name="N10163"><strong>VNC viewer</strong></a><br>
<img width="532" height="381" src="http://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/vncviewer3.jpg" alt="VNC viewer">             <br>
<p>下面我们来修改RIM_Oracle_Agent.9i脚本，使它看起来像下面这样：</p>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">#!/bin/sh<br>export DISPLAY=tivf09:1.0; xterm -e gdb RIM_Oracle_Agent.binary</pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>如果你的程序在exec的时候还传入了参数，可以改成：</p>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">#!/bin/sh<br>export DISPLAY=tivf09:1.0; xterm -e gdb --args RIM_Oracle_Agent.binary $@</pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>最后加上执行权限</p>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">[root@tivf09 bin]# chmod 755 RIM_Oracle_Agent.9i</pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>现在就可以调试了。运行启动子进程的程序：</p>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">[root@tivf09 root]# wrimtest -l 9i_linux<br>Resource Type  : RIM<br>Resource Label : 9i_linux<br>Host Name      : tivf09<br>User Name      : mdstatus<br>Vendor         : Oracle<br>Database       : rim<br>Database Home  : /data/oracle9i/920<br>Server ID      : rim<br>Instance Home  : <br>Instance Name  : <br>Opening Regular Session...</pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>程序停住了。从VNC viewer中可以看到，一个新的gdb xterm窗口在服务器端打开了</p>
<br>
<a name="N10195"><strong>gdb xterm 窗口</strong></a><br>
<img width="546" height="365" src="http://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/gdbwindow.jpg" alt="gdb xterm窗口">             <br>
<p> </p>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">[root@tivf09 root]# ps -ef|grep gdb<br>nobody   24312 24311  0 04:30 ?        00:00:00 xterm -e gdb RIM_Oracle_Agent.binary<br>nobody   24314 24312  0 04:30 pts/2    00:00:00 gdb RIM_Oracle_Agent.binary<br>root     24326 10599  0 04:30 pts/0    00:00:00 grep gdb</pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>运行的正是要调试的程序。设置好断点，开始调试吧！</p>
<p>注意，下面的错误一般是权限的问题，使用 xhost 命令来修改权限：</p>
<br>
<a name="N101B1"><strong>xterm 错误</strong></a><br>
<img width="572" height="176" src="http://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/error.jpg" alt="xterm 错误">             <br>
<p> </p>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">[root@tivf09 bin]# export DISPLAY=tivf09:1.0<br>[root@tivf09 bin]# xhost +<br>access control disabled, clients can connect from any host</pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>xhost + 禁止了访问控制，从任何机器都可以连接过来。考虑到安全问题，你也可以使用xhost + &lt;你的机器名&gt;。</p>
<p><a name="N101C8"><span class="atitle">                 <strong>小结</strong>             </span></a></p>
<p>上述三种方法各有特点和优劣，因此适应于不同的场合和环境：</p>
<ul>
    <li>follow-fork-mode方法：方便易用，对系统内核和GDB版本有限制，适合于较为简单的多进程系统</li>
    <li>attach子进程方法：灵活强大，但需要添加额外代码，适合于各种复杂情况，特别是守护进程</li>
    <li>GDB wrapper方法：专用于fork+exec模式，不用添加额外代码，但需要X环境支持（xterm/VNC）。</li>
</ul>
<br>
<br>
<p><a name="resources"><span class="atitle">参考资料 </span></a></p>
<ul>
    <li>GDB 官方参考资料：<a href="http://sourceware.org/gdb/documentation/">http://sourceware.org/gdb/documentation/</a></li>
    <li>更多 VNC 信息：<a href="http://www.realvnc.com/">http://www.realvnc.com/</a></li>
</ul> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/wgcno7/blog/category/Linux">Linux</a>&nbsp;<a href="http://hi.baidu.com/wgcno7/blog/item/d110400c38a04cc67bcbe1f0.html#comment">查看评论</a><br>文章来源:<a href='http://hi.baidu.com/wgcno7/blog/item/d110400c38a04cc67bcbe1f0.html'>http://hi.baidu.com/wgcno7/blog/item/d110400c38a04cc67bcbe1f0.html</a><img src ="http://www.cppblog.com/wgcno7/aggbug/115953.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wgcno7/" target="_blank">wgcno7</a> 2010-05-06 14:03 <a href="http://www.cppblog.com/wgcno7/archive/2010/05/06/115953.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]Wireshark</title><link>http://www.cppblog.com/wgcno7/archive/2010/04/29/115954.html</link><dc:creator>wgcno7</dc:creator><author>wgcno7</author><pubDate>Thu, 29 Apr 2010 09:50:00 GMT</pubDate><guid>http://www.cppblog.com/wgcno7/archive/2010/04/29/115954.html</guid><wfw:comment>http://www.cppblog.com/wgcno7/comments/115954.html</wfw:comment><comments>http://www.cppblog.com/wgcno7/archive/2010/04/29/115954.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wgcno7/comments/commentRss/115954.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wgcno7/services/trackbacks/115954.html</trackback:ping><description><![CDATA[
		
		　　<strong>Wireshark</strong>（前称<strong>Ethereal</strong>）是一个网络封包分析软件。网络封包分析软件的功能是撷取网络封包，并尽可能显示出最为详细的网络封包资料。网络封包分析软件的功能可想像成 &quot;电工技师使用电表来量测电流、电压、电阻&quot; 的工作 - 只是将场景移植到网络上，并将电线替换成网络线。<br>
在过去，网络封包分析软件是非常昂贵，或是专门属于营利用的软件。Ethereal的出现改变 了这一切。在GNUGPL通用许可证的保障范围底下，使用者可以以免费的代价取得软件与其程式码，并拥有针对其源代码修改及客制化的权利。 Ethereal是目前全世界最广泛的网络封包分析软件之一。<br>
软件简介<br>
Wireshark使用目的以下是一些使用Wireshark目的的例子：<br>
网络管理员使用Wireshark来检测网络问题，网络安全工程师使用Wireshark来检 查资讯安全相关问题，开发者使用Wireshark来为新的通讯协定除错，普通使用者使用Wireshark来学习网络协定的相关知识当然，有的人也会“ 居心叵测”的用它来寻找一些敏感信息……<br>
Wireshark不是入侵侦测软件（Intrusion DetectionSoftware,IDS）。对于网络上的异常流量行为，Wireshark不会产生警示或是任何提示。然而，仔细分析 Wireshark撷取的封包能够帮助使用者对于网络行为有更清楚的了解。Wireshark不会对网络封包产生内容的修改，它只会反映出目前流通的封包 资讯。 Wireshark本身也不会送出封包至网络上。<br>
官方:http://www.wireshark.org/ 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/wgcno7/blog/category/%CD%F8%C2%E7%B1%E0%B3%CC">网络编程</a>&nbsp;<a href="http://hi.baidu.com/wgcno7/blog/item/9d3507f80ddefc859e514630.html#comment">查看评论</a><br>文章来源:<a href='http://hi.baidu.com/wgcno7/blog/item/9d3507f80ddefc859e514630.html'>http://hi.baidu.com/wgcno7/blog/item/9d3507f80ddefc859e514630.html</a><img src ="http://www.cppblog.com/wgcno7/aggbug/115954.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wgcno7/" target="_blank">wgcno7</a> 2010-04-29 17:50 <a href="http://www.cppblog.com/wgcno7/archive/2010/04/29/115954.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]linux下kill命令小结</title><link>http://www.cppblog.com/wgcno7/archive/2010/04/29/115955.html</link><dc:creator>wgcno7</dc:creator><author>wgcno7</author><pubDate>Thu, 29 Apr 2010 03:25:00 GMT</pubDate><guid>http://www.cppblog.com/wgcno7/archive/2010/04/29/115955.html</guid><wfw:comment>http://www.cppblog.com/wgcno7/comments/115955.html</wfw:comment><comments>http://www.cppblog.com/wgcno7/archive/2010/04/29/115955.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wgcno7/comments/commentRss/115955.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wgcno7/services/trackbacks/115955.html</trackback:ping><description><![CDATA[
		
		<span style="font-size: medium;">1.作用 <br>
kill命令用来中止一个进程。 <br>
<br>
2.格式 <br>
kill [ －s signal | －p ] [ －a ] pid ... <br>
kill －l [ signal ] <br>
<br>
3.参数 <br>
－s：指定发送的信号。 <br>
－p：模拟发送信号。 <br>
－l：指定信号的名称列表。 <br>
pid：要中止进程的ID号。 <br>
Signal：表示信号。 <br>
<br>
4.说明 <br>
进程是Linux系统中一个非常重要的概念。Linux是一个多任务的操作系统，系统上经常同时运行着多个进程。我们不关心这些进程究竟是如何分配的，或者是内核如何管理分配时间片的，所关心的是如何去控制这些进程，让它们能够很好地为用户服务。 <br>
<br>
Linux操作系统包括三种不同类型的进程，每种进程都有自己的特点和属性。交互进程是由一个Shell启动的进程。交互进程既可以在前台运行， 也可以在后台运行。批处理进程和终端没有联系，是一个进程序列。监控进程（也称系统守护进程）时Linux系统启动时启动的进程，并在后台运行。例 如，httpd是著名的Apache服务器的监控进程。 <br>
<br>
kill命令的工作原理是，向Linux系统的内核发送一个系统操作信号和某个程序的进程标识号，然后系统内核就可以对进程标识号指定的进程进行 操作。比如在top命令中，我们看到系统运行许多进程，有时就需要使用kill中止某些进程来提高系统资源。在讲解安装和登陆命令时，曾提到系统多个虚拟 控制台的作用是当一个程序出错造成系统死锁时，可以切换到其它虚拟控制台工作关闭这个程序。此时使用的命令就是kill，因为kill是大多数Shell 内部命令可以直接调用的。 <br>
<br>
5.应用实例 <br>
（1）强行中止（经常使用杀掉）一个进程标识号为324的进程： <br>
＃kill －9 324 <br>
<br>
（2）解除Linux系统的死锁 <br>
在Linux中有时会发生这样一种情况：一个程序崩溃，并且处于死锁的状态。此时一般不用重新启动计算机，只需要中止(或者说是关闭)这个有问题 的程序即可。当kill处于X-Window界面时，主要的程序(除了崩溃的程序之外)一般都已经正常启动了。此时打开一个终端，在那里中止有问题的程 序。比如，如果Mozilla浏览器程序出现了锁死的情况，可以使用kill命令来中止所有包含有Mozolla浏览器的程序。首先用top命令查处该程 序的 PID，然后使用kill命令停止这个程序： <br>
＃kill －SIGKILL XXX <br>
其中，XXX是包含有Mozolla浏览器的程序的进程标识号。 <br>
<br>
（3）使用命令回收内存 <br>
我们知道内存对于系统是非常重要的，回收内存可以提高系统资源。kill命令可以及时地中止一些“越轨”的程序或很长时间没有相应的程序。例如，使用top命令发现一个无用 (Zombie) 的进程，此时可以使用下面命令： <br>
＃kill －9 XXX <br>
其中，XXX是无用的进程标识号。 <br>
<br>
然后使用下面命令： <br>
＃free <br>
此时会发现可用内存容量增加了。 <br>
<br>
（4）killall命令 <br>
Linux下还提供了一个killall命令，可以直接使用进程的名字而不是进程标识号，例如： <br>
＃ killall -HUP inetd <br>
<br>
*杀死进程最安全的方法是单纯使用kill命令，不加修饰符，不带标志。 <br>
<br>
<br>
<br>
首先使用ps -ef命令确定要杀死进程的PID，然后输入以下命令：  <br>
<br>
# kill -pid  <br>
<br>
注释：标准的kill命令通常都能达到目的。终止有问题的进程，并把进程的资源释放给系统。然而，如果进程启动了子进程，只杀死父进程，子进程仍在运行，因此仍消耗资源。为了防止这些所谓的“僵尸进程”，应确保在杀死父进程之前，先杀死其所有的子进程。  <br>
<br>
<br>
-------------------------------------------------------------------------------- <br>
<br>
<br>
*确定要杀死进程的PID或PPID  <br>
<br>
# ps -ef | grep httpd  <br>
-------------------------------------------------------------------------------- <br>
<br>
<br>
*以优雅的方式结束进程  <br>
<br>
# kill -l PID  <br>
<br>
-l选项告诉kill命令用好像启动进程的用户已注销的方式结束进程。当使用该选项时，kill命令也试图杀死所留下的子进程。但这个命令也不是总能成功--或许仍然需要先手工杀死子进程，然后再杀死父进程。  <br>
-------------------------------------------------------------------------------- <br>
<br>
<br>
*TERM信号  <br>
<br>
给父进程发送一个TERM信号，试图杀死它和它的子进程。  <br>
<br>
# kill -TERM PPID  <br>
-------------------------------------------------------------------------------- <br>
<br>
<br>
*killall命令  <br>
<br>
killall命令杀死同一进程组内的所有进程。其允许指定要终止的进程的名称，而非PID。  <br>
<br>
# killall httpd  <br>
-------------------------------------------------------------------------------- <br>
<br>
<br>
*停止和重启进程  <br>
<br>
有时候只想简单的停止和重启进程。如下：  <br>
<br>
# kill -HUP PID  <br>
<br>
该命令让Linux和缓的执行进程关闭，然后立即重启。在配置应用程序的时候，这个命令很方便，在对配置文件修改后需要重启进程时就可以执行此命令。  <br>
-------------------------------------------------------------------------------- <br>
<br>
<br>
*绝杀 kill -9 PID  <br>
<br>
同意的 kill -s SIGKILL  <br>
<br>
这个强大和危险的命令迫使进程在运行时突然终止，进程在结束后不能自我清理。危害是导致系统资源无法正常释放，一般不推荐使用，除非其他办法都无效。  <br>
<br>
当使用此命令时，一定要通过ps -ef确认没有剩下任何僵尸进程。只能通过终止父进程来消除僵尸进程。如果僵尸进程被init收养，问题就比较严重了。杀死init进程意味着关闭系统。  <br>
<br>
如果系统中有僵尸进程，并且其父进程是init，而且僵尸进程占用了大量的系统资源，那么就需要在某个时候重启机器以清除进程表了。</span> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/wgcno7/blog/category/Linux">Linux</a>&nbsp;<a href="http://hi.baidu.com/wgcno7/blog/item/c42233ebbfcea433b90e2d74.html#comment">查看评论</a><br>文章来源:<a href='http://hi.baidu.com/wgcno7/blog/item/c42233ebbfcea433b90e2d74.html'>http://hi.baidu.com/wgcno7/blog/item/c42233ebbfcea433b90e2d74.html</a><img src ="http://www.cppblog.com/wgcno7/aggbug/115955.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wgcno7/" target="_blank">wgcno7</a> 2010-04-29 11:25 <a href="http://www.cppblog.com/wgcno7/archive/2010/04/29/115955.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]基于TCP协议的网络程序zz</title><link>http://www.cppblog.com/wgcno7/archive/2010/04/28/115956.html</link><dc:creator>wgcno7</dc:creator><author>wgcno7</author><pubDate>Wed, 28 Apr 2010 09:55:00 GMT</pubDate><guid>http://www.cppblog.com/wgcno7/archive/2010/04/28/115956.html</guid><wfw:comment>http://www.cppblog.com/wgcno7/comments/115956.html</wfw:comment><comments>http://www.cppblog.com/wgcno7/archive/2010/04/28/115956.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wgcno7/comments/commentRss/115956.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wgcno7/services/trackbacks/115956.html</trackback:ping><description><![CDATA[
		
		<p><font face="宋体"><span align="left">下图是基于TCP协议的客户端/服务器程序的一般流程：</span><span align="left"><img width="510" height="452" border="0" src="http://hiphotos.baidu.com/countryhu/pic/item/52d6cd4e26cc013cb2de0529.jpg" small="0" class="blogimg" style="width: 635px; height: 523px;"></span></font></p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p><font face="宋体">/*server.c time 命令时间*/</font></p>
<p><font face="宋体">#include &lt;stdio.h&gt;<br>
#include &lt;sys/socket.h&gt;<br>
#include &lt;unistd.h&gt;<br>
#include &lt;sys/types.h&gt;<br>
#include &lt;netinet/in.h&gt;<br>
#include &lt;arpa/inet.h&gt; //很重要的库，inet_ntop函数源于此。<br>
#include &lt;stdlib.h&gt;<br>
#include &lt;time.h&gt;<br>
#include &lt;string.h&gt;&#160;&#160;  //not strings.h</font></p>
<p><font face="宋体">#define SERVER_PORT 20000&#160;&#160;&#160;  //define the defualt connect port id<br>
#define BUFFER_SIZE 255<br>
#define LENGTH_OF_LISTEN_QUEUE 20</font></p>
<p><font face="宋体">int main(void)<br>
{</font></p>
<p><font face="宋体">&#160;&#160;&#160;  pid_t childpid; //定义新fork（）进程的pid<br>
int servfd, clifd; //服务器套接字，和客户端套接字<br>
struct sockaddr_in servaddr,cliaddr; <br>
socklen_t chiaddr_len;<br>
char buf[BUFFER_SIZE], strtmp[BUFFER_SIZE];<br>
time_t timestamp;</font></p>
<p><font face="宋体">&#160;&#160;&#160;  //socket()打开一个网络通讯端口<br>
servfd = socket(AF_INET, SOCK_STREAM, 0 );&#160;&#160;  </font></p>
<p><font face="宋体">&#160;&#160;&#160; /*首先将整个结构体清零，然后设置地址类型为AF_INET，网络地址为INADDR_ANY，这个宏表示本地的任意IP地址，因为服务器可能有多个网 卡，每个网卡也可能绑定多个IP地址，这样设置可以在所有的IP地址上监听，直到与某个客户端建立了连接时才确定下来到底用哪个IP地址，端口号为 SERV_PORT，我们自己定义为8000。*/<br>
bzero( &amp;servaddr, sizeof( servaddr ) );<br>
servaddr.sin_family = AF_INET;<br>
servaddr.sin_port = htons(SERVER_PORT);<br>
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);</font></p>
<font face="宋体">
<p><br>
bind(servfd, (struct sockaddr*) &amp;servaddr, sizeof(servaddr)); //用bind绑定一个固定的网络地址和端口</p>
<p><br>
/*listen()声明sockfd处于监听状态，并且最多允许有backlog个客户端处于连接待状态，如果接收到更 多的连接请求就忽略。*/<br>
listen(servfd, LENGTH_OF_LISTEN_QUEUE); <br>
<br>
printf(&quot;accepting conections ...\n&quot;);<br>
while(1)<br>
{&#160;&#160;  //server loop will nerver exit unless any body kill the process<br>
chiaddr_len = sizeof(cliaddr);</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; /*服务器调用accept()接受连接，如果服务器调用accept()时还没有客户端的连接请求，就阻塞等待直到有客户端连接上来。cliaddr是 一个传出参数，accept()返回时传出客户端的地址和端口号。addrlen参数是一个传入传出参数（value-result argument），传入的是调用者提供的缓冲区cliaddr的长度以避免缓冲区溢出问题，传出的是客户端地址结构体的实际长度（有可能没有占满调用者 提供的缓冲区）。如果给cliaddr参数传NULL，表示不关心客户端的地址*/<br>
clifd = accept(servfd,( struct sockaddr * ) &amp;cliaddr, &amp;chiaddr_len);</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160; if( childpid = fork(),childpid == 0 ) //注意fork() create a child processOn success, the PID of the child process is returned in&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //the parent’s thread of execution, and a 0 is returned in the child’s thread of execution.<br>
{<br>
close(servfd);&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;  //关掉子进程的sevfd</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; printf( &quot; from client,IP:%s,Port:%d\n &quot;,inet_ntop(AF_INET, &amp;cliaddr.sin_addr, buf,sizeof(buf)),ntohs(cliaddr.sin_port));<br>
while(1)<br>
{<br>
read(clifd,buf,BUFFER_SIZE);<br>
//对传来的命令进行处理<br>
if( strncmp(buf, &quot;time&quot;,4) == 0)<br>
{<br>
timestamp = time(NULL);<br>
snprintf(buf, sizeof(buf), &quot;%.24s\r\n&quot;,ctime( &amp;timestamp ));<br>
write(clifd,buf,strlen(buf));<br>
}<br>
else<br>
{<br>
snprintf(strtmp, sizeof(strtmp),&quot;%s&quot;,&quot;Sorry! commond not found!\n&quot;);<br>
write(clifd,strtmp,strlen(strtmp));<br>
}<br>
}<br>
close(clifd); //关掉子进程的clifd<br>
exit(0);<br>
} //if<br>
close(clifd); //关掉父进程的clifd套接字</p>
<p>&#160;&#160;&#160;  }<br>
return 0;<br>
}</p>
<p><br>
/*client316.c*/<br>
#include &lt;stdio.h&gt;<br>
#include &lt;string.h&gt;<br>
#include &lt;sys/socket.h&gt;<br>
#include &lt;netinet/in.h&gt;<br>
#include &lt;stdlib.h&gt;<br>
#include &lt;unistd.h&gt;</p>
<p>#define MAXLINE 80<br>
#define SERV_PORT 20000</p>
<p>int main(int argc, char **argv)<br>
{<br>
struct sockaddr_in servaddr;<br>
char buf[MAXLINE];<br>
int sockfd,n;<br>
char str[MAXLINE];</p>
<p>&#160;&#160;&#160;  sockfd = socket(AF_INET,SOCK_STREAM,0);</p>
<p>&#160;&#160;&#160;  bzero(&amp;servaddr, sizeof(servaddr));<br>
servaddr.sin_family = AF_INET;<br>
inet_pton(AF_INET,&quot;192.168.13.128&quot;, &amp;servaddr.sin_addr);<br>
servaddr.sin_port = htons(SERV_PORT);</p>
<p>&#160;&#160;&#160;  connect(sockfd, (struct sockaddr *) &amp; servaddr, sizeof(servaddr)); //connect绑定服务器套接字，地址等信息<br>
while(fgets(str,MAXLINE,stdin) != NULL) //从屏幕中读取一行数据<br>
{<br>
write(sockfd,str,strlen(str));<br>
n = read(sockfd,buf,MAXLINE);<br>
if(n == 0)<br>
{<br>
printf(&quot;Server has been closed.\n&quot;);<br>
break;<br>
}<br>
else<br>
{<br>
write(STDOUT_FILENO, &quot;Response from server:&quot;,21); <br>
write(STDOUT_FILENO, buf, n);<br>
}<br>
}<br>
close(sockfd);<br>
<br>
return 0;<br>
}</p>
<p><br>
/*makefile*/<br>
all: server client<br>
server:server315.c<br>
gcc $^ -o $@ <br>
client:client316.c<br>
gcc $^ -o $@</p>
<p><br>
操作步骤：1.新建 vi server315.c 并写入代码。然后保存esc，:wq<br>
2.新建 vi client316.c 并写入代码。然后保存esc，:wq<br>
3.新建vi makefile并写入代码。然后保存esc，:wq<br>
4.执行命令make<br>
5.执行./server<br>
6.clone Session（新建一个窗口）。执行命令./client<br>
7.输入命令。如是time.则返回服务器当前时间。</p>
<p> </p>
<p>注： 部分内容（如流程图）参考Linux_C一站式学习_最新版.pdf</p>
</font> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/wgcno7/blog/category/%CD%F8%C2%E7%B1%E0%B3%CC">网络编程</a>&nbsp;<a href="http://hi.baidu.com/wgcno7/blog/item/1b54e214e3fb2814962b4344.html#comment">查看评论</a><br>文章来源:<a href='http://hi.baidu.com/wgcno7/blog/item/1b54e214e3fb2814962b4344.html'>http://hi.baidu.com/wgcno7/blog/item/1b54e214e3fb2814962b4344.html</a><img src ="http://www.cppblog.com/wgcno7/aggbug/115956.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wgcno7/" target="_blank">wgcno7</a> 2010-04-28 17:55 <a href="http://www.cppblog.com/wgcno7/archive/2010/04/28/115956.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>