﻿<?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++博客-andylei</title><link>http://www.cppblog.com/andylei/</link><description /><language>zh-cn</language><lastBuildDate>Thu, 09 Apr 2026 04:50:04 GMT</lastBuildDate><pubDate>Thu, 09 Apr 2026 04:50:04 GMT</pubDate><ttl>60</ttl><item><title>Unix下IO模型</title><link>http://www.cppblog.com/andylei/archive/2010/03/30/110966.html</link><dc:creator>逆水行舟</dc:creator><author>逆水行舟</author><pubDate>Tue, 30 Mar 2010 08:28:00 GMT</pubDate><guid>http://www.cppblog.com/andylei/archive/2010/03/30/110966.html</guid><wfw:comment>http://www.cppblog.com/andylei/comments/110966.html</wfw:comment><comments>http://www.cppblog.com/andylei/archive/2010/03/30/110966.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/andylei/comments/commentRss/110966.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/andylei/services/trackbacks/110966.html</trackback:ping><description><![CDATA[Unix下我们可用的五种IO模型是：<br>
<ul>
    <li>阻塞I/O</li>
    <li>非阻塞I/O</li>
    <li>I/O复用</li>
    <li>信号驱动I/O</li>
    <li>异步I/O(POSIX.1的aio_序列函数</li>
</ul>
<ol>
    <li>阻塞I/O<br>是最流行的I/O模型,以recvfrom为例,此系统调用直到数据到达且拷贝到应用缓冲区或出错才返回.进程阻塞于该系统调用,然后1).等待数据到达内核缓冲区,2)将数据从内核缓冲区中拷贝到用户空间中应用程序缓冲区. 拷贝完成后,返回成功指示.<br><br></li>
    <li>非阻塞I/O<br>进程不阻塞于I/O函数(recvfrom),不会等待数据, 如果数据没有到达,就立即从recvfrom返回到应用进程,然后等待一段时间,再次调用recvfrom,这个过程叫轮询(进程对一个非阻塞描述字循环调用I/O函数). 通过轮询不断查询内核,看看操作是否准备好,这对CPU时间是极大浪费.<br></li>
    <li>I/O复用<br>通过select或poll调用,在这两个调用中的某一个阻塞,而不是阻塞于真正的系统调用. 这样的好处在于select可这等待多个描述字,阻塞IO模型在真正的系统调用recvfrom上阻塞,而recvfrom一次只能读一个描述字,对它的阻塞使得进程只能为这个描述字傻傻等待. 一般应用系统中都会有多个描述字.使用select可这很方便地对所有提供的描述字进行等待.<br></li>
    <li>信号驱动I/O<br>在描述字准备好后,让内核给应用进程发一个信号SIGIO,应用进程捕捉到该信号后再对描述字调用recvfrom. 首先允许套接口进行信号驱动,并通过系统调用sigaction安装一个信号处理程序,此系统调用立即返回,进程继续工作.<br></li>
    <li>异步I/O(POSIX.1的aio_序列函数<br>异步I/O是指Posix.1的1993版本中的新内容。异步的意思是，让内核启动操作，并在整个操作完成后(包括将数据从内核拷贝到应用进程的缓冲区中)通知我们。这种模型与其他四种模型的主要区别在于，信号驱动IO是由内核通知我们什么时候可以启动一个io操作， 而异步io模型是由内核通知我们io操作何时完成。</li>
</ol>
各种模型比较：<br>1.前四种模型在第一阶段（等待数据阶段）的行为不同， 在第二阶段基本相同：在将数据从内核拷贝到调用者的缓冲区时，进程都阻塞于recvfrom调用。<br>2.异步io模型处理的两个阶段都不同于前四种。<br><br>同步I/O 与异步I/O<br>同步I/O操作引起请求进程阻塞，直到IO操作完成<br>异步I/O操作不引起请求进程阻塞<br>上述前四种IO模型都属于同步IO, 因为真正的IO操作（recvfrom）阻塞进程。<br><br><br><br> <img src ="http://www.cppblog.com/andylei/aggbug/110966.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/andylei/" target="_blank">逆水行舟</a> 2010-03-30 16:28 <a href="http://www.cppblog.com/andylei/archive/2010/03/30/110966.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用 lsof 工具查看CLOSE_WAIT进程信息</title><link>http://www.cppblog.com/andylei/archive/2010/03/25/110549.html</link><dc:creator>逆水行舟</dc:creator><author>逆水行舟</author><pubDate>Thu, 25 Mar 2010 12:45:00 GMT</pubDate><guid>http://www.cppblog.com/andylei/archive/2010/03/25/110549.html</guid><wfw:comment>http://www.cppblog.com/andylei/comments/110549.html</wfw:comment><comments>http://www.cppblog.com/andylei/archive/2010/03/25/110549.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/andylei/comments/commentRss/110549.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/andylei/services/trackbacks/110549.html</trackback:ping><description><![CDATA[编写unix网络通信程序时，经常会遗留一些状态为CLOSE_WAIT的进程，使用netstat 命令查看，结果中没有进程相关的信息：<br>netstat -a|grep 9877<br>tcp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 ylei-laptop.local:53773 ylei-linux.local:9877&nbsp;&nbsp; CLOSE_WAIT <br>tcp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 ylei-laptop.local:54080 ylei-laptop.local:9877&nbsp; CLOSE_WAIT&nbsp;
<br><br>这时可这使用lsof工具，它可这显示出状态为CLOSE_WAIT的进程的程序名（command）,进程id(pid),&nbsp; 等等。<br><br>lsof -i@ylei-laptop.local<br>COMMAND&nbsp;&nbsp;&nbsp; PID USER&nbsp;&nbsp; FD&nbsp;&nbsp; TYPE DEVICE SIZE/OFF NODE NAME<br>gvfsd-smb 2217 ylei&nbsp;&nbsp; 18u&nbsp; IPv4&nbsp; 41440&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0t0&nbsp; TCP ylei-laptop.local:60953-&gt;ylei-linux.local:netbios-ssn (ESTABLISHED)<br>tcpcli&nbsp;&nbsp;&nbsp; 8055 ylei&nbsp;&nbsp;&nbsp; 3u&nbsp; IPv4 312580&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0t0&nbsp; TCP ylei-laptop.local:54080-&gt;ylei-laptop.local:9877 (CLOSE_WAIT)<br>tcpcli&nbsp;&nbsp;&nbsp; 8057 ylei&nbsp;&nbsp;&nbsp; 3u&nbsp; IPv4 312872&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0t0&nbsp; TCP ylei-laptop.local:53773-&gt;ylei-linux.local:9877 (CLOSE_WAIT)<br><br>这时就可这用KILL命令来杀死这些进程。<br><br>这种CLOSE_WAIT
进程遗留多了会对系统有一定的影响，
如何避免出现CLOSE_WAIT状态的通信进程？<br><br>http://blog.chinaunix.net/u/19782/showart_218982.html<br>这是一篇lsof使用的文章，可作参考。<br>
<br><br>  <img src ="http://www.cppblog.com/andylei/aggbug/110549.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/andylei/" target="_blank">逆水行舟</a> 2010-03-25 20:45 <a href="http://www.cppblog.com/andylei/archive/2010/03/25/110549.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ubuntu9.10上pdf文件中的中文无法显示解决方案</title><link>http://www.cppblog.com/andylei/archive/2010/03/25/110538.html</link><dc:creator>逆水行舟</dc:creator><author>逆水行舟</author><pubDate>Thu, 25 Mar 2010 09:58:00 GMT</pubDate><guid>http://www.cppblog.com/andylei/archive/2010/03/25/110538.html</guid><wfw:comment>http://www.cppblog.com/andylei/comments/110538.html</wfw:comment><comments>http://www.cppblog.com/andylei/archive/2010/03/25/110538.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/andylei/comments/commentRss/110538.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/andylei/services/trackbacks/110538.html</trackback:ping><description><![CDATA[在我的64位Ubuntu9.10上，有的pdf文档中文无法显示，是空白。解决方案:<br>&nbsp;<br>1. sudo apt-get install xpdf-chinese-simplified&nbsp;
&nbsp;&nbsp; <br>2. sudo apt-get install xpdf-chinese-traditional <br>3. sudo apt-get install poppler-data<br><br>重新打开pdf文档，中文正常显示
<br><img src ="http://www.cppblog.com/andylei/aggbug/110538.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/andylei/" target="_blank">逆水行舟</a> 2010-03-25 17:58 <a href="http://www.cppblog.com/andylei/archive/2010/03/25/110538.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在QT中编写linux 程序 初次问题</title><link>http://www.cppblog.com/andylei/archive/2010/03/25/110529.html</link><dc:creator>逆水行舟</dc:creator><author>逆水行舟</author><pubDate>Thu, 25 Mar 2010 09:07:00 GMT</pubDate><guid>http://www.cppblog.com/andylei/archive/2010/03/25/110529.html</guid><wfw:comment>http://www.cppblog.com/andylei/comments/110529.html</wfw:comment><comments>http://www.cppblog.com/andylei/archive/2010/03/25/110529.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/andylei/comments/commentRss/110529.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/andylei/services/trackbacks/110529.html</trackback:ping><description><![CDATA[今天在QT中编译纯linux程序时出现一个编译错误：<br><br>multiple definition of main
<br><br>搜不半天，也没有合适的办法。<br><br>问题的出现原因在于项目的创建过程：<br>使用QT创建了一个含有main.cpp的项目，然后添加了一些*.c文件，因为同一个项目中不想同时包含两种不同类型的源文件，所以就把main.cpp改成了main.c. 但是，QT的项目文件（tcpserver.pro）中的内容多出了一个main.c来，这样，编译时,qmake会根据这个.pro文件生成Makefile, 这个Makefile中就会包含两个相同的目标main.o,连接的时候就会出现上面的错误。<br><br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">QT&nbsp;</span><span style="color: #000000;">-=</span><span style="color: #000000;">&nbsp;gui<br>TARGET&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;tcpserver<br>CONFIG&nbsp;</span><span style="color: #000000;">+=</span><span style="color: #000000;">&nbsp;console<br>CONFIG&nbsp;</span><span style="color: #000000;">-=</span><span style="color: #000000;">&nbsp;app_bundle<br>TEMPLATE&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;app<br>SOURCES&nbsp;</span><span style="color: #000000;">+=</span><span style="color: #000000;">&nbsp;main.c&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">lib</span><span style="color: #000000;">/</span><span style="color: #000000;">wrapsock.c&nbsp;\<br>&nbsp;&nbsp;&nbsp;<span style="font-weight: bold; color: red;">&nbsp;main.c&nbsp;\</span><br>&nbsp;&nbsp;&nbsp;&nbsp;..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">lib</span><span style="color: #000000;">/</span><span style="color: #000000;">str_echo.c&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">lib</span><span style="color: #000000;">/</span><span style="color: #000000;">error.c&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">lib</span><span style="color: #000000;">/</span><span style="color: #000000;">wrapunix.c&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">lib</span><span style="color: #000000;">/</span><span style="color: #000000;">writen.c&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">lib</span><span style="color: #000000;">/</span><span style="color: #000000;">readline.c<br>HEADERS&nbsp;</span><span style="color: #000000;">+=</span><span style="color: #000000;">&nbsp;..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">lib</span><span style="color: #000000;">/</span><span style="color: #000000;">unp.h</span></div>
生成的Makefile如下：<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">#######&nbsp;Compile<br><br><span style="color: red;">main.o:&nbsp;main.c&nbsp;..</span></span><span style="color: red;">/../../lib/unp.h&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;../config.h&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;../../../lib/addrinfo.h<br>&nbsp;&nbsp;&nbsp;&nbsp;$(CC)&nbsp;-c&nbsp;$(CFLAGS)&nbsp;$(INCPATH)&nbsp;-</span><span style="color: #000000;"><span style="color: red;">o&nbsp;main.o&nbsp;main.c</span><br><br>wrapsock.o:&nbsp;..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">lib</span><span style="color: #000000;">/</span><span style="color: #000000;">wrapsock.c&nbsp;..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">lib</span><span style="color: #000000;">/</span><span style="color: #000000;">unp.h&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;..</span><span style="color: #000000;">/</span><span style="color: #000000;">config.h&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">lib</span><span style="color: #000000;">/</span><span style="color: #000000;">addrinfo.h<br>&nbsp;&nbsp;&nbsp;&nbsp;$(CC)&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">c&nbsp;$(CFLAGS)&nbsp;$(INCPATH)&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">o&nbsp;wrapsock.o&nbsp;..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">lib</span><span style="color: #000000;">/</span><span style="color: #000000;">wrapsock.c<br><br><span style="color: red;">main.o:&nbsp;main.c&nbsp;..</span></span><span style="color: red;">/../../lib/unp.h&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;../config.h&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;../../../lib/addrinfo.h<br>&nbsp;&nbsp;&nbsp;&nbsp;$(CC)&nbsp;-c&nbsp;$(CFLAGS)&nbsp;$(INCPATH)&nbsp;-</span><span style="color: #000000;"><span style="color: red;">o&nbsp;main.o&nbsp;</span><br><br>str_echo.o:&nbsp;..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">lib</span><span style="color: #000000;">/</span><span style="color: #000000;">str_echo.c&nbsp;..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">lib</span><span style="color: #000000;">/</span><span style="color: #000000;">unp.h&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;..</span><span style="color: #000000;">/</span><span style="color: #000000;">config.h&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">lib</span><span style="color: #000000;">/</span><span style="color: #000000;">addrinfo.h<br>&nbsp;&nbsp;&nbsp;&nbsp;$(CC)&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">c&nbsp;$(CFLAGS)&nbsp;$(INCPATH)&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">o&nbsp;str_echo.o&nbsp;..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">lib</span><span style="color: #000000;">/</span><span style="color: #000000;">str_echo.c<br><br>error.o:&nbsp;..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">lib</span><span style="color: #000000;">/</span><span style="color: #000000;">error.c&nbsp;..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">lib</span><span style="color: #000000;">/</span><span style="color: #000000;">unp.h&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;..</span><span style="color: #000000;">/</span><span style="color: #000000;">config.h&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">lib</span><span style="color: #000000;">/</span><span style="color: #000000;">addrinfo.h<br>&nbsp;&nbsp;&nbsp;&nbsp;$(CC)&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">c&nbsp;$(CFLAGS)&nbsp;$(INCPATH)&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">o&nbsp;error.o&nbsp;..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">..</span><span style="color: #000000;">/</span><span style="color: #000000;">lib</span><span style="color: #000000;">/</span><span style="color: #000000;">error.c<br></span></div>
<br><br>解决办法是：<br>
修改项目文件（tcpserver.pro）
，去掉重复的main.c.然后依次调用<br>clean all<br>qmake<br>make<br><img src ="http://www.cppblog.com/andylei/aggbug/110529.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/andylei/" target="_blank">逆水行舟</a> 2010-03-25 17:07 <a href="http://www.cppblog.com/andylei/archive/2010/03/25/110529.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>TCP状态转换</title><link>http://www.cppblog.com/andylei/archive/2010/03/23/110337.html</link><dc:creator>逆水行舟</dc:creator><author>逆水行舟</author><pubDate>Tue, 23 Mar 2010 03:00:00 GMT</pubDate><guid>http://www.cppblog.com/andylei/archive/2010/03/23/110337.html</guid><wfw:comment>http://www.cppblog.com/andylei/comments/110337.html</wfw:comment><comments>http://www.cppblog.com/andylei/archive/2010/03/23/110337.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/andylei/comments/commentRss/110337.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/andylei/services/trackbacks/110337.html</trackback:ping><description><![CDATA[TCP状态转换看起来很复杂，实质很只有两个主要状态，<br>1. 从CLOSED 到 ESTABLISHED<br>2. 从ESTABLISHED到CLOSED<br><br>TCP应用一般涉及客户和服务器应用，根据客户和服务器端的不同，对TCP的状态进行细分：<br><br><br>对照Unix 网络编程卷1 第33页的图，下面分别是客户端和服务器端的TCP状态转换过程。<br>
<br>客户端<br>　　客户端的TCP状态转换<br>
<ol>
    <li>客户端调用connect()，TCP发送SYN给服务器，执行主动打开，状态从CLOSED到SYN_SENT</li>
    <li>客户处于SYN_SENT状态时，可能出现三种情况：</li>
    <ul>
        <li>如果发送SYN后没有收到服务器响应，出现超时，状态回到CLOSED</li>
        <li>如果接收到服务器的ACK和SYN,客户就会发送ACK作为对服务器的SYN确认，这时状态转换到ESTABLISHED，表示连接已建立</li>
        <li>如果客户发送SYN的<span style="font-weight: bold;">同时</span>接收到服务器发来的SYN,状态会变为SYN_RCVD（同时打开），这属于不正常的客户端TCP状态，在unp第33面的TCP状态转换图中，使用细实线来连接这种状态转换，表示不正常的状态转换。在图例中说明，正常的客户端TCP状态转换使用粗实线来连接，正常的服务器TCP状态转换使用粗虚线连接。</li>
    </ul>
    <li>客户端经过上述第二步进入ESTABLISHED后，它发送完数据，然后客户端应用程序调用close(),它的下一个状态是关闭，即CLOSED,但是，有几种情况可以进入CLOSED状态</li>
    <ul>
        <li>客户端应用程序调用close后，TCP发送FIN给服务器，TCP处于FIN_WAIT_1状态,这个状态wait_1表示等待服务器对FIN的确认ACK,如果接收到服务器对FIN的确认，客户端TCP状态转换为FIN_WAIT_2,wait_2表示客户还在等待服务器的FIN.如果接收到服务器的FIN，客户就发送ACK对服务器的FIN进行确认，然后状态进入TIME_WAIT</li>
        <li>同时接收到FIN和ACK，然后发送ACK给服务器，进入TIME_WAIT状态<br></li>
        <li>客户端应用程序调用close后，TCP发送FIN给服务器，如果发送的同时接收到服务器的FIN，状态转换为CLOSING,表示同时关闭</li>
    </ul>
</ol>
服务器<br>&nbsp;&nbsp;&nbsp; 服务器应用程序启动后,一直等待客户端连接, 当等到以后, 执行被动打开。<br>
<ol>
    <li>服务器程序启动后，如果程序编写正确，自动从初始状态CLOSED转换为LISTEN</li>
    <li>服务器收到客户端的SYN, 然后发送SYN和ACK给客户端，这时服务器处于SYN_RCVD</li>
    <li>服务器收到客户端的ACK, 状态变为ESTABLISHED</li>
    <li>服务器收到客户端的FIN, 然后发送ACK给客户端，状态变为CLOSE_WAIT</li>
    <li>服务器应用程序调用close时，TCP发送FIN给客户，状态为LAST_ACK，表示等待最后一个ACK.</li>
    <li>服务器收到客户的ACK, 状态变为初始状态 CLOSED.<br></li>
</ol>
<br><br><br>       <img src ="http://www.cppblog.com/andylei/aggbug/110337.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/andylei/" target="_blank">逆水行舟</a> 2010-03-23 11:00 <a href="http://www.cppblog.com/andylei/archive/2010/03/23/110337.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在ubuntu中安装 manpages-dev</title><link>http://www.cppblog.com/andylei/archive/2010/03/19/110135.html</link><dc:creator>逆水行舟</dc:creator><author>逆水行舟</author><pubDate>Fri, 19 Mar 2010 14:58:00 GMT</pubDate><guid>http://www.cppblog.com/andylei/archive/2010/03/19/110135.html</guid><wfw:comment>http://www.cppblog.com/andylei/comments/110135.html</wfw:comment><comments>http://www.cppblog.com/andylei/archive/2010/03/19/110135.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/andylei/comments/commentRss/110135.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/andylei/services/trackbacks/110135.html</trackback:ping><description><![CDATA[By default installation, Ubuntu does not include the manual pages for developer, use the following command to install them manually:<br><br>1. apt-cache search manpages-dev <br>&nbsp;&nbsp;&nbsp; This command search the man pages and output the following:<br><span style="color: red;">manpages-dev - Manual pages about using GNU/Linux for development</span><br style="color: red;"><span style="color: red;">manpages-de-dev - German development manpages</span><br style="color: red;"><span style="color: red;">manpages-fr-extra - French version of the manual pages</span><br style="color: red;"><br><br>2. sudo apt-get install manpages-dev<br>this command install the man pages in the computer.<br><br> <img src ="http://www.cppblog.com/andylei/aggbug/110135.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/andylei/" target="_blank">逆水行舟</a> 2010-03-19 22:58 <a href="http://www.cppblog.com/andylei/archive/2010/03/19/110135.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>函数指针的应用</title><link>http://www.cppblog.com/andylei/archive/2010/02/04/107180.html</link><dc:creator>逆水行舟</dc:creator><author>逆水行舟</author><pubDate>Thu, 04 Feb 2010 09:02:00 GMT</pubDate><guid>http://www.cppblog.com/andylei/archive/2010/02/04/107180.html</guid><wfw:comment>http://www.cppblog.com/andylei/comments/107180.html</wfw:comment><comments>http://www.cppblog.com/andylei/archive/2010/02/04/107180.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/andylei/comments/commentRss/107180.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/andylei/services/trackbacks/107180.html</trackback:ping><description><![CDATA[<ol>
    <li>函数指针的定义:<br>void (*funcPtr)();　<br>这个表达式定义一个指向没有参数，没有返回值的函数。函数指针变量名是funcPtr. 分析一个较复杂的函数指针定义表达式时，可按下列步骤进行：</li>
    <ul>
        <li>先找到变量名</li>
        <li>找变量名右边的项，然后找左边的项，然后右边，...这种右-左－右的方法适用于大多数的表达式。</li>
    </ul>
    <li>void (*funcPtr)();的分析</li>
    <ul>
        <li>变量名是funcPtr,</li>
        <li>找右边，右边没有项了，只是一个右括号:")"</li>
        <li>找左边，变量左边是*表示funcPtr是一个指针</li>
        <li>找右边, 是(),表示一个空参数列表</li>
        <li>找左边，*的左边是void,　表示函数的返回类型。</li>
    </ul>
    <ul>
        <li>结果:<br>funcPtr是一个指向函数的指针，该函数无参数，返回类型是void.</li>
    </ul>
    <li>void * (*(*fp1)(int))[10];的分析:</li>
    <ul>
        <li>fp1</li>
        <li>右: ) <br></li>
        <li>左: *, fp1是一个指针</li>
        <li>右:(int), fp1指向的函数的参数是int</li>
        <li>左:*,fp1指向的函数的返回值是一个指针</li>
        <li>右[10],fp1指向的函数的返回值是一个指针数组</li>
        <li>左void *,指针数组指向的是void类型。<br></li>
    </ul>
    <li>float (*(*fp2)(int,int,float))(int);</li>
    <ul>
        <li>&nbsp;fp2指向一个带有三个参数的函数，这个函数f返回一个指针，该指针又指向一个函数，这个函数有一个int参数，返回类型是float.</li>
    </ul>
    <li>使用函数指针</li>
    <ul>
        <li>定义函数指针</li>
        <li>定义函数</li>
        <li>将函数地址赋给函数指针</li>
        <li>通过函数指针调用函数</li>
    </ul>
