﻿<?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>IT博客-I believe I can make a miracle</title><link>http://www.cnitblog.com/wujian-IT/</link><description /><language>zh-cn</language><lastBuildDate>Wed, 29 Apr 2026 05:16:01 GMT</lastBuildDate><pubDate>Wed, 29 Apr 2026 05:16:01 GMT</pubDate><ttl>60</ttl><item><title>epoll的用法</title><link>http://www.cnitblog.com/wujian-IT/archive/2008/02/19/39948.html</link><dc:creator>吴剑</dc:creator><author>吴剑</author><pubDate>Tue, 19 Feb 2008 10:17:00 GMT</pubDate><guid>http://www.cnitblog.com/wujian-IT/archive/2008/02/19/39948.html</guid><wfw:comment>http://www.cnitblog.com/wujian-IT/comments/39948.html</wfw:comment><comments>http://www.cnitblog.com/wujian-IT/archive/2008/02/19/39948.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnitblog.com/wujian-IT/comments/commentRss/39948.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/wujian-IT/services/trackbacks/39948.html</trackback:ping><description><![CDATA[<p>看了很多的资料，决定自己写个程序练习练习，于是就自己写了个小程序来练练手：<br>Server端（linux环境下）：<br>#include &lt;stdio.h&gt;<br>#include &lt;unistd.h&gt;<br>#include &lt;string.h&gt;<br>#include &lt;stdlib.h&gt;<br>#include &lt;sys/epoll.h&gt;<br>#include &lt;sys/types.h&gt;<br>#include &lt;sys/socket.h&gt;<br>&nbsp;#include &lt;arpa/inet.h&gt;<br>&nbsp;#include &lt;fcntl.h&gt;</p>
<p><br>#define PORT&nbsp;&nbsp;&nbsp;&nbsp;3456<br>#define BACKLOG&nbsp;&nbsp;&nbsp;10<br>#define MAX_EPOLL_FD&nbsp;65535</p>
<p>int CreateTcpListenSocket();<br>int InitEpollFd();<br>void UseConnectFd(int sockfd);<br>void setnonblocking(int sock);</p>
<p>static int listenfd;</p>
<p>int main()<br>{<br>&nbsp;int epoll_fd;<br>&nbsp;int nfds;<br>&nbsp;int i;<br>&nbsp;<br>&nbsp;struct epoll_event events[50];<br>&nbsp;struct epoll_event tempEvent;</p>
<p>&nbsp;int sockConnect;<br>&nbsp;struct sockaddr_in remoteAddr;<br>&nbsp;int addrLen;</p>
<p>&nbsp;addrLen = sizeof(struct sockaddr_in);<br>&nbsp;epoll_fd = InitEpollFd();<br>&nbsp;if (epoll_fd == -1)<br>&nbsp;{<br>&nbsp;&nbsp;perror("init epoll fd error.");<br>&nbsp;&nbsp;exit(1);<br>&nbsp;}</p>
<p>&nbsp;printf("begin in loop.\n");<br>&nbsp;while (1)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;nfds = epoll_wait(epoll_fd, events, 50, 1000);<br>&nbsp;&nbsp;//sleep(3);<br>&nbsp;&nbsp;printf("connect num: %d\n", nfds);<br>&nbsp;&nbsp;if (nfds == -1)<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;perror("epoll_wait error.");<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;for (i = 0; i &lt; nfds; i++)<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;if (listenfd == events[i].data.fd)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;printf("connected success\n");<br>&nbsp;&nbsp;&nbsp;&nbsp;sockConnect = accept(events[i].data.fd, (struct sockaddr*)&amp;remoteAddr, &amp;addrLen);<br>&nbsp;&nbsp;&nbsp;&nbsp;if (sockConnect == -1)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror("accept error.");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;setnonblocking(sockConnect);<br>&nbsp;&nbsp;&nbsp;&nbsp;tempEvent.events = EPOLLIN | EPOLLET;<br>&nbsp;&nbsp;&nbsp;&nbsp;tempEvent.data.fd = sockConnect;<br>&nbsp;&nbsp;&nbsp;&nbsp;if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, sockConnect, &amp;tempEvent) &lt; 0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror("epoll ctl error.");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;UseConnectFd(events[i].data.fd);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}<br>&nbsp;<br>}</p>
<p>int CreateTcpListenSocket()<br>{<br>&nbsp;int sockfd;<br>&nbsp;struct sockaddr_in localAddr;<br>&nbsp;if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)<br>&nbsp;{<br>&nbsp;&nbsp;perror("create socket fail");<br>&nbsp;&nbsp;return -1;<br>&nbsp;}</p>
<p>&nbsp;setnonblocking(sockfd);<br>&nbsp;<br>&nbsp;bzero(&amp;localAddr, sizeof(localAddr));<br>&nbsp;localAddr.sin_family = AF_INET;<br>&nbsp;localAddr.sin_port = htons(PORT);<br>&nbsp;localAddr.sin_addr.s_addr = htonl(INADDR_ANY);</p>
<p>&nbsp;if (bind(sockfd,&nbsp; (struct sockaddr*)&amp;localAddr, sizeof(struct sockaddr)) == -1)<br>&nbsp;{<br>&nbsp;&nbsp;perror("bind error");<br>&nbsp;&nbsp;return -1;<br>&nbsp;}</p>
<p>&nbsp;if (listen(sockfd, BACKLOG) == -1)<br>&nbsp;{<br>&nbsp;&nbsp;perror("listen error");<br>&nbsp;&nbsp;return -1;<br>&nbsp;}</p>
<p>&nbsp;return sockfd;<br>}</p>
<p>int InitEpollFd()<br>{<br>&nbsp;//epoll descriptor<br>&nbsp;int s_epfd;<br>&nbsp;struct epoll_event ev;<br>&nbsp;</p>
<p>&nbsp;listenfd = CreateTcpListenSocket();</p>
<p>&nbsp;if (listenfd == -1)<br>&nbsp;{<br>&nbsp;&nbsp;perror("create tcp listen socket error");<br>&nbsp;&nbsp;return -1;<br>&nbsp;}</p>
<p>&nbsp;s_epfd = epoll_create(MAX_EPOLL_FD);<br>&nbsp;ev.events = EPOLLIN;<br>&nbsp;ev.data.fd = listenfd;<br>&nbsp;if (epoll_ctl(s_epfd, EPOLL_CTL_ADD, listenfd, &amp;ev) &lt; 0)<br>&nbsp;{<br>&nbsp;&nbsp;perror("epoll ctl error");<br>&nbsp;&nbsp;return -1;<br>&nbsp;}</p>
<p>&nbsp;return s_epfd;<br>}</p>
<p>void UseConnectFd(int sockfd)<br>{<br>&nbsp;char recvBuff[1500];<br>&nbsp;int recvNum = 0;</p>
<p>&nbsp;recvNum = recv(sockfd, recvBuff, 1500, 0);<br>&nbsp;if (recvNum == -1)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;perror("recv error.");<br>&nbsp;&nbsp;return;<br>&nbsp;&nbsp;}</p>
<p>&nbsp;recvBuff[recvNum] = '\0';<br>&nbsp;printf("message: %s \n", recvBuff);<br>}</p>
<p>void setnonblocking(int sock)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; int opts;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; opts=fcntl(sock,F_GETFL);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; if(opts&lt;0)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; perror("fcntl(sock,GETFL)");</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(1);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; opts = opts|O_NONBLOCK;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; if(fcntl(sock,F_SETFL,opts)&lt;0)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; perror("fcntl(sock,SETFL,opts)");</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(1);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; </p>
<p>}</p>
<p>client端（VC6.0）:<br><br>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;<br>#include &lt;string.h&gt;<br>#include &lt;winsock2.h&gt;<br>//#include &lt;sockets.h&gt;<br>//#include &lt;unistd.h&gt;<br>//#include &lt;sys/types.h&gt;<br>//#include &lt;sys/socket.h&gt;<br>//#include &lt;arpa/inet.h&gt;<br>#pragma comment(lib,"wsock32.lib") <br>#define PORT&nbsp;&nbsp;&nbsp;&nbsp;3456</p>
<p>int main()<br>{<br>&nbsp;int sockfd;<br>&nbsp;struct sockaddr_in remoteAddr;<br>&nbsp;char mesg[] = "This is a client for epoll test";<br>&nbsp;WSADATA wsdata;</p>
<p>&nbsp;memset(&amp;remoteAddr, 0, sizeof(remoteAddr));<br>&nbsp;remoteAddr.sin_family = AF_INET;<br>&nbsp;remoteAddr.sin_port = htons(PORT);<br>&nbsp;remoteAddr.sin_addr.s_addr = inet_addr("10.40.8.15");</p>
<p>&nbsp;<br>&nbsp;WSAStartup(0x0202,&amp;wsdata);</p>
<p>&nbsp;if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;perror("create socket fail.");<br>&nbsp;&nbsp;return -1;<br>&nbsp;&nbsp;}<br>&nbsp;WSAAsyncSelect(sockfd, NULL, NULL, 0);<br>&nbsp;printf("server ip is: %s\n", (char *)inet_ntoa(remoteAddr.sin_addr));</p>
<p>//&nbsp;while (1)<br>//&nbsp;{<br>&nbsp;&nbsp;if (connect(sockfd, (struct sockaddr*)&amp;remoteAddr, sizeof(remoteAddr)) == -1)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;//perror("connect error.");<br>&nbsp;&nbsp;&nbsp;printf("Error code: %d\n", WSAGetLastError());<br>&nbsp;&nbsp;&nbsp;return -1;<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;//printf("times\n");<br>//&nbsp;}</p>
<p>&nbsp;printf("connected!\n");<br>&nbsp;while (1)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;send(sockfd, mesg, strlen(mesg), 0);<br>&nbsp;&nbsp;printf("send over\n");<br>&nbsp;&nbsp;Sleep(1000);<br>&nbsp;&nbsp;}<br>}<br></p>
<img src ="http://www.cnitblog.com/wujian-IT/aggbug/39948.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/wujian-IT/" target="_blank">吴剑</a> 2008-02-19 18:17 <a href="http://www.cnitblog.com/wujian-IT/archive/2008/02/19/39948.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>UTF-8, Unicode, GB2312格式串转换之C语言版</title><link>http://www.cnitblog.com/wujian-IT/archive/2007/12/13/37671.html</link><dc:creator>吴剑</dc:creator><author>吴剑</author><pubDate>Thu, 13 Dec 2007 11:21:00 GMT</pubDate><guid>http://www.cnitblog.com/wujian-IT/archive/2007/12/13/37671.html</guid><wfw:comment>http://www.cnitblog.com/wujian-IT/comments/37671.html</wfw:comment><comments>http://www.cnitblog.com/wujian-IT/archive/2007/12/13/37671.html#Feedback</comments><slash:comments>63</slash:comments><wfw:commentRss>http://www.cnitblog.com/wujian-IT/comments/commentRss/37671.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/wujian-IT/services/trackbacks/37671.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（申明：此文章属于原创，若转载请表明作者和原处链接 ）&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;author:&nbsp;&nbsp;&nbsp;wu.jian&nbsp;&nbsp;&nbsp;（吴剑）&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;English name: Sword<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;date:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2007-12-13<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;purpose:&nbsp;&nbsp;&nbsp;知识共享<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这几天工作上碰到了UTF-8转GB2312的问题，而且是在嵌入式的环境下，没有API可用，查了很多网上的资料，大多调用VC或者linux下自带的接口。在这里我将这两天的工作做个总结。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;总的来说分为两大步（这里就不介绍基础知识了）：<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一、UTF8 -&gt; Unicode<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;由于UTF8和Unicode存在着联系，所以不需要任何库就可以直接进行转换。首先要看懂UTF8的编码格式：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U-00000000&nbsp;-&nbsp;U-0000007F:&nbsp;0xxxxxxx&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U-00000080&nbsp;-&nbsp;U-000007FF:&nbsp;110xxxxx&nbsp;10xxxxxx&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U-00000800&nbsp;-&nbsp;U-0000FFFF:&nbsp;1110xxxx&nbsp;10xxxxxx&nbsp;10xxxxxx&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U-00010000&nbsp;-&nbsp;U-001FFFFF:&nbsp;11110xxx&nbsp;10xxxxxx&nbsp;10xxxxxx&nbsp;10xxxxxx&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U-00200000&nbsp;-&nbsp;U-03FFFFFF:&nbsp;111110xx&nbsp;10xxxxxx&nbsp;10xxxxxx&nbsp;10xxxxxx&nbsp;10xxxxxx&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U-04000000&nbsp;-&nbsp;U-7FFFFFFF:&nbsp;1111110x&nbsp;10xxxxxx&nbsp;10xxxxxx&nbsp;10xxxxxx&nbsp;10xxxxxx&nbsp;10xxxxxx&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;前面几个1就代表后面几个字节是属于一起的。如果要解析一长串UTF8格式的字符串，这点就很有用了。下面这个函数就是判断前面几个1的（这里有define APP_PRINT printf，这样当release的时候将这个宏定义为空就行了，不需要一个一个去改，又方便重新调试）：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int GetUtf8ByteNumForWord(u8 firstCh)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;u8 temp = 0x80;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int num = 0;<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while (temp &amp; firstCh)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;num++;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp = (temp &gt;&gt; 1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;APP_PRINT("the num is: %d", num);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return num;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;利用这个函数可以得到字符串中那几个字节是一起的。因为UTF8最大只有6个字节，所以就根据返回值来处理这里我只处理了3个字节和1个字节的UTF8的编码，因为一般来说中文在UTF8中是3个字节。<br><br>//将len个字节的UTF8格式的转换成GB2312格式存放在temp预先申请好的缓冲区中<br>void Utf8ToGb2312(const char* utf8, int len, char *temp)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;APP_PRINT("utf8-&gt;unicode: \n");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;APP_PRINT("utf8: [");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int k = 0; k &lt; len; k++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;APP_PRINT("%02x ", utf8[k]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;APP_PRINT("]\n");<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int byteCount = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int i = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int j = 0;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;u16 unicodeKey = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;u16 gbKey = 0;<br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//循环解析<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while (i &lt; len)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch(GetUtf8ByteNumForWord((u8)utf8[i]))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>case 0:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp[j] = utf8[i];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byteCount = 1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br></strong><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 2:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp[j] = utf8[i];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp[j + 1] = utf8[i + 1];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byteCount = 2;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>&nbsp;case 3:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//这里就开始进行UTF8-&gt;Unicode<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp[j + 1] = ((utf8[i] &amp; 0x0F) &lt;&lt; 4) | ((utf8[i + 1] &gt;&gt; 2) &amp; 0x0F);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp[j] = ((utf8[i + 1] &amp; 0x03) &lt;&lt; 6) + (utf8[i + 2] &amp; 0x3F);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //取得Unicode的值<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memcpy(&amp;unicodeKey, (temp + j), 2);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;APP_PRINT("unicode key is: 0x%04X\n", unicodeKey);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//根据这个值查表取得对应的GB2312的值<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gbKey = SearchCodeTable(unicodeKey);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;APP_PRINT("gb2312 key is: 0x%04X\n", gbKey);<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (gbKey != 0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//here change the byte<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//不为0表示搜索到，将高低两个字节调换调成我要的形式<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gbKey = (gbKey &gt;&gt; 8) | (gbKey &lt;&lt; 8);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;APP_PRINT("after changing, gb2312 key is: 0x%04X\n", gbKey);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memcpy((temp + j), &amp;gbKey, 2);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</strong></p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byteCount = 3;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br><br></strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case 4:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byteCount = 4;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case 5:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byteCount = 5;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case 6:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byteCount = 6;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;APP_PRINT("the len is more than 6\n");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i += byteCount;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (byteCount == 1)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j++;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j += 2;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;APP_PRINT("utf8: [");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (k = 0; k &lt; j; k++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;APP_PRINT("%02x ", temp[k]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;APP_PRINT("]\n");<br>}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;二、下面主要谈谈利用查表法来进行Unicode-&gt;GB2312的转换，首先下载码表，一般码表都是将GB2312的放在前面，Unicode放在后面，这样对于我们来说不方便使用，所以我转换了下，将Unicode放在前面，而且按照从小到大排好序。（这里只需要考虑都为两个字节的情况，因为前面的UTF8-&gt;Unicode并没有将单字节的ASCII转换成Unicode）<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1)做表：(可以到这里下载：<a href="http://blog.91bs.com/?action=show&amp;id=20">http://blog.91bs.com/?action=show&amp;id=20</a>，这里谢谢<a href="http://blog.91bs.com/"><u><font color=#0000ff>渣渣的猪窝</font></u></a>)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这个是原来的样子：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x8140&nbsp;0x4E02&nbsp;#CJK UNIFIED IDEOGRAPH<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x8141&nbsp;0x4E04&nbsp;#CJK UNIFIED IDEOGRAPH<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x8142&nbsp;0x4E05&nbsp;#CJK UNIFIED IDEOGRAPH<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;先弄成（这个可以写个小程序来做，我就是在VC上做的，如果需要可以联系我）：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;0x4E02&nbsp;，0x8140&nbsp;}, //CJK UNIFIED IDEOGRAPH<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;0x4E04&nbsp;，0x8141&nbsp;}, //CJK UNIFIED IDEOGRAPH<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;0x4E05&nbsp;，0x8142&nbsp;}, //CJK UNIFIED IDEOGRAPH<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这样就可以把这些放在.h文件中了，下面是我的定义：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef struct unicode_gb<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned short&nbsp;unicode;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned short gb;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} UNICODE_GB;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UNICODE_GB code_table[] =&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;0x4E02, 0x8140&nbsp;},&nbsp;&nbsp; //CJK UNIFIED IDEOGRAPH<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;0x4E04, 0x8141&nbsp;},&nbsp; //CJK UNIFIED IDEOGRAPH<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;0x4E05, 0x8142&nbsp;},&nbsp; //CJK UNIFIED IDEOGRAPH<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;。。。。。。省略<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;下面这一步也很简单，在VC中用冒泡排序法，对这个数组按照unicode值进行排序，如果需要可以联系我，把最终结果打印出来，在cmd下运行name &gt; 1.txt就输出到文件，这样就有了一个按照unicode排好序的unicode-&gt;gb2312码表。<br><br>&nbsp;&nbsp;&nbsp;int main(int argc, char *argv[])<br>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;int num = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;UNICODE_GB temp;<br>&nbsp;&nbsp;&nbsp;&nbsp;int i = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;int j = 0;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;num = sizeof(code_table) / sizeof(UNICODE_GB);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;printf("struct size: %d | total size: %d | num is: %d \n",&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;sizeof(UNICODE_GB), sizeof(code_table), num);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i &lt; num; i++)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (j = 1; j &lt; num - i; j++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (code_table[j - 1].unicode &gt; code_table[j].unicode)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp.unicode = code_table[j - 1].unicode;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp.gb = code_table[j - 1].gb;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;code_table[j - 1].unicode = code_table[j].unicode;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;code_table[j - 1].gb = code_table[j].gb;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;code_table[j].unicode = temp.unicode;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;code_table[j].gb = temp.gb;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;printf("here is the code table sorted by unicode\n\n");</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i &lt; num; i++)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("{\t0x%04X,\t0x%04X\t},\t\n", code_table[i].unicode, code_table[i].gb);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("\n\n print over!\n");<br><br>&nbsp;&nbsp;&nbsp;//以下注释掉的其实就是我用来对原来的码表添加，{，}等用的<br>&nbsp;&nbsp;&nbsp;/*<br>&nbsp;&nbsp;&nbsp;&nbsp;char buff[100];<br>&nbsp;&nbsp;&nbsp;&nbsp;char buff_1[100];&nbsp;<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;FILE* fp = NULL;<br>&nbsp;&nbsp;&nbsp;&nbsp;FILE *fp_1 = NULL;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;memset(buff, 0, 100);<br>&nbsp;&nbsp;&nbsp;&nbsp;memset(buff_1, 0, 100);<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;fp = fopen("table.txt", "rw");<br>&nbsp;&nbsp;&nbsp;&nbsp;fp_1 = fopen("table_1.txt", "a+");</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;if ((fp == NULL) || (fp_1 == NULL))<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("open file error!\n");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 1;<br>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;while (fgets(buff, 100, fp) != NULL)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buff[8] = ',';</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fputs(buff, fp_1);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;*/</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;return 0;<br>}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;最后就是搜索算法了，前面已经排好序了，现在我们把排好序的码表放在我们真正需要的.h文件中。大家应该猜我用什么算法搜索了吧，二分法。<br><br>#define CODE_TABLE_SIZE 21791<br>//这个表是死的，所以就直接用宏表示长度，不用每次都用size，不过这样可能对移植性不好。<br>u16 SearchCodeTable(u16 unicodeKey)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;int first = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;int end = CODE_TABLE_SIZE - 1;<br>&nbsp;&nbsp;&nbsp;&nbsp;int mid = 0;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;while (first &lt;= end)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mid = (first + end) / 2;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (code_table[mid].unicode == unicodeKey)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return code_table[mid].gb;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else if (code_table[mid].unicode &gt; unicodeKey)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end = mid - 1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;first = mid + 1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;return 0;<br>}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;到此，已经能够将UTF8串转换成GB2312了。是一长串哦，而不是单个汉字的编码转换。<br><br><br></p>
<img src ="http://www.cnitblog.com/wujian-IT/aggbug/37671.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/wujian-IT/" target="_blank">吴剑</a> 2007-12-13 19:21 <a href="http://www.cnitblog.com/wujian-IT/archive/2007/12/13/37671.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>终于自己伪造了一个包，且发出去了，纪录下来</title><link>http://www.cnitblog.com/wujian-IT/archive/2007/11/26/36882.html</link><dc:creator>吴剑</dc:creator><author>吴剑</author><pubDate>Mon, 26 Nov 2007 11:18:00 GMT</pubDate><guid>http://www.cnitblog.com/wujian-IT/archive/2007/11/26/36882.html</guid><wfw:comment>http://www.cnitblog.com/wujian-IT/comments/36882.html</wfw:comment><comments>http://www.cnitblog.com/wujian-IT/archive/2007/11/26/36882.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/wujian-IT/comments/commentRss/36882.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/wujian-IT/services/trackbacks/36882.html</trackback:ping><description><![CDATA[<p>#include &lt;sys/types.h&gt;<br>#include &lt;sys/socket.h&gt;<br>#include &lt;string.h&gt;<br>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;<br>#include &lt;arpa/inet.h&gt;<br>#include &lt;unistd.h&gt;<br>#include &lt;errno.h&gt;</p>
<p>#include &lt;netdb.h&gt;<br>#include &lt;netinet/in.h&gt;</p>
<p>#include "ATA_Update.h"</p>
<p>#define MY_SOCK_PORT&nbsp;2468<br>int socketId;<br>BOOL isSetServerAddr;<br>struct sockaddr sa;</p>
<p><br>int main(int argc, char *argv[])<br>{<br>&nbsp;<br>&nbsp;isSetServerAddr = FALSE;<br>&nbsp;</p>
<p>&nbsp;socketId = socket(PF_PACKET, SOCK_PACKET, htons(0x0003));<br>&nbsp;if (socketId &lt; 0)<br>&nbsp;{<br>&nbsp;&nbsp;perror ("can not get SOCK_PACKET socket");<br>&nbsp;&nbsp;return 0;<br>&nbsp;}</p>
<p>&nbsp;//struct sockaddr sa;<br>&nbsp;memset(&amp;sa, 0, sizeof(struct sockaddr));<br>&nbsp;sa.sa_family = PF_PACKET;<br>&nbsp;strcpy(sa.sa_data, "eth0");</p>
<p>&nbsp;if (bind(socketId, &amp;sa, sizeof(sa)) &lt; 0)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;perror("bind ");<br>&nbsp;&nbsp;return 0;<br>&nbsp;&nbsp;}<br>&nbsp;<br>//&nbsp;int value = 1;<br>//&nbsp;setsockopt(socketId, SOL_SOCKET, SO_BROADCAST, &amp;value, sizeof(value));</p>
<p>&nbsp;printf("send data test...\n");</p>
<p>&nbsp;while (1)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;SendData(CMD_BROADCAST, NO_NEED_ACK);<br>&nbsp;&nbsp;&nbsp;sleep(5);<br>&nbsp;&nbsp;}<br>/*<br>&nbsp;printf("send broad cast pkg...\n");<br>&nbsp;BlockWaitForUpdate();<br>&nbsp;printf("get the server addr, after BlockWaitForUpdate\n");</p>
<p>&nbsp;printf("begin to recv data......\n");<br>&nbsp;RecvData(socketId);<br>&nbsp;printf("recv data over.........\n");<br>*/<br>&nbsp;return 0;<br>&nbsp;<br>}</p>
<p>BOOL SendData(UINT8 cmdType, UINT8 ackType) <br>{<br>&nbsp;int i = 0;<br>&nbsp;int writeNum = 0;<br>&nbsp;printf("the cmd is: %d || ack type is : %d \n", cmdType, ackType);<br>&nbsp;UINT8 sendBuffer[100];<br>&nbsp;memset(sendBuffer, 0 , 100);<br>&nbsp;for (i = 0; i &lt; 100; i++)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;sendBuffer[i] = 16;<br>&nbsp;&nbsp;}</p>
<p>&nbsp;//00-16-76-A8-6E-AA<br>&nbsp;sendBuffer[0] = 0x00;<br>&nbsp;sendBuffer[1] = 0x16;<br>&nbsp;sendBuffer[2] = 0x76;<br>&nbsp;sendBuffer[3] = 0xA8;<br>&nbsp;sendBuffer[4] = 0x6E;<br>&nbsp;sendBuffer[5] = 0xAA;</p>
<p><br>&nbsp;//50:78:4C:70:92:EF<br>&nbsp;sendBuffer[6] = 0x50;<br>&nbsp;sendBuffer[7] = 0x78;<br>&nbsp;sendBuffer[8] = 0x4c;<br>&nbsp;sendBuffer[9]= 0x70;<br>&nbsp;sendBuffer[10] = 0x92;<br>&nbsp;sendBuffer[11] = 0xEF;<br>/*</p>
<p>&nbsp;for (i = 6; i &lt; 12; i++)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;sendBuffer[i] = 0x00;<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;*/<br>&nbsp;sendBuffer[12] = 0x00;<br>&nbsp;sendBuffer[13] = 0x00;</p>
<p>&nbsp;sendBuffer[14] = cmdType;<br>&nbsp;sendBuffer[15] = ackType;</p>
<p>&nbsp;memcpy(sendBuffer + 14, "ATA_UPDATE", 10);</p>
<p>&nbsp;for (i = 0; i &lt; 100; i++)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;printf(" %02x", sendBuffer[i]);<br>&nbsp;&nbsp;}</p>
<p>&nbsp;writeNum = sendto(socketId, sendBuffer, 100, 0, &amp;sa, sizeof sa);<br>&nbsp;printf("&nbsp;&nbsp;&nbsp; ==&nbsp;&nbsp;&nbsp; write %d \n", writeNum);<br>&nbsp;if (writeNum == -1)<br>&nbsp;&nbsp;perror("sendto");<br>&nbsp;<br>&nbsp;return TRUE;<br>}</p>
<p>/*<br>BOOL BlockWaitForUpdate()<br>{<br>&nbsp;fd_set readFd;<br>&nbsp;struct timeval tv;<br>&nbsp;int ret;<br>&nbsp;<br>&nbsp;SendData(CMD_BROADCAST, NO_NEED_ACK);<br>&nbsp;<br>&nbsp;while(1)<br>&nbsp;{<br>&nbsp;&nbsp;tv.tv_sec = 5;<br>&nbsp;&nbsp;tv.tv_usec = 0;<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;FD_ZERO(&amp;readFd);<br>&nbsp;&nbsp;FD_SET(socketId, &amp;readFd);</p>
<p>&nbsp;&nbsp;ret = select(socketId + 1, &amp;readFd, NULL, NULL, &amp;tv);</p>
<p>&nbsp;&nbsp;switch(ret)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;case -1:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;break;</p>
<p>&nbsp;&nbsp;&nbsp;case 0:<br>&nbsp;&nbsp;&nbsp;&nbsp;printf("resend data\n");<br>&nbsp;&nbsp;&nbsp;&nbsp;SendData(CMD_BROADCAST, NO_NEED_ACK);<br>&nbsp;&nbsp;&nbsp;&nbsp;break;</p>
<p>&nbsp;&nbsp;&nbsp;default:<br>&nbsp;&nbsp;&nbsp;&nbsp;if (FD_ISSET(socketId, &amp;readFd))<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("here come pkg\n");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (isRightPkg(socketId, CMD_UPDATE))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return TRUE;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}<br>&nbsp;}<br>}</p>
<p>//这里还可以进行一些字符内容的设定，增加安全性<br>BOOL isRightData(char *recvBuff, UINT8 cmdType)<br>{<br>&nbsp;if (recvBuff == NULL)<br>&nbsp;&nbsp;return FALSE;</p>
<p>&nbsp;if (recvBuff[0] == cmdType)<br>&nbsp;&nbsp;return TRUE;</p>
<p>&nbsp;return FALSE;<br>}</p>
<p>BOOL isRightPkg(int sockfd, UINT8 cmdType)<br>{<br>&nbsp;int recvNum;<br>&nbsp;char recvBuff[1024];<br>&nbsp;struct sockaddr_in addr;</p>
<p>&nbsp;int addrLen = sizeof(struct sockaddr_in);<br>&nbsp;memset(&amp;addr, 0, sizeof(addr));<br>&nbsp;recvNum = recvfrom(sockfd, recvBuff, sizeof(recvBuff),<br>&nbsp;&nbsp;0, (struct sockaddr*)&amp;addr, &amp;addrLen);</p>
<p>&nbsp;if (recvNum &lt; 0)<br>&nbsp;{<br>&nbsp;&nbsp;return FALSE;<br>&nbsp;}</p>
<p>&nbsp;recvBuff[recvNum] = 0;<br>&nbsp;printf("receive from [%s] : %s\n", inet_ntoa(addr.sin_addr), recvBuff);</p>
<p>&nbsp;if (!isSetServerAddr)<br>&nbsp;{<br>&nbsp;&nbsp;if ((cmdType == CMD_UPDATE) <br>&nbsp;&nbsp;&nbsp;&amp;&amp;( isRightData(recvBuff, CMD_UPDATE)))<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;isSetServerAddr = TRUE;<br>&nbsp;&nbsp;&nbsp;serverAddress = addr;<br>&nbsp;&nbsp;&nbsp;printf("address is set: %s\n", inet_ntoa(serverAddress.sin_addr));</p>
<p>&nbsp;&nbsp;&nbsp;SendData(CMD_ACK, ACK_FOR_UPDATE);</p>
<p>&nbsp;&nbsp;&nbsp;printf("\n\n---after here begin to data transfer........\n");<br>&nbsp;&nbsp;&nbsp;return TRUE;<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;return FALSE;<br>&nbsp;}<br>&nbsp;else<br>&nbsp;{<br>&nbsp;&nbsp;if ((addr.sin_addr.s_addr == serverAddress.sin_addr.s_addr)<br>&nbsp;&nbsp;&nbsp;&amp;&amp; (isRightData(recvBuff, cmdType)))<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;return TRUE;<br>&nbsp;&nbsp;}<br>&nbsp;}</p>
<p>&nbsp;return FALSE;<br>}</p>
<p>void RecvData(int sockfd)<br>{<br>&nbsp;int recvNum;<br>&nbsp;char recvBuff[1024];<br>&nbsp;struct sockaddr_in addr;</p>
<p>&nbsp;int addrLen = sizeof(struct sockaddr_in);<br>&nbsp;memset(&amp;addr, 0, sizeof(addr));</p>
<p>&nbsp;while (1)<br>&nbsp;{<br>&nbsp;&nbsp;recvNum = recvfrom(sockfd, recvBuff, sizeof(recvBuff),<br>&nbsp;&nbsp;&nbsp;0, (struct sockaddr*)&amp;addr, &amp;addrLen);</p>
<p>&nbsp;&nbsp;if (recvNum &lt; 0)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;printf("error with recv data\n");<br>&nbsp;&nbsp;&nbsp;continue;<br>&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;recvBuff[recvNum] = 0;<br>&nbsp;&nbsp;PrintPkgAndAddr(PKG_RECV, addr, recvBuff, recvNum);</p>
<p>&nbsp;&nbsp;//here process the pkg<br>&nbsp;&nbsp;//PutDataInPkg();<br>&nbsp;&nbsp;//CheckRecvPkg();</p>
<p>&nbsp;&nbsp;//send ack back<br>&nbsp;&nbsp;if (recvBuff[0] == CMD_DATA)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;SendData(CMD_ACK, ACK_FOR_DATA);<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;else<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;<br>&nbsp;}<br>&nbsp;<br>}</p>
<p>void PrintPkgAndAddr(PKG_TYPE type, struct sockaddr_in addr, char *buff, int len)<br>{<br>&nbsp;int i;<br>&nbsp;<br>&nbsp;if (type == PKG_SEND)<br>&nbsp;{<br>&nbsp;&nbsp;printf("\nsend [%d bytes] to [%s] : ", len, inet_ntoa(addr.sin_addr));<br>&nbsp;}<br>&nbsp;else if (type == PKG_RECV)<br>&nbsp;{<br>&nbsp;&nbsp;printf("\nrecv [%d bytes] from [%s] : ", len, inet_ntoa(addr.sin_addr));<br>&nbsp;}</p>
<p>&nbsp;for (i = 0; i &lt; len; i++)<br>&nbsp;{<br>&nbsp;&nbsp;printf(" %02x ", (unsigned char)buff[i]);<br>&nbsp;}</p>
<p>&nbsp;printf("\n");<br>&nbsp;<br>}</p>
<p>void PutDataInPkg(char *buff)<br>{<br>}</p>
<p>BOOL CheckRecvPkg(APP_PKG *pkg)<br>{<br>}<br>*/<br></p>
<img src ="http://www.cnitblog.com/wujian-IT/aggbug/36882.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/wujian-IT/" target="_blank">吴剑</a> 2007-11-26 19:18 <a href="http://www.cnitblog.com/wujian-IT/archive/2007/11/26/36882.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>预编译指令的作用</title><link>http://www.cnitblog.com/wujian-IT/archive/2007/11/11/36148.html</link><dc:creator>吴剑</dc:creator><author>吴剑</author><pubDate>Sun, 11 Nov 2007 14:20:00 GMT</pubDate><guid>http://www.cnitblog.com/wujian-IT/archive/2007/11/11/36148.html</guid><wfw:comment>http://www.cnitblog.com/wujian-IT/comments/36148.html</wfw:comment><comments>http://www.cnitblog.com/wujian-IT/archive/2007/11/11/36148.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/wujian-IT/comments/commentRss/36148.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/wujian-IT/services/trackbacks/36148.html</trackback:ping><description><![CDATA[预编译一般用来防止头文件的重复包含和编译。<br><br>在我们用C做开发的是候，有时候项目很大，我们所编写的程序会很长。这样我们如果还是写在一个文件中会出现管理上的问题和&nbsp;<br>查看上的不方便。因此，我们可以分多个文件编写我们的程序，这样把一个功能的程序写到一个文件里，便于查看&nbsp;也有助于我们管理。&nbsp;<br>如main.c&nbsp;sd.h&nbsp;sd.c&nbsp;lcd.h&nbsp;lcd.c&nbsp;fat.h&nbsp;fat.c&nbsp;delay.h&nbsp;delay.c&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;至于头文件(sd.h)和源文件(sd.c)的写法应该是这样的：&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在头文件中&nbsp;我们写的是&nbsp;函数的声明，和一些使用到的变量的声明；&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在源文件中&nbsp;我们写的是&nbsp;对应于头文件中的函数的具体实现，即函数左大括号和右大括号中的内容。&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;在具体使用相关函数是可以使用#include&nbsp;命令来包含其函数所在的头文件。下面我们虚拟如下的一个程序结构来展开说明：&nbsp;<br><br>如在main.c中&nbsp;<br>#include&nbsp;delay.h&nbsp;<br>#include&nbsp;sd.h&nbsp;<br>#include&nbsp;lcd.h&nbsp;<br>#include&nbsp;fat.h&nbsp;<br>main()&nbsp;<br>{&nbsp;<br>&nbsp;&nbsp;sd_init();&nbsp;<br>&nbsp;&nbsp;delay_nms(10);&nbsp;<br>&nbsp;&nbsp;lcd_init();&nbsp;<br>&nbsp;&nbsp;while(1)&nbsp;<br>&nbsp;&nbsp;{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;....&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;....;&nbsp;<br>&nbsp;&nbsp;}&nbsp;<br>}&nbsp;<br><br>在sd.c中&nbsp;<br>void&nbsp;sd_init()&nbsp;<br>{&nbsp;<br>&nbsp;......&nbsp;<br>&nbsp;......;&nbsp;&nbsp;<br>}&nbsp;<br><br>在sd.h中&nbsp;<br>#include&nbsp;delay.h&nbsp;<br>#include&nbsp;.......&nbsp;<br>void&nbsp;sd_init()；&nbsp;<br>.....&nbsp;<br><br>在delay.c中&nbsp;<br>void&nbsp;delay_nms(UINT&nbsp;n)&nbsp;<br>{&nbsp;<br>&nbsp;for(....)&nbsp;<br>&nbsp;&nbsp;{...&nbsp;<br>&nbsp;&nbsp;&nbsp;_asm_("nop");&nbsp;<br>&nbsp;&nbsp;&nbsp;...&nbsp;<br>&nbsp;&nbsp;}&nbsp;&nbsp;<br><br>}&nbsp;<br>在delay.h中&nbsp;<br>void&nbsp;delay_nms(UINT&nbsp;n);&nbsp;<br><br>.....&nbsp;<br><br>&nbsp;&nbsp;&nbsp;我们看，如果在头文件的书写中都没加预编译指令&nbsp;<br>#ifndef&nbsp;XXXXXXXX&nbsp;&nbsp;<br>#define&nbsp;XXXXXXXX&nbsp;<br>&nbsp;&nbsp;....&nbsp;<br>&nbsp;&nbsp;....&nbsp;<br>&nbsp;&nbsp;（头文件内容）&nbsp;<br>&nbsp;&nbsp;....&nbsp;<br>#endif&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br><br>会出现怎么样的情况？？？？&nbsp;&nbsp;&nbsp;&nbsp;其实这样，编译会报错。编译器会提示&nbsp;void&nbsp;delay_nms()定义了两次。为什么会出现这种情况呢？&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;我们顺着程序读一下，当我们在main.c中，编译器读到#include&nbsp;delay.h时会把&nbsp;delay.h文件中的内容包含进来，这样delay.h中的&nbsp;<br>delay_nms()函数定义了一次，当我们在往下，读到#include&nbsp;sd.h时，把sd.h包含进来，在把sd.h的内容展开，我们又读到了一次delay.h&nbsp;<br>这样又把delay.h的内容包含近了main.c&nbsp;。因此，我们发现delay.h被main.c重复包含了2次。这样使得void&nbsp;delay_nms()函数也被定义了二次。&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;如何解决重复定义的问题，我们是用条件编译，#ifndef&nbsp;..等。在头文件中加入条件编译指令，如下：&nbsp;<br><br>在sd.h中&nbsp;<br>#ifndef&nbsp;_SD_H_&nbsp;&nbsp;<br>#define&nbsp;_SD_H_&nbsp;<br><br>#include&nbsp;delay.h&nbsp;<br>#include&nbsp;.......&nbsp;<br>void&nbsp;sd_init()；&nbsp;<br>.....&nbsp;<br><br>#endif&nbsp;<br><br>在delay.h中&nbsp;<br>#ifndef&nbsp;_DELAY_H_&nbsp;&nbsp;<br>#define&nbsp;_DELAY_H_&nbsp;<br><br>void&nbsp;delay_nms(UINT&nbsp;n);&nbsp;<br><br>.....&nbsp;<br>#endif&nbsp;<br><br>&nbsp;&nbsp;&nbsp;这样，让我们再看下会出现什么情况。&nbsp;<br>&nbsp;&nbsp;&nbsp;当我们在main.c中，编译器读到#include&nbsp;delay.h时会把&nbsp;delay.h文件中的内容包含进来，（#ifndef&nbsp;_DELAY_H_）我们先判断有没有定义&nbsp;<br>了&nbsp;_DELAY_H_&nbsp;&nbsp;这个宏，由于这是第一次调用delay.h，_DELAY_H_这个宏还没定义，这样编译器会顺序向下执行，执行到#define&nbsp;_DELAY_H_&nbsp;<br>则定义了一个_DELAY_H_宏，宏值为NULL.&nbsp;当我们main.c中再往下，读到#include&nbsp;sd.h时，把sd.h包含进来，在把sd.h的内容展开，&nbsp;<br>我们又读到了一次delay.h。&nbsp;这一次&nbsp;我们判断&nbsp;#ifndef&nbsp;_DELAY_H_&nbsp;结果是已经定义了，这样，编译器会跳过下面的内容，直接到&nbsp;#endif。&nbsp;<br>可见，我们的函数&nbsp;void&nbsp;delay_nms(UINT&nbsp;n);&nbsp;就不会被重复定义二次！&nbsp;对于其他的头文件，我们现在也加上&nbsp;预编译指令，防止被重复包含。&nbsp;<br><br>&nbsp;&nbsp;另外，在WinAVR中，如果使用多文件编译，需要在Makeflie中修改&nbsp;SRC&nbsp;=&nbsp;$(TARGET).c&nbsp;在其后面添加你的头文件的源文件的名字。如&nbsp;<br>&nbsp;&nbsp;SRC&nbsp;=&nbsp;$(TARGET).c&nbsp;delay.c&nbsp;sd.c&nbsp;fat.c&nbsp;lcd.h&nbsp;<br><br><br><br><br>希望以上内容能对初学者有所帮助，有什么不对的地方也恳请大家指出修正。
<br><img src ="http://www.cnitblog.com/wujian-IT/aggbug/36148.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/wujian-IT/" target="_blank">吴剑</a> 2007-11-11 22:20 <a href="http://www.cnitblog.com/wujian-IT/archive/2007/11/11/36148.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>_init宏</title><link>http://www.cnitblog.com/wujian-IT/archive/2007/11/06/35950.html</link><dc:creator>吴剑</dc:creator><author>吴剑</author><pubDate>Tue, 06 Nov 2007 10:36:00 GMT</pubDate><guid>http://www.cnitblog.com/wujian-IT/archive/2007/11/06/35950.html</guid><wfw:comment>http://www.cnitblog.com/wujian-IT/comments/35950.html</wfw:comment><comments>http://www.cnitblog.com/wujian-IT/archive/2007/11/06/35950.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/wujian-IT/comments/commentRss/35950.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/wujian-IT/services/trackbacks/35950.html</trackback:ping><description><![CDATA[<div class=t_msgfont id=message5229490>_init关键字不是gcc的， 而是linux内核的。&nbsp;&nbsp;__init， __initdata等属性标志， 是要把这种属性的代码放入目标文件的.init.text节， 数据放入.init.data节──这一过程是通过编译内核时为相关目标平台提供了xxx.lds链接脚本， 来指导ld完成的。 对i386来说， 可以参考arch/i386/kernel/vmlinux.lds.S文件。<br><br>对编译成module的代码和数据来说， 当模块加载时， __init属性的函数就被执行;<br>对静态编入内核的代码和数据来说， 当内核引导时， do_basic_setup()函数调用do_initcalls()函数， 后者负责所有.init节函数的执行。<br><br>
<div class=t_msgfont id=message5230488>__init说明这个函数仅在初始化的时候使用,在模块挂载以后,就会把初始化函数扔掉,可以把该函数占用的内存扔掉,</div>
<br></div>
<img src ="http://www.cnitblog.com/wujian-IT/aggbug/35950.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/wujian-IT/" target="_blank">吴剑</a> 2007-11-06 18:36 <a href="http://www.cnitblog.com/wujian-IT/archive/2007/11/06/35950.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>并发性单线程服务器</title><link>http://www.cnitblog.com/wujian-IT/archive/2007/11/05/35910.html</link><dc:creator>吴剑</dc:creator><author>吴剑</author><pubDate>Mon, 05 Nov 2007 14:10:00 GMT</pubDate><guid>http://www.cnitblog.com/wujian-IT/archive/2007/11/05/35910.html</guid><wfw:comment>http://www.cnitblog.com/wujian-IT/comments/35910.html</wfw:comment><comments>http://www.cnitblog.com/wujian-IT/archive/2007/11/05/35910.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/wujian-IT/comments/commentRss/35910.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/wujian-IT/services/trackbacks/35910.html</trackback:ping><description><![CDATA[// File: prg6_9.c<br>&nbsp;&nbsp; &nbsp;#include &lt;stdio.h&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* These are the usual header files */ <br>&nbsp;&nbsp; &nbsp;#include &lt;strings.h&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* for bzero() */<br>&nbsp;&nbsp; &nbsp;#include &lt;unistd.h&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* for close() */<br>&nbsp;&nbsp; &nbsp;#include &lt;sys/types.h&gt; <br>&nbsp;&nbsp; &nbsp;#include &lt;sys/socket.h&gt; <br>&nbsp;&nbsp; &nbsp;#include &lt;netinet/in.h&gt; <br>&nbsp;&nbsp; &nbsp;#include &lt;arpa/inet.h&gt;<br>&nbsp;&nbsp; &nbsp;#include &lt;sys/time.h&gt;<br>&nbsp;&nbsp; &nbsp;#include &lt;stdlib.h&gt;<br><br>&nbsp;&nbsp; &nbsp;#define PORT 1234&nbsp;&nbsp; /* Port that will be opened */ <br>&nbsp;&nbsp; &nbsp;#define BACKLOG 5&nbsp;&nbsp; /* Number of allowed connections */ <br>&nbsp;&nbsp; &nbsp;#define MAXDATASIZE 1000 <br>&nbsp;&nbsp; &nbsp;typedef struct CLIENT{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; &nbsp; fd;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; char*&nbsp; name;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; struct sockaddr_in addr; /* client's address information */<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; char* data;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp; &nbsp;}; &nbsp;<br>&nbsp;&nbsp; &nbsp;void process_cli(CLIENT *client, char* recvbuf, int len);<br>&nbsp;&nbsp; &nbsp;void savedata(char* recvbuf, int len, char* data);<br><br>&nbsp;&nbsp; &nbsp;main() <br>&nbsp;&nbsp; &nbsp;{ <br>&nbsp;&nbsp; &nbsp;int&nbsp;&nbsp; &nbsp;i, maxi, maxfd,sockfd;<br>&nbsp;&nbsp; &nbsp;int&nbsp;&nbsp; &nbsp;nready;<br>&nbsp;&nbsp; &nbsp;ssize_t&nbsp;&nbsp; &nbsp;n;<br>&nbsp;&nbsp; &nbsp;fd_set&nbsp;&nbsp; &nbsp;rset, allset;<br>&nbsp;&nbsp; &nbsp;int listenfd, connectfd; /* socket descriptors */&nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp; &nbsp;struct sockaddr_in server; /* server's address information */ <br>&nbsp;&nbsp; &nbsp;/* client's information */ <br>&nbsp;&nbsp; &nbsp;CLIENT client[FD_SETSIZE];<br>&nbsp;&nbsp; &nbsp;char recvbuf[MAXDATASIZE];<br>&nbsp;&nbsp; &nbsp;int sin_size; <br><br>&nbsp;&nbsp; &nbsp;/* Create TCP socket&nbsp; */<br>&nbsp;&nbsp; &nbsp;if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* handle exception */<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; perror("Creating socket failed.");<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; exit(1);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp; &nbsp;int opt = SO_REUSEADDR;<br>&nbsp;&nbsp; &nbsp;setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &amp;opt, sizeof(opt));<br><br>&nbsp;&nbsp; &nbsp;bzero(&amp;server,sizeof(server));<br>&nbsp;&nbsp; &nbsp;server.sin_family=AF_INET; <br>&nbsp;&nbsp; &nbsp;server.sin_port=htons(PORT); <br>&nbsp;&nbsp; &nbsp;server.sin_addr.s_addr = htonl (INADDR_ANY); <br>&nbsp;&nbsp; &nbsp;if (bind(listenfd, (struct sockaddr *)&amp;server, sizeof(struct sockaddr)) == -1) { <br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* handle exception */<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; perror("Bind error.");<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; exit(1); <br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; &nbsp;<br><br>&nbsp;&nbsp; &nbsp;if(listen(listenfd,BACKLOG) == -1){&nbsp; /* calls listen() */ <br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; perror("listen() error\n"); <br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; exit(1); <br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } <br><br>&nbsp;&nbsp; &nbsp;sin_size=sizeof(struct sockaddr_in); <br>&nbsp;&nbsp; &nbsp;/*initialize for select */<br>&nbsp;&nbsp; &nbsp;maxfd = listenfd;&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp; &nbsp;maxi = -1;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp; &nbsp;for (i = 0; i &lt; FD_SETSIZE; i++) {<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; client[i].fd = -1;&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp; &nbsp;FD_ZERO(&amp;allset);<br>&nbsp;&nbsp; &nbsp;FD_SET(listenfd, &amp;allset);<br><br>&nbsp;&nbsp; &nbsp;while(1)<br>&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;struct sockaddr_in addr;<br>&nbsp;&nbsp; &nbsp;rset = allset;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp; &nbsp;nready = select(maxfd+1, &amp;rset, NULL, NULL, NULL);<br><br>&nbsp;&nbsp; &nbsp;if (FD_ISSET(listenfd, &amp;rset)) {&nbsp;&nbsp; &nbsp;/* new client connection */<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Accept connection */<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if ((connectfd = accept(listenfd,(struct sockaddr *)&amp;addr,&amp;sin_size))==-1) {<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; perror("accept() error\n"); <br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue; <br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Put new fd to client */<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for (i = 0; i &lt; FD_SETSIZE; i++)<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (client[i].fd &lt; 0) {<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; client[i].fd = connectfd;&nbsp;&nbsp; &nbsp;/* save descriptor */<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; client[i].name = new char[MAXDATASIZE];<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; client[i].addr = addr;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; client[i].data = new char[MAXDATASIZE];<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; client[i].name[0] = '\0';<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; client[i].data[0] = '\0';<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("You got a connection from %s.&nbsp; ",inet_ntoa(client[i].addr.sin_addr) ); <br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (i == FD_SETSIZE)&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; printf("too many clients\n");<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FD_SET(connectfd, &amp;allset);&nbsp;&nbsp; &nbsp;/* add new descriptor to set */<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (connectfd &gt; maxfd)&nbsp; maxfd = connectfd;&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (i &gt; maxi)&nbsp;&nbsp; &nbsp;maxi = i;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (--nready &lt;= 0) continue;&nbsp;&nbsp; &nbsp;/* no more readable descriptors */<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for (i = 0; i &lt;= maxi; i++) {&nbsp;&nbsp; &nbsp;/* check all clients for data */<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( (sockfd = client[i].fd) &lt; 0)&nbsp;&nbsp; &nbsp;continue;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (FD_ISSET(sockfd, &amp;rset)) {<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( (n = recv(sockfd, recvbuf, MAXDATASIZE,0)) == 0) {<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*connection closed by client */<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; close(sockfd);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Client( %s ) closed connection. User's data: %s\n",client[i].name,client[i].data);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FD_CLR(sockfd, &amp;allset);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; client[i].fd = -1;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete client[i].name;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete client[i].data;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; process_cli(&amp;client[i], recvbuf, n);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (--nready &lt;= 0)&nbsp;&nbsp; &nbsp;break;&nbsp;&nbsp; &nbsp;/* no more readable descriptors */<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp; &nbsp;close(listenfd);&nbsp;&nbsp; /* close listenfd */&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp; &nbsp;} <br><br>&nbsp;&nbsp; &nbsp;void process_cli(CLIENT *client, char* recvbuf, int len)<br>&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;char sendbuf[MAXDATASIZE];<br><br>&nbsp;&nbsp; &nbsp;recvbuf[len-1] = '\0';<br>&nbsp;&nbsp; &nbsp;if (strlen(client-&gt;name) == 0) {<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Got client's name from client */<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; memcpy(client-&gt;name,recvbuf, len);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf("Client's name is %s.\n",client-&gt;name);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp; &nbsp;/* save client's data */<br>&nbsp;&nbsp; &nbsp;printf("Received client( %s ) message: %s\n",client-&gt;name, recvbuf);<br>&nbsp;&nbsp; &nbsp;/* save user's data */<br>&nbsp;&nbsp; &nbsp;savedata(recvbuf,len, client-&gt;data);<br>&nbsp;&nbsp; &nbsp;/* reverse usr's data */<br>&nbsp;&nbsp; &nbsp;for (int i1 = 0; i1 &lt; len - 1; i1++) {<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sendbuf[i1] = recvbuf[len - i1 -2];<br>&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp; &nbsp;sendbuf[len - 1] = '\0';<br><br>&nbsp;&nbsp; &nbsp;send(client-&gt;fd,sendbuf,strlen(sendbuf),0); <br>&nbsp;&nbsp; &nbsp;}<br><br>&nbsp;&nbsp; &nbsp;void savedata(char* recvbuf, int len, char* data)<br>&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;int start = strlen(data);<br>&nbsp;&nbsp; &nbsp;for (int i = 0; i &lt; len; i++) {<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; data[start + i] = recvbuf[i];<br>&nbsp;&nbsp; &nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp; &nbsp;}<br><br><br>
<br><img src ="http://www.cnitblog.com/wujian-IT/aggbug/35910.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/wujian-IT/" target="_blank">吴剑</a> 2007-11-05 22:10 <a href="http://www.cnitblog.com/wujian-IT/archive/2007/11/05/35910.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>TCP/IP学习笔记1，2，3章（协议篇）</title><link>http://www.cnitblog.com/wujian-IT/archive/2007/10/25/35342.html</link><dc:creator>吴剑</dc:creator><author>吴剑</author><pubDate>Thu, 25 Oct 2007 11:43:00 GMT</pubDate><guid>http://www.cnitblog.com/wujian-IT/archive/2007/10/25/35342.html</guid><wfw:comment>http://www.cnitblog.com/wujian-IT/comments/35342.html</wfw:comment><comments>http://www.cnitblog.com/wujian-IT/archive/2007/10/25/35342.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/wujian-IT/comments/commentRss/35342.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/wujian-IT/services/trackbacks/35342.html</trackback:ping><description><![CDATA[<p class=MsoNormal style="MARGIN: 0in 0in 0pt">1<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、概述</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">1) <span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">链路层，有时也称作数据链路层或网络接口层，</span>(<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">硬件接口，</span>ARP,RARP)</p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">2) <span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">网络层，有时也称作互联网层，</span>(IP, ICMP, IGMP)I C M P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">协议的附属协议</span>,I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">层用它来与其他主机或路由器交换错误报文和其他重要信息。</span>P i n g<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span>Tr a c e r o u t e<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">它们都使用了</span>I C M P</p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">3) <span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">运输层主要为两台主机上的应用程序提供端到端的通信。</span>(TCP, UDP)</p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">4) <span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">应用层负责处理特定的应用程序细节。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">&nbsp;<o:p></o:p></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一个互连网就是一组通过相同协议族互连在一起的网络。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">&nbsp;<o:p></o:p></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">构造互连网最简单的方法是把两个或多个网络通过路由器进行连接。它是一种特殊的用</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">于网络互连的硬件盒。路由器的好处是为不同类型的物理网络提供连接：以太网、令牌环网、</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">点对点的链接和</span>F D D I<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（光纤分布式数据接口）等等。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">&nbsp;<o:p></o:p></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">连接网络的另一个途径是使用网桥。网桥是在链路层上对网络进行互连，而路由器则是</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在网络层上对网络进行互连。网桥使得多个局域网（</span> L A N<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）组合在一起，这样对上层来说就好像是一个局域网。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><v:shapetype id=_x0000_t75 stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></v:path><o:lock aspectratio="t" v:ext="edit"></o:lock></v:shapetype><v:shape id=_x0000_i1025 style="WIDTH: 353.25pt; HEIGHT: 198pt" type="#_x0000_t75"><v:imagedata o:title="" src="file:///C:/DOCUME~1/WU93D5~1.JIA/LOCALS~1/Temp/msoclip1/01/clip_image001.png"></v:imagedata></v:shape></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><v:shape id=_x0000_i1026 style="WIDTH: 192.75pt; HEIGHT: 123.75pt" type="#_x0000_t75"><v:imagedata o:title="" src="file:///C:/DOCUME~1/WU93D5~1.JIA/LOCALS~1/Temp/msoclip1/01/clip_image003.png"></v:imagedata></v:shape></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">有三类</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址：单播地址（目的为单个主机）、广播地址（目的端为给定网络上的所有主</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">机）以及多播地址（目的端为同一组内的所有主机）。在</span>T C P / I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">领域中，域名系统（</span>D N S<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）是一个分布的数据库，由它来提供</span> I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址和主机名之间的映射信息。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">T C P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">传给</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的数据单元称作</span> T C P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">报文段或简称为</span>T C P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">段（</span>T C P</p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">s e g m e n t<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）。</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">传给网络接口层的数据单元称作</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据报</span>(IP datagram)<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。通过以太网传输的比特流称作帧</span>(Fr a m e )<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><v:shape id=_x0000_i1027 style="WIDTH: 414.75pt; HEIGHT: 303pt" type="#_x0000_t75"><v:imagedata o:title="" src="file:///C:/DOCUME~1/WU93D5~1.JIA/LOCALS~1/Temp/msoclip1/01/clip_image005.png"></v:imagedata></v:shape></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">由于</span>T C P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span>U D P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span>I C M P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span>I G M P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">都要向</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">传送数据，因此</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">必须在</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">生成的</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">首部中加入某种标识，以表明数据属于哪一层。为此，</span> I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在首部中存入一个长度为</span>8 b i t<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的数值，称作协议域。</span>1<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表示为</span>I C M P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">协议，</span>2<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表示为</span>I G M P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">协议，</span>6<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表示为</span>T C P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">协议，</span>1 7<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表示为</span>U D P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">协议。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类似地，许多应用程序都可以使用</span> T C P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</span>U D P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来传送数据。运输层协议在生成报文首部时要存入一个应用程序的标识符。</span> T C P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span>U D P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">都用一个</span>1 6 b i t<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的端口号来表示不同的应用程序。</span>T C P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span>U D P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">把源端口号和目的端口号分别存入报文首部中。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">网络接口分别要发送和接收</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span>A R P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span>R A R P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据，因此也必须在以太网的帧首部中加入某种形式的标识，以指明生成数据的网络层协议。为此，以太网的帧首部也有一个</span> 16 bit<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的帧类型域。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><v:shape id=_x0000_i1028 style="WIDTH: 414.75pt; HEIGHT: 264pt" type="#_x0000_t75"><v:imagedata o:title="" src="file:///C:/DOCUME~1/WU93D5~1.JIA/LOCALS~1/Temp/msoclip1/01/clip_image007.png"></v:imagedata></v:shape></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为协议</span>I C M P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span>I G M P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">定位一直是一件很棘手的事情。在图</span>1 - 4<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中，把它们与</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">放在</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">同一层上，那是因为事实上它们是</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的附属协议。但是在这里，我们又把它们放在</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">层</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的上面，这是因为</span>ICMP<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span>IGMP<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">报文都被封装在</span>IP<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据报中。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对于</span>A R P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span>R A R P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，我们也遇到类似的难题。在这里把它们放在以太网设备驱动程</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">序的上方，这是因为它们和</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据报一样，都有各自的以太网数据帧类型。但在图</span>2 - 4</p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中，我们又把</span>A R P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">作为以太网设备驱动程序的一部分，放在</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">层的下面，其原因在逻</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">辑上是合理的。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">&nbsp;<o:p></o:p></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">2<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、链路层</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span>T C P / I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">协议族中，链路层主要有三个目的：（</span>1<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）为</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模块发送和接收</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据报；（</span>2<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）为</span>A R P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模块发送</span>A R P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">请求和接收</span>A R P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">应答；（</span>3<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）为</span>R A R P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">发送</span>R A R P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">请求和接收</span>R A R P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">应答。</span>T C P / I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">支持多种不同的链路层协议，这取决于网络所使用的硬件，如以太网、令牌环网、</span>F D D I<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（光纤分布式数据接口）及</span>R S-2 3 2<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">串行线路等。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">以太网和</span>IEEE 802<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">封装：</span><span lang=ZH-CN> </span><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当今</span> T C P / I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">采用的主要的局域网技术。它采用一种称作</span> C S M A / C D<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的媒体接入方法，其意思是带冲突检测的载波侦听多路接入（</span>Carrier Sense, Multiple Access with Collision Detection<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）。它的速率为</span>10 Mb/s<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，地址为</span>48 bit<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span>I E E E<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（电子电气工程师协会）</span> 8 0 2<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">委员会公布了一个稍有不同的标准集。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">S L I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的全称是</span>Serial Line IP<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。它是一种在串行线路上对</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据报进行封装的简单形式</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">P P P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，点对点协议修改了</span>S L I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">协议中的所有缺陷。</span>P P P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">包括以下三个部分：</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">1) <span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在串行链路上封装</span> I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据报的方法。</span> P P P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">既支持数据为</span>8<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">位和无奇偶检验的异步模式大多数计算机上都普遍存在的串行接口），还支持面向比特的同步链接。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">2) <span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">建立、配置及测试数据链路的链路控制协议（</span> L C P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：</span>Link Control Protocol<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）。它允许通</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方进行协商，以确定不同的选项。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">3) <span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">针对不同网络层协议的网络控制协议（</span> N C P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：</span>Network Control Protocol<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）体系。当前定义的网络层有</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span>O S I<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">网络层、</span>D E C n e t<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">以及</span>A p p l e Ta l k<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。例如，</span>IP NCP<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">允许双方商定是报文首部进行压缩，类似于</span>C S L I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（缩写词</span>N C P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">也可用在</span>T C P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的前面）。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><v:shape id=_x0000_i1029 style="WIDTH: 414.75pt; HEIGHT: 373.5pt" type="#_x0000_t75"><v:imagedata o:title="" src="file:///C:/DOCUME~1/WU93D5~1.JIA/LOCALS~1/Temp/msoclip1/01/clip_image009.png"></v:imagedata></v:shape></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">&nbsp;<o:p></o:p></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><v:shape id=_x0000_i1030 style="WIDTH: 387pt; HEIGHT: 203.25pt" type="#_x0000_t75"><v:imagedata o:title="" src="file:///C:/DOCUME~1/WU93D5~1.JIA/LOCALS~1/Temp/msoclip1/01/clip_image011.png"></v:imagedata></v:shape></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">大多数的产品都支持环回接口（</span>Loopback Interface<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">），以允许运行在同一台主机上的客户</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">程序和服务器程序通过</span> T C P / I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">进行通信。一旦传输层检测到目的端地址是环回地址时，应该可以省略部分传输层和所有网络层的逻辑操作。但是大多数的产品还是照样完成传输层和网络层的所有过程，只是当</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据报离开网络层时把它返回给自己。正因为不经过链路层，所以这种数据包不会出现在网络上。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">以太网和</span>8 0 2 . 3<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对数据帧的长度都有一个限制，其最大值分别是</span>1 5 0 0<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span>1 4 9 2<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">字节。链路层的这个特性称作</span>MTU<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">字节网络</span>M T U<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，最大传输单元。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">T C P / I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">成功的原因之一是它几乎能在任何数据链路技术上运行。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">&nbsp;<o:p></o:p></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">3<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是</span>T C P / I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">协议族中最为核心的协议。所有的</span>T C P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span>U D P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span>I C M P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">及</span>I G M P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据都以</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据报格式传输。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不可靠（</span>u n r e l i a b l e<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）的意思是它不能保证</span> I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据报能成功地到达目的地。</span> I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">仅提供最好的传输服务。如果发生某种错误时，如某个路由器暂时用完了缓冲区，</span> I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">有一个简单的错误处理算法：丢弃该数据报，然后发送</span> I C M P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">消息报给信源端。任何要求的可靠性必须由上层来提供（如</span>T C P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">无连接（</span>c o n n e c t i o n l e s s<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）这个术语的意思是</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">并不维护任何关于后续数据报的状态信息。每个数据报的处理是相互独立的。这也说明，</span> I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据报可以不按发送顺序接收。如果一信源向相同的信宿发送两个连续的数据报（先是</span> A<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，然后是</span>B<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">），每个数据报都是独立地进行路由选择，可能选择不同的路线，因此</span>B<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可能在</span>A<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">到达之前先到达。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><v:shape id=_x0000_i1031 style="WIDTH: 393pt; HEIGHT: 281.25pt" type="#_x0000_t75"><v:imagedata o:title="" src="file:///C:/DOCUME~1/WU93D5~1.JIA/LOCALS~1/Temp/msoclip1/01/clip_image013.png"></v:imagedata></v:shape></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为了计算一份数据报的</span> I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">检验和，首先把检验和字段置为</span> 0<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。然后，对首部中每个</span> 16 bit</p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">进行二进制反码求和（整个首部看成是由一串</span> 16 bit<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的字组成），结果存在检验和字段中。当收到一份</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据报后，同样对首部中每个</span>16 bit<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">进行二进制反码的求和。由于接收方在计算过程中包含了发送方存在首部中的检验和，因此，如果首部在传输过程中没有发生任何差错，那么接收方计算的结果应该为全</span> 1<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。如果结果不是全</span>1<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（即检验和错误），那么</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就丢弃收到的数据报。但是不生成差错报文，由上层去发现丢失的数据报并进行重传。</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">路由选择是简单的，特别对于主机来说。如果目的主机与源主机直接相连（如点对点链路）或都在一个共享网络上（以太网或令牌环网），那么</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据报就直接送到目的主机上。否则，主机把数据报发往一默认的路由器上，由路由器来转发该数据报。大多数的主机都是采用这种简单机制。即</span> I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">层既可以配置成路由器的功能，也可以配置成主机的功能。当今的大多数多用户系统，包括几乎所有的</span> U n i x<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">系统，都可以配置成一个路由器。我们可以为它指定主机和路由器都可以使用的简单路由算法。本质上的区别在于主机从不把数据报从一个接口转发到另一个接口，而路由器则要转发数据报。内含路由器功能的主机应该从不转发数据报，除非它被设置成那样。在</span> 9 . 4<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">小节中，我们将进一步讨论配置的有关问题。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在一般的体制中，</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以从</span>T C P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span>U D P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span>I C M P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span>I G M P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接收数据报（即在本地生成的数据报）并进行发送，或者从一个网络接口接收数据报（待转发的数据报）并进行发送。</span> I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">层在内存中有一个路由表。当收到一份数据报并进行发送时，它都要对该表搜索一次。当数据报来自某个网络接口时，</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">首先检查目的</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址是否为本机的</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址之一或者</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">广播地址。如果确实是这样，数据报就被送到由</span> I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">首部协议字段所指定的协议模块进行处理。如果数据报的目的不是这些地址，那么（</span> 1<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）如果</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">层被设置为路由器的功能，那么就对数据报进行转发（也就是说，像下面对待发出的数据报一样处理）；否则（</span> 2<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）数据报被丢弃。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">路由表中的每一项都包含下面这些信息：</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">* <span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">目的</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址。它既可以是一个完整的主机地址，也可以是一个网络地址，由该表目中的标志字段来指定（如下所述）。主机地址有一个非</span>0<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的主机号（见图</span>1 - 5<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">），以指定某一特定的主机，而网络地址中的主机号为</span>0<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，以指定网络中的所有主机（如以太网，令牌环网）。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">* <span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">下一站（或下一跳）路由器（</span> next-hop router<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）的</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址，或者有直接连接的网络</span> I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址。下一站路由器是指一个在直接相连网络上的路由器，通过它可以转发数据报。下</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一站路由器不是最终的目的，但是它可以把传送给它的数据报转发到最终目的。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">*<span style="mso-spacerun: yes">&nbsp; </span><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">标志。其中一个标志指明目的</span> I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址是网络地址还是主机地址，另一个标志指明下一</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">站路由器是否为真正的下一站路由器，还是一个直接相连的接口（我们将在</span> 9 . 2<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">节中</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">详细介绍这些标志）。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.25in"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为数据报的传输指定一个网络接口。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">&nbsp;<o:p></o:p></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">路由选择是逐跳地（</span>h o p - b y - h o p <span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）进行的。从这个路由表信息可以看出，</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">并不知道到</span><span lang=ZH-CN> </span><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">达任何目的的完整路径（当然，除了那些与主机直接相连的目的）。所有的</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">路由选择只为数</span><span lang=ZH-CN> </span><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">据报传输提供下一站路由器的</span> I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址。它假定下一站路由器比发送数据报的主机更接近目的，</span><span lang=ZH-CN> </span><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">而且下一站路由器与该主机是直接相连的。</span> </p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">路由选择主要完成以下这些功能：</span> </p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>1) <span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">搜索路由表，寻找能与目的</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址完全匹配的表目（网络号和主机号都要匹配）。如果找到，则把报文发送给该表目指定的下一站路由器或直接连接的网络接口（取决于标</span> </p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">志字段的值）。</span> </p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>2) <span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">搜索路由表，寻找能与目的网络号相匹配的表目。如果找到，则把报文发送给该表目指定的下一站路由器或直接连接的网络接口（取决于标志字段的值）。目的网络上的所有主机都可以通过这个表目来处置。例如，一个以太网上的所有主机都是通过这种表目进行寻径的。这种搜索网络的匹配方法必须考虑可能的子网掩码。关于这一点我们在下一节中进行</span> </p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">讨论。</span> </p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt; TEXT-INDENT: 21.75pt">3) <span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">搜索路由表，寻找标为&#8220;默认（</span> d e f a u l t <span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）&#8221;的表目。如果找到，则把报文发送给该表目指定的下一站路由器。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt; TEXT-INDENT: 21.75pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果上面这些步骤都没有成功，那么该数据报就不能被传送。如果不能传送的数据报来自本机，那么一般会向生成数据报的应用程序返回一个&#8220;主机不可达&#8221;或&#8220;网络不可达&#8221;的错误。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><v:shape id=_x0000_i1032 style="WIDTH: 414.75pt; HEIGHT: 67.5pt" type="#_x0000_t75"><v:imagedata o:title="" src="file:///C:/DOCUME~1/WU93D5~1.JIA/LOCALS~1/Temp/msoclip1/01/clip_image015.png"></v:imagedata></v:shape></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><v:shape id=_x0000_i1033 style="WIDTH: 414.75pt; HEIGHT: 118.5pt" type="#_x0000_t75"><v:imagedata o:title="" src="file:///C:/DOCUME~1/WU93D5~1.JIA/LOCALS~1/Temp/msoclip1/01/clip_image017.png"></v:imagedata></v:shape></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">&nbsp;<o:p></o:p></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">给定</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址和子网掩码以后，主机就可以确定</span> I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据报的目的是：</span>(1)<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">本子网上的主机；</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">(2)<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">本网络中其他子网中的主机；</span>( 3)<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">其他网络上的主机。如果知道本机的</span> I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址，那么就知道它是否为</span>A<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类、</span>B<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类或</span>C<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类地址</span>(<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">从</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址的高位可以得知</span>)<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，也就知道网络号和子网号之间的分界线。而根据子网掩码就可知道子网号与主机号之间的分界线。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">&nbsp;<o:p></o:p></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">举例</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">假设我们的主机地址是</span>1 4 0 . 2 5 2 . 1 . 1<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（一个</span>B<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类地址），而子网掩码为</span>2 5 5 . 2 5 5 . 2 5 5 . 0<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（其中</span>8b i t<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为子网号，</span>8 bit<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为主机号）。</span>* <span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果目的</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址是</span>1 4 0 . 2 5 2 . 4 . 5<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，那么我们就知道</span>B<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类网络号是相同的（</span>1 4 0 . 2 5 2<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">），但是子网号是不同的（</span>1<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span>4<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）。用子网掩码在两个</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址之间的比较如图</span>3 - 8<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">所示。</span>* <span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果目的</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址是</span>1 4 0 . 2 5 2 . 1 . 2 2<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，那么</span>B<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类网络号还是一样的（</span>1 4 0 . 2 5 2<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">），而且子网号也是一样的（</span>1<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">），但是主机号是不同的。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果目的</span>I P<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址是</span>1 9 2 . 4 3 . 2 3 5 . 6<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（一个</span>C<span lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类地址），那么网络号是不同的，因而进一步的比较就不用再进行了。</span></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><v:shape id=_x0000_i1034 style="WIDTH: 417pt; HEIGHT: 135.75pt" type="#_x0000_t75"><v:imagedata o:title="" src="file:///C:/DOCUME~1/WU93D5~1.JIA/LOCALS~1/Temp/msoclip1/01/clip_image019.png"></v:imagedata></v:shape></p>
<img src ="http://www.cnitblog.com/wujian-IT/aggbug/35342.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/wujian-IT/" target="_blank">吴剑</a> 2007-10-25 19:43 <a href="http://www.cnitblog.com/wujian-IT/archive/2007/10/25/35342.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>TCP/IP学习笔记6，7，8章（协议篇）</title><link>http://www.cnitblog.com/wujian-IT/archive/2007/10/24/35298.html</link><dc:creator>吴剑</dc:creator><author>吴剑</author><pubDate>Wed, 24 Oct 2007 15:09:00 GMT</pubDate><guid>http://www.cnitblog.com/wujian-IT/archive/2007/10/24/35298.html</guid><wfw:comment>http://www.cnitblog.com/wujian-IT/comments/35298.html</wfw:comment><comments>http://www.cnitblog.com/wujian-IT/archive/2007/10/24/35298.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/wujian-IT/comments/commentRss/35298.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/wujian-IT/services/trackbacks/35298.html</trackback:ping><description><![CDATA[<p>6、ICMP: Internet控制报文协议</p>
<p>I C M P报文通常被I P层或更高层协议（ T C P或U D P）使用。I C M P报文是在I P数据报内部被传输的</p>
<p><!--[if gte vml 1]>
<![endif]--><!--[if !vml]--><img src="file:///C:/DOCUME%7E1/ADMINI%7E1/LOCALS%7E1/Temp/msohtml1/01/clip_image002.jpg" v:shapes="_x0000_i1025" height="137" width="344"><!--[endif]--></p>
<p><!--[if gte vml 1]>
<![endif]--><!--[if !vml]--><img src="file:///C:/DOCUME%7E1/ADMINI%7E1/LOCALS%7E1/Temp/msohtml1/01/clip_image004.jpg" v:shapes="_x0000_i1026" height="180" width="480"><!--[endif]--></p>
<p>ICMP不同类型由报文中的类型字段和代码字段来共同决定。可以确定I C M P报文是一份查询报文还是一份差错报文。因为对I C M P差错报</p>
<p>文有时需要作特殊处理，因此我们需要对它们进行区分。例如，在对I C M P差错报文进行响应</p>
<p>时，永远不会生成另一份I C M P差错报文（如果没有这个限制规则，可能会遇到一个差错产生</p>
<p>另一个差错的情况，而差错再产生差错，这样会无休止地循环下去）。当发送一份I C M P差错报文时，报文始终包含I P的首部和产生I C M P差错报文的I P数据报的前8个字节。这样，接收I C M P差错报文的模块就会把它与某个特定的协议（根据I P数据报首部中的协议字段来判断）和用户进程（根据包含在I P数据报前8个字节中的T C P或U D P报文首部中的T C P或U D P端口号来判断）联系起来。</p>
<p>&nbsp;</p>
<p>7、ping程序</p>
<p>发送回显请求的p i n g程序为客户，而称被p i n g的主机为服务器。大多数的T C P / I P</p>
<p>实现都在内核中直接支持P i n g服务器—这种服务器不是一个用户进程（在第6章中描述的两</p>
<p>种I C M P查询服务，地址掩码和时间戳请求，也都是直接在内核中进行处理的）</p>
<p>I C M P回显请求和回显应答报文如图7 - 1所示。</p>
<p><!--[if gte vml 1]>
<![endif]--><!--[if !vml]--><img src="file:///C:/DOCUME%7E1/ADMINI%7E1/LOCALS%7E1/Temp/msohtml1/01/clip_image006.jpg" v:shapes="_x0000_i1027" height="216" width="554"><!--[endif]--></p>
<p>对于其他类型的I C M P查询报文，服务器必须响应标识符和序列号字段。另外，客户发送</p>
<p>的选项数据必须回显，假设客户对这些信息都会感兴趣。</p>
<p>U n i x系统在实现p i n g程序时是把I C M P报文中的标识符字段置成发送进程的I D号。这样</p>
<p>即使在同一台主机上同时运行了多个p i n g程序实例， p i n g程序也可以识别出返回的信息。序列号从0开始，每发送一次新的回显请求就加1。p i n g程序打印出返回的每个分组的序列号，允许我们查看是否有分组丢失、失序或重复。I P是一种最好的数据报传递服务，因此</p>
<p>这三个条件都有可能发生。</p>
<p>敲入p i n g命令，几秒钟过后会在第1行打印出I P地址， D N S就是利用这段时间来确定主机</p>
<p>名所对应的I P地址。通常，第1个往返时间值要比其他的大。这是由于目的端的硬件地址不在A R P高速缓存中的缘故。在发送第一个回显请求之前要发送一个A R P请求并接收A R P应答，这需要花费几毫秒的时间。</p>
<p>IP首部最长为6 0个字节, 固定长度为2 0字节，R R选项用去3个字节（下面我们再讨论），这样只剩下3 7个字节（ 6 0-2 0-3）来存放I P地址清单，也就是说只能存放9个I P地址。I P数据报中的R R选项的一般格式如图所示。</p>
<p><!--[if gte vml 1]>
<![endif]--><!--[if !vml]--><img src="file:///C:/DOCUME%7E1/ADMINI%7E1/LOCALS%7E1/Temp/msohtml1/01/clip_image008.jpg" v:shapes="_x0000_i1028" height="146" width="554"><!--[endif]--></p>
<p>c o d e是一个字节，指明I P选项的类型。对于R R选项来说，它的值为7。l e n是R R选项总字</p>
<p>节长度，在这种情况下为3 9（尽管可以为R R选项设置比最大长度小的长度，但是p
i n g程序</p>
<p>总是提供3 9字节的选项字段，最多可以记录9个I P地址。由于I P首部中留给选项的空间有限，</p>
<p>它一般情况都设置成最大长度）。</p>
<p>p t r称作指针字段。它是一个基于1的指针，指向存放下一个I P地址的位置。它的最小值为</p>
<p>4，指向存放第一个I P地址的位置。随着每个I P地址存入清单， p t r的值分别为8，1 2，1 6，最</p>
<p>大到3 6。当记录下9个I P地址后，p t r的值为4 0，表示清单已满。</p>
<p>I P时间戳选项与记录路由选项类似。</p>
<p><!--[if gte vml 1]>
<![endif]--><!--[if !vml]--><img src="file:///C:/DOCUME%7E1/ADMINI%7E1/LOCALS%7E1/Temp/msohtml1/01/clip_image010.jpg" v:shapes="_x0000_i1029" height="123" width="554"><!--[endif]--></p>
<p>8、Traceroute程序</p>
<p>在7 . 3节中，我们描述了I P记录路由选项（ R R）。为什么不使用这个选项而另外开发一个</p>
<p>新的应用程序？有三个方面的原因。首先，原先并不是所有的路由器都支持记录路由选项，</p>
<p>因此该选项在某些路径上不能使用（ Tr a c e r o u t e程序不需要中间路由器具备任何特殊的或可选的功能）。</p>
<p>其次，记录路由一般是单向的选项。发送端设置了该选项，那么接收端不得不从收到的I P</p>
<p>首部中提取出所有的信息，然后全部返回给发送端。在7 . 3节中，我们看到大多数P i n g服务器的实现（内核中的I C M P回显应答功能）把接收到的R R清单返回，但是这样使得记录下来的I P地址翻了一番（一来一回）。这样做会受到一些限制，这一点我们在下一段讨论（
Tr a c e r o u t e程序只需要目的端运行一个U D P模块—其他不需要任何特殊的服务器应用程序）。</p>
<p>最后一个原因也是最主要的原因是， I P首部中留给选项的空间有限，不能存放当前大多</p>
<p>数的路径。在I P首部选项字段中最多只能存放9个I P地址。在原先的A R PA N E T中这是足够的，</p>
<p>但是对现在来说是远远不够的。</p>
<p>Tr a c e r o u t e程序使用I C M P报文和I P首部中的T T L字段（生存周期）。每个处理数据报的路由器都需要把T T L的值减1或减去数据报在路由器中停留的秒数。由于大多数的路由器转发数据报的时延都小于1秒钟，因此T T L最终成为一个跳站的计数器，所经过的每个路由器都将其值减1。T T L字段的目的是防止数据报在选路时无休止地在网络中流动。</p>
<p>当路由器收到一份I P数据报，如果其T T L字段是0或1，则路由器不转发该数据报（接收到</p>
<p>这种数据报的目的主机可以将它交给应用程序，这是因为不需要转发该数据报。但是在通常</p>
<p>情况下，系统不应该接收T T L字段为0的数据报）。相反，路由器将该数据报丢弃，并给信源</p>
<p>机发一份I C M P&#8220;超时&#8221;信息。Tr a c e r o u t e程序的关键在于包含这份I C M P信息的I P报文的信源地址是该路由器的I P地址。</p>
<p>我们现在可以猜想一下Tr a c e r o u t e程序的操作过程。它发送一份T T L字段为1的I P数据报给</p>
<p>目的主机。处理这份数据报的第一个路由器将T T L值减1，丢弃该数据报，并发回一份超时</p>
<p>I C M P报文。这样就得到了该路径中的第一个路由器的地址。然后Tr a c e r o u t e程序发送一份</p>
<p>T T L值为2的数据报，这样我们就可以得到第二个路由器的地址。继续这个过程直至该数据报</p>
<p>到达目的主机。但是目的主机哪怕接收到T T L值为1的I P数据报，也不会丢弃该数据报并产生</p>
<p>一份超时I C M P报文，这是因为数据报已经到达其最终目的地。那么我们该如何判断是否已经</p>
<p>到达目的主机了呢？</p>
<p>Tr a c e r o u t e程序发送一份U D P数据报给目的主机，但它选择一个不可能的值作为U D P端口</p>
<p>号（大于30 000），使目的主机的任何一个应用程序都不可能使用该端口。因为，当该数据报</p>
<p>到达时，将使目的主机的U D P模块产生一份&#8220;端口不可达&#8221;错误（见6 . 5节）的I C M P报文。</p>
<p>这样，Tr a c e r o u t e程序所要做的就是区分接收到的I C M P报文是超时还是端口不可达，以判断什么时候结束。</p>
<br><img src ="http://www.cnitblog.com/wujian-IT/aggbug/35298.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/wujian-IT/" target="_blank">吴剑</a> 2007-10-24 23:09 <a href="http://www.cnitblog.com/wujian-IT/archive/2007/10/24/35298.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>原码、反码和补码</title><link>http://www.cnitblog.com/wujian-IT/archive/2007/10/23/35248.html</link><dc:creator>吴剑</dc:creator><author>吴剑</author><pubDate>Tue, 23 Oct 2007 15:11:00 GMT</pubDate><guid>http://www.cnitblog.com/wujian-IT/archive/2007/10/23/35248.html</guid><wfw:comment>http://www.cnitblog.com/wujian-IT/comments/35248.html</wfw:comment><comments>http://www.cnitblog.com/wujian-IT/archive/2007/10/23/35248.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/wujian-IT/comments/commentRss/35248.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/wujian-IT/services/trackbacks/35248.html</trackback:ping><description><![CDATA[<p>大家都知道数据在计算机中都是按字节来储存了，1个字节等于8位（1Byte=8bit），而计算机只能识别0和1这两个数，所以根据排列，1个字
节能代表256种不同的信息，即28（0和1两种可能，8位排列），比如定义一个字节大小的无符号整数（unsigned
char），那么它能表示的是0～255（0~28-1）这些数，一共是256个数，因为，前面说了，一个字节只能表示256种不同的信息。别停下，还是
一个字节的无符号整数，我们来进一步剖析它，0是这些数中最小的一个，我们先假设它在计算机内部就用8位二进制表示为00000000（从理论上来说也可
以表示成其他不同的二进制码，只要这256个数每个数对应的二进制码都不相同就可以了），再假设1表示为00000001，2表示为00000010，3
表示为00000011，依次类推，那么最大的那个数255在8位二进制中就表示为最大的数11111111，然后，我们把这些二进制码换算成十进制看
看，会发现刚好和我们假设的数是相同的，而事实上，在计算机中，无符号的整数就是按这个原理来储存的，所以告诉你一个无符号的整数的二进制码，你就可以知
道这个数是多少，而且知道在计算机中，这个数本身就是以这个二进制码来储存的。比如我给你一个2个字节大小的二进制码，首先声明它表示的是无符号的整数：
00000000
00000010，我们把前面的0省略，换算一下，它表示的也是数值2，和前面不同的是，它占了2个字节的内存。不同的类型占的内存空间不同，如在我的电
脑中char是1个字节，int是4个字节，long是8个字节（你的可能不同，这取决于不同的计算机设置），它们的不同之处仅仅是内存大的能表示的不同
的信息多些，也就是能表示的数范围更大些（unsigned
int能表示的范围是0~28*4-1），至于怎么算，其实都是一样的，直接把二进制与十进制相互转换，二进制就是它在计算机中的样子，十进制就是我们所
表示的数。啊哈，原来这些都是可以计算的呀，我曾经还以为不同的计算机储存的原理是不同的，取决于商家的喜好呢，呵呵。说了这么多怎么还没有提到原码、反
码和补码呀，别急别急，心急吃不了热豆腐，呵呵，因为无符号的整数根本就没有原码、反码和补码。（啊，那不是被欺骗了，5555````我告诉妈妈去，哥
哥欺负我）都说了别急嘛，你就不想想我说了这么半天的无符号整数，那么有符号的整数怎么办啊？</p>
<p>　　呵呵，对，只有有符号的整数才有原码、反
码和补码的！其他的类型一概没有。虽然我们也可以用二进制中最小的数去对应最小的负数，最大的也相对应，但是那样不科学，下面来说说科学的方法。还是说一
个字节的整数，不过这次是有符号的啦，1个字节它不管怎么样还是只能表示256个数，因为有符号所以我们就把它表示成范围：-128-127。它在计算机
中是怎么储存的呢？可以这样理解，用最高位表示符号位，如果是0表示正数，如果是1表示负数，剩下的7位用来储存数的绝对值的话，能表示27个数的绝对
值，再考虑正负两种情况，27*2还是256个数。首先定义0在计算机中储存为00000000，对于正数我们依然可以像无符号数那样换算，从
00000001到01111111依次表示1到127。那么这些数对应的二进制码就是这些数的原码。到这里很多人就会想，那负数是不是从
10000001到11111111依次表示-1到-127，那你发现没有，如果这样的话那么一共就只有255个数了，因为10000000的情况没有考
虑在内。实际上，10000000在计算机中表示最小的负整数，就是这里的-128，而且实际上并不是从10000001到11111111依次表示-1
到-127，而是刚好相反的，从10000001到11111111依次表示-127到-1。负整数在计算机中是以补码形式储存的，补码是怎么样表示的
呢，这里还要引入另一个概念——反码，所谓反码就是把负数的原码（负数的原码和和它的绝对值所对应的原码相同，简单的说就是绝对值相同的数原码相同）各个
位按位取反，是1就换成0，是0就换成1，如-1的原码是00000001，和1的原码相同，那么-1的反码就是11111110，而补码就是在反码的基
础上加1，即-1的补码是11111110+1=11111111，因此我们可以算出-1在计算机中是按11111111储存的。总结一下，计算机储存有
符号的整数时，是用该整数的补码进行储存的，0的原码、补码都是0，正数的原码、补码可以特殊理解为相同，负数的补码是它的反码加1。下面再多举几个例
子，来帮助大家理解！</p>
<p>十进制　&#8594;　二进制　　（怎么算？要是不知道看计算机基础的书去）<br>47　　　&#8594;　101111</p>
<p>有符号的整数　　　　原码　　　　反码　　　　补码<br>　　47　　　　　　00101111　　11010000　　00101111（正数补码和原码相同）<br>　－47　　　　　　00101111　　11010000　　11010001（负数补码是在反码上加1）</p>
<p>再举个例子，学C语言的同学应该做过这道题：<br>把－1以无符号的类型输出，得什么结果？（程序如下）</p>
<p>#include&lt;iostream.h&gt;<br>void main()<br>{<br>&nbsp;short int  n=-1;<br>&nbsp;cout&lt;&lt;(unsigned short int)n&lt;&lt;endl;<br>}</p>
<p>
首先在我的电脑中short
int类型的储存空间是2个字节，你的可能不同，我说过，这取决于你的计算机配置。它能储存28*2＝65536个不同的数据信息，如果是无符号那么它的
范围是0~65535（0~216-1），如果是有符号，那么它的范围是-32768~32767（-215~215-1）。这道题目中，开始n是一个有
符号的短整型变量，我们给它赋值为-1，根据我们前面所说的，它在计算机中是以补码11111111
11111111储存的，注意前面说了是2个字节。如果把它强制为无符号的短整型输出的话，那么我们就把刚才的二进制把看成无符号的整型在计算机中储存的
形式，对待无符号的整型就没有什么原码、反码和补码的概念了，直接把11111111
11111111转化成十进制就是65535，其实我们一看都是一就知道它是范围中最大的一个数了。呵呵，就这么简单。你个把上面的源代码编译运行看看，
如果你的电脑short int也是两个字节，那就会和我得一样的结果。你可以先用这个语句看看：cout&lt;&lt;sizeof(short
int)&lt;&lt;endl;看看你的电脑里的短整型占多少的储存空间，也可以用sizeof来看其它任何类型所分配的储存空间。</p>
<p>　　最后提醒一句，关于数据如何在计算机中储存的，这里只适用于整型的数据，对于浮点型的是另一种方式，这里我们暂时就不深究了。</p>
<br><img src ="http://www.cnitblog.com/wujian-IT/aggbug/35248.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/wujian-IT/" target="_blank">吴剑</a> 2007-10-23 23:11 <a href="http://www.cnitblog.com/wujian-IT/archive/2007/10/23/35248.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>字符串转化成16进制</title><link>http://www.cnitblog.com/wujian-IT/archive/2007/10/21/35155.html</link><dc:creator>吴剑</dc:creator><author>吴剑</author><pubDate>Sun, 21 Oct 2007 15:44:00 GMT</pubDate><guid>http://www.cnitblog.com/wujian-IT/archive/2007/10/21/35155.html</guid><wfw:comment>http://www.cnitblog.com/wujian-IT/comments/35155.html</wfw:comment><comments>http://www.cnitblog.com/wujian-IT/archive/2007/10/21/35155.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/wujian-IT/comments/commentRss/35155.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/wujian-IT/services/trackbacks/35155.html</trackback:ping><description><![CDATA[//********************************************************* &nbsp; <br> &nbsp; // &nbsp;  &nbsp;  &nbsp; <br>&nbsp; &nbsp; // &nbsp;  &nbsp;  &nbsp;
<p><nobr id="key2" style="border-bottom: 0px dotted; text-decoration: underline; color: #6600ff; background-color: transparent;" onclick="return kwc();" target="_blank" oncontextmenu="return false;" onmouseover="kwE(event,2, this);" onmouseout="kwL(event, this);" onmousemove="kwM(2);"></nobr>//字符串转化成16进制存入CHAR数组中 &nbsp; <br> &nbsp; // &nbsp;  &nbsp;  &nbsp; 作者:QQTCC &nbsp; <br> &nbsp; // &nbsp;  &nbsp;  &nbsp; 日期:2006.12.7 &nbsp; <br> &nbsp; // &nbsp; <br> &nbsp; //********************************************************* &nbsp; <br> &nbsp; #include &nbsp; &lt;iostream&gt; &nbsp; <br> &nbsp; using &nbsp; namespace &nbsp; std; &nbsp; <br> &nbsp; bool &nbsp; isNumber(char &nbsp; *p) &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp; //字符串位是否数字或字母判断; &nbsp; <br> &nbsp; { &nbsp; <br> &nbsp; 	if(*p&gt;='0'&amp;&amp; &nbsp; *p&lt;='9') &nbsp; <br> &nbsp; 	{return &nbsp; true;} &nbsp; <br> &nbsp; 	else &nbsp; return &nbsp; false; &nbsp; <br> &nbsp; } &nbsp; <br> &nbsp;  &nbsp; <br> &nbsp; void &nbsp; convert(char &nbsp; *p,unsigned &nbsp; char &nbsp; str[]) &nbsp; <br> &nbsp; { &nbsp; <br> &nbsp; 	int &nbsp; high,low,i=0; &nbsp; <br> &nbsp; 	while(*p!='\0') &nbsp; <br> &nbsp; 	{ &nbsp; <br> &nbsp; 		if(isNumber(p)) &nbsp; <br> &nbsp; 		{high=(*p-48)&lt;&lt;4; &nbsp; } &nbsp;  &nbsp;  &nbsp; //按ASCII转换成整数并左移4位 &nbsp; <br> &nbsp; 		else &nbsp; <br> &nbsp; 		{high=(*p-55)&lt;&lt;4; &nbsp; } &nbsp;  &nbsp;  &nbsp; //ASCII转换成整数左移4位 &nbsp; <br> &nbsp; 		high=high&amp;0xF0; &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp; //低4位屏蔽 &nbsp; <br> &nbsp; 		++p; &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp; //读低4位 &nbsp; <br> &nbsp; 		if(isNumber(p)) &nbsp; <br> &nbsp; 		{low=*p-48; &nbsp; } &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp; //左移4位 &nbsp; <br> &nbsp; 		else &nbsp; <br> &nbsp; 		{low=*p-55; &nbsp;  &nbsp; } &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp; //左移4位 &nbsp; <br> &nbsp; 		low=low&amp;0x0F; &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp; //高4位屏蔽 &nbsp; <br> &nbsp; 		str[i++]=low|high; &nbsp; <br> &nbsp; 		++p; &nbsp; <br> &nbsp; 	} &nbsp; <br> &nbsp; } &nbsp; <br> &nbsp; void &nbsp; main() &nbsp; <br> &nbsp; { &nbsp; <br> &nbsp; 	char &nbsp; str[]="1234567890ABCDEF"; &nbsp; <br> &nbsp; 	unsigned &nbsp; char &nbsp; dest[8]; &nbsp; <br> &nbsp; 	char &nbsp; *p=str; &nbsp; <br> &nbsp; 	convert(p,dest);	 &nbsp; <br> &nbsp; 	for(int &nbsp; j=0;j&lt;8;j++) &nbsp; <br> &nbsp; 	{cout&lt;&lt;hex&lt;&lt;dest[j]&lt;&lt;endl;}	//结果扩展ASCII,我查表验证过. &nbsp; <br> &nbsp; }</p>
<br><img src ="http://www.cnitblog.com/wujian-IT/aggbug/35155.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/wujian-IT/" target="_blank">吴剑</a> 2007-10-21 23:44 <a href="http://www.cnitblog.com/wujian-IT/archive/2007/10/21/35155.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>