</ol>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">iostream</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">using</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">namespace</span><span style="color: #000000;">&nbsp;std;<br><br></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;func(){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">"</span><span style="color: #000000;">func()&nbsp;called<img src="http://www.cppblog.com/Images/dot.gif"></span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;endl;&nbsp;<br>}<br><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main(){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">*</span><span style="color: #000000;">fp)();&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;define&nbsp;a&nbsp;function&nbsp;pointer</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fp&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;func;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Initialize&nbsp;it</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #000000;">*</span><span style="color: #000000;">fp)();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Dereferencing&nbsp;calls&nbsp;the&nbsp;function</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">*</span><span style="color: #000000;">fp2)()&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;func;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;define&nbsp;and&nbsp;initialize</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #000000;">*</span><span style="color: #000000;">fp2)();<br>}</span></div>
<br><br><img src ="http://www.cppblog.com/andylei/aggbug/107180.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/andylei/" target="_blank">逆水行舟</a> 2010-02-04 17:02 <a href="http://www.cppblog.com/andylei/archive/2010/02/04/107180.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++中使用#号输出变量名 - 在调试时有用</title><link>http://www.cppblog.com/andylei/archive/2010/02/04/107171.html</link><dc:creator>逆水行舟</dc:creator><author>逆水行舟</author><pubDate>Thu, 04 Feb 2010 07:21:00 GMT</pubDate><guid>http://www.cppblog.com/andylei/archive/2010/02/04/107171.html</guid><wfw:comment>http://www.cppblog.com/andylei/comments/107171.html</wfw:comment><comments>http://www.cppblog.com/andylei/archive/2010/02/04/107171.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/andylei/comments/commentRss/107171.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/andylei/services/trackbacks/107171.html</trackback:ping><description><![CDATA[通过#define来使用#来输出变量的名字<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;P(A)&nbsp;cout&nbsp;&lt;&lt;&nbsp;#A&nbsp;&lt;&lt;&nbsp;":&nbsp;"&nbsp;&lt;&lt;&nbsp;(A)&nbsp;&lt;&lt;&nbsp;endl;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;_tmain(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;argc,&nbsp;_TCHAR</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;argv[])<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;a&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">,&nbsp;b&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">2</span><span style="color: #000000;">,&nbsp;c&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">3</span><span style="color: #000000;">;<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;P(a);<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;P(b);<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;P(c);<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;P(a&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;b);<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">}</span></div>
<br>输出:<br>a: 1<br>b: 2<br>c: 3<br>a + b: 3<br><br>在Think In C++中，有这样一段描述:<br>When you put a # before an argument in a preprocessor macro, the preprocessor turns that argument into a character array. <br><br>在定义宏的时候，1. 在变量名前加#, 2. 输出变量值的时候使用（）括号括起来。<br><br><br>    <img src ="http://www.cppblog.com/andylei/aggbug/107171.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/andylei/" target="_blank">逆水行舟</a> 2010-02-04 15:21 <a href="http://www.cppblog.com/andylei/archive/2010/02/04/107171.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>