<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
 <channel>
  <title>一个软件</title>
  <link>http://asoft.blogbus.com</link>
  <description><![CDATA[傻人写程序、人傻程序绝 2005-9-1]]></description>
  <generator> by blogbus.com </generator>
  <lastBuildDate>Thu, 01 Jan 1970 07:00:00 +0700</lastBuildDate>
  <image>
									<url>http://public.blogbus.com/profile/head.gif</url>
									<title>一个软件</title>
									<link>http://asoft.blogbus.com</link>
								</image>  <item>
   <title>KM3D引擎功能描述</title>
   <description><![CDATA[<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-family: "Times New Roman"; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: 15pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left"><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><strong>引言</strong><span lang="EN-US"><br />KM3D</span>引擎是合适制作类似《魔兽争霸<span lang="EN-US">3</span>》视角的全<span lang="EN-US">3D</span>游戏引擎。<span lang="EN-US"><br /></span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: 15pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left"><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><strong>客户端部分</strong>：引擎亮点（模型、界面、场景）<span lang="EN-US"><p /></span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: 15pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left"><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: 15pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left"><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><strong>渲染引擎</strong>：游戏采用<span lang="EN-US">D3D/OpenGL</span>技术实现<span lang="EN-US">3D</span>渲染部分，可供用户根据自己的显卡自己选择合适的渲染管道。引擎用的是<span lang="EN-US">DX7.0</span>和少部分<span lang="EN-US">DX8.0</span>的技术。<span lang="EN-US">OpenGL</span>部分也只用到了<span lang="EN-US">OGL1.3</span>版本规范，向下兼容。目前能够支持的显卡大约市值大约<span lang="EN-US">150</span>元左右。<span lang="EN-US"><p /></span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: 15pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left"><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: 15pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left"><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><strong>地图场景</strong><span lang="EN-US"><br /></span>    每张场景最大<span lang="EN-US">256*256</span>个网格，每个网格分为<span lang="EN-US">4</span>段做步长。也就是横竖可以放置<span lang="EN-US">1024</span>个角色单位。中上复杂度场景（指很多场景装饰物件）<span lang="EN-US">P4-2.4CPU</span>可以做到无消耗切换，<span lang="EN-US">P3-500</span>机器需要<span lang="EN-US">5</span>秒钟。<span lang="EN-US">[</span>注：《魔兽争霸<span lang="EN-US">3</span>》游戏中提供的官方场景，复杂度都没有超过中上复杂，如果运用在网游中，场景复杂度要要简单很多。可以编辑出可进入式的房间供场景编辑器：可以编辑类似《魔兽争霸<span lang="EN-US">3</span>》地形地貌的编辑器，该编辑器可以读取并编辑《魔兽争霸<span lang="EN-US">3-</span>冰峰王座》编辑器生成的地图，也可以编辑的《魔兽争霸<span lang="EN-US">2</span>》地图编辑器生成的地图。</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: 15pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left"><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><span lang="EN-US"><p /></span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: 15pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left"><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><strong>游戏界面</strong><span lang="EN-US"><br /></span>    采用类似《魔兽世界》的界面方式，采用<span lang="EN-US">XML+LUA</span>脚本的实现方法。界面编辑非常灵活简单，而且界面也可以做到非常花哨。目前除《魔兽世界》树型下拉列表外的其他所有界面都可以实现。</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: 15pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left"><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: 15pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left"><span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><strong>3D</strong></span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><strong>模型</strong>：使用<span lang="EN-US">3DMax</span>模型编辑。<span lang="EN-US"><br /></span>   模型制作是这个游戏引擎的重点，引擎中的绝大部分都是模型操作，包括天空盒、烟火爆炸效果，甚至是雨雪的天气变化均有粒子模型产生。这样做的目的是这些效果有美术效果好看，程序控制简单。<span lang="EN-US"><br /></span>   特色一：角色模型制作采用和《魔兽世界》等同的方法。制作者无需要考虑换装时候有关连接可能会破损的因素。每个角色不包括换装，只是个性化特色，就有<span lang="EN-US">1300</span>万种之多。此类模型体统<span lang="EN-US">LOD3</span>级细节，就是模型制作时候按照三角面分为<span lang="EN-US">3</span>层近多远少的原则制作，也可以根据同屏幕中角色的多少进行调节。<span lang="EN-US"><br /></span>   特色二：模型中的骨骼蒙皮和顶点蒙皮相互混合的方式制作，目前该技术只有《魔兽世界》在运用。该技术对<span lang="EN-US">3D</span>美术制作水平要求低，完全不需要懂什么是骨骼动画。甚至连<span lang="EN-US">3Dmax</span>中的<span lang="EN-US">character studio</span>的插件都无需安装。但是却能够做到一些意想不到的效果，例如角色呼吸时候，胸部的起伏。角色眼睛眨动，嘴巴说话等。正是由于实现了该技术，无需显卡支持<span lang="EN-US">VS/PS</span>技术，也能够在低档显卡上做到流畅效果。<span lang="EN-US"><br /></span>   特色三：在动画制作中可以根据某个特殊需要，直接插入音效播放。例如模型在受到攻击时候需要发出什么样的声音，小鸟在天空飞翔时候，叽叽喳喳的声音，都是放在模型中处理的。<span lang="EN-US"><br /></span>   特色四：模型中的粒子也全部在<span lang="EN-US">3DMax</span>中实现。制作简单，美术编辑程序播放，效果更好。<span lang="EN-US"><br /></span>   特色五：模型中的带子效果，指具有带状的魔法特效也全部在<span lang="EN-US">3DMax</span>中制作。例如，一个角色在拿着武器攻击时候，武器运动的虚光等。也直接在<span lang="EN-US">3DMax</span>中，附属于武器时候直接编辑就可以了。<span lang="EN-US"><br /></span>   特色六：角色模型在游戏中，头部可以根据需要智能转向。例如个头高大的角色和个头低矮的角色在说话或对战时，个高的会低头，个矮的会抬头。这些细节只需在制作模型时候指定参数，无需调整动画。<span lang="EN-US"><p /></span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: 15pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left"><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: 15pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left"><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><strong>渲染效率</strong>：<span lang="EN-US"><br /></span>    同屏场景中可以容纳在<span lang="EN-US">30</span>个动画角色左右，每个角色<span lang="EN-US">1500</span>个三角面，在<span lang="EN-US">PIII500</span>，<span lang="EN-US">G-Force2 MMX440</span>显示卡的机器，可以做到每秒播放<span lang="EN-US">30</span>帧流畅渲染。该种视角主角人物一般<span lang="EN-US">800</span>个三角面足以表现细致。可参加提供的模型范例。<span lang="EN-US">[</span>注意：引擎场景不合适第一人称视角的游戏，如果一定要采用第一人称视角，需要酌情考虑利用引擎的其他部分，重新写过该引擎提供场景部分<span lang="EN-US">]<p /></span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: 15pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left"><span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><br /></span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><strong>服务器部分</strong>：<span lang="EN-US"><br /></span>    采用<span lang="EN-US">ACE+BOOST+LUA</span>构成，跨平台。<span lang="EN-US"><br /></span>    建议使用<span lang="EN-US">Linux2.6</span>系统平台，采用了<span lang="EN-US">E-Poll</span>技术，从而解决了网络游戏最大的瓶颈<span lang="EN-US">-</span>即<span lang="EN-US">IO</span>效率，理论上可以同时允许<span lang="EN-US">1024*128</span>的连接。<span lang="EN-US"><br /></span>    高性能的负载均衡采用<span lang="EN-US">mosix</span>或者<span lang="EN-US">openmosix</span>方案，可以大大降低服务器运营成本。<span lang="EN-US"><br />    [</span>参见<span lang="EN-US"><a href="http://www.mosix.org">http://www.mosix.org</a></span>或者<span lang="EN-US">http://openmosix.sourceforge.net]<br /></span>    网络通讯部分代码，采用<span lang="EN-US">ACE</span>技术，这是免费开源的一整套网络解决方案，<span lang="EN-US">2004</span>年被称之为<span lang="EN-US">“</span>无需继续开发轮子<span lang="EN-US">”</span>网络方案，意思就是目前没有更好的网络解决方案了。虽然目前网络游戏应用还是很少见，大部分都还是制作公司自己实现的。但是该解决方案在其他大型企业网络产品领域已经开始被推崇并使用。使用<span lang="EN-US">ACE</span>的好处是：增强可移植、更好的软件质量、更高的效率和可预测性、更容易转换到标准的高级中间件。<span lang="EN-US"><br />    [</span>参见<span lang="EN-US"><a href="http://www.cs.wustl.edu/~schmidt/ACE.html">http://www.cs.wustl.edu/~schmidt/ACE.html</a>]<p /></span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: 15pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left"><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">    游戏服务器的逻辑运算均有<span lang="EN-US">LUA</span>脚本实现,<span lang="EN-US">LUA</span>是免费开源的脚本语言，目前已经是<span lang="EN-US">5.4</span>版本了。台湾游戏制作公司的一些单机版本游戏中已经使用。最新暴雪公司推出的《魔兽世界》也采用了该脚本语言，一下子成为游戏届的领头脚本语言。该脚本语言短小精悍，效率很高。一般非程序人员大约<span lang="EN-US">1</span>周时间可以基本掌握使用。<span lang="EN-US">[</span>参见<span lang="EN-US"><a href="http://www.lua.org">http://www.lua.org</a>]</span>这样做的目的是为了更加灵活的对服务器的游戏中逻辑运算进行方便的调节，甚至是不需要重新启动服务器程序，达到在运行中修改的目的。</span><span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><br /></span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">    为了更好地描述<span lang="EN-US">KM3D</span>游戏引擎，可参照制作一个类似《暗黑<span lang="EN-US">2</span>》<span lang="EN-US">+</span>《魔兽世界》的网络游戏演示程序。该演示只在更加直观的说明游戏引擎所达到的一些效果。<span lang="EN-US"><br /></span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: 15pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left"><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><strong>道具</strong>：<span lang="EN-US"><br /></span>    全套模拟《暗黑<span lang="EN-US">2</span>》的道具机制，包括名称、属性以及掉落算法等。该部分有脚本生成，策划可以自由修改，哪怕是写错了，也不会造成服务停止。<span lang="EN-US"><br /></span>    基本道具书写参见<span lang="EN-US">Item.xls</span>文件<span lang="EN-US"><br /></span>    魔法技能参见<span lang="EN-US">spell.xls</span>文件<span lang="EN-US"><p /></span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: 15pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left"><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">    魔法属性和故事情节：<span lang="EN-US"><br /></span>    游戏服务器框架结构完全模仿《魔兽世界》，甚至是角色属性，法术技能也全部模拟。<span lang="EN-US"><br /></span>    故事情节构成也是由<span lang="EN-US">LUA</span>脚本<span lang="EN-US">+</span>经过处理后的<span lang="EN-US">Excel</span>文档构成，目前网络上流行的故事情节都能够做到。故事情节也可在线及时修改和添加，无需要重新启动服务程序。<span lang="EN-US"><p /></span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: 15pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left"><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: 15pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left"><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><strong>数据库</strong>：<span lang="EN-US"><br /></span>    后台数据库采用免费开源的轻量级数据库<span lang="EN-US">-MYSQL</span>。并且依照<span lang="EN-US">MYSQL</span>特性做了合适的设计，相信速度效率足以应付<span lang="EN-US">10</span>亿条信息。程序可以兼容使用<span lang="EN-US">Oracle</span>和<span lang="EN-US">MSSQL</span>数据库。<span lang="EN-US"><p /></span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: 15pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left"><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: 15pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left"><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><strong>整体服务器构建方案</strong>：<span lang="EN-US"><p /></span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: 15pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left"><span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><a href="http://www.gameking.com.cn/"><span style="COLOR: windowtext; TEXT-DECORATION: none; text-underline: none"><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"><stroke joinstyle="miter" /><formulas><f eqn="if lineDrawn pixelLineWidth 0" /><f eqn="sum @0 1 0" /><f eqn="sum 0 0 @1" /><f eqn="prod @2 1 2" /><f eqn="prod @3 21600 pixelWidth" /><f eqn="prod @3 21600 pixelHeight" /><f eqn="sum @0 0 1" /><f eqn="prod @6 1 2" /><f eqn="prod @7 21600 pixelWidth" /><f eqn="sum @8 21600 0" /><f eqn="prod @7 21600 pixelHeight" /><f eqn="sum @10 21600 0" /></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f" /><lock aspectratio="t" v:ext="edit" /></shapetype><shape id="_x0000_i1025" style="WIDTH: 405pt; HEIGHT: 319.5pt" o:button="t" type="#_x0000_t75"><imagedata o:href="http://www.gameking.com.cn/gk/zt/guanggao/img/biaoqian.gif" src="file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\msohtml1\01\clip_image001.png" /></shape></span></a><br /></span><span style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">    最少<span lang="EN-US">4</span>台服务器配置为<span lang="EN-US">1</span>组服务器，服务器结构采用<span lang="EN-US">Realmlist Server</span>，<span lang="EN-US">Login Server</span>，<span lang="EN-US">Game Center Server</span>以及<span lang="EN-US">SQL Server</span>构成。能够很好的解决网络带宽压力以及分布程序计算压力。详细参见服务器构建方案（该解决方案如有购买意向时提供）。该组服务器可以同时提供<span lang="EN-US">2048</span>个服务，每添加一台<span lang="EN-US">Realmlist</span>服务器，可增加<span lang="EN-US">2048</span>个连接，等等。当然提供更加多服务连接时候，需要相应的配置<span lang="EN-US">Game Center Server</span>的数量以及解决方案。<span lang="EN-US"><br /></span>以上各服务器最低配置为<span lang="EN-US">P4<chmetcnv w:st="on" unitname="g" sourcevalue="2.4" hasspace="False" negative="True" numbertype="1" tcsc="0">-2.4G</chmetcnv></span>单<span lang="EN-US">CPU</span>。其中<span lang="EN-US">Game Center Server</span>服务器配置需要根据游戏内容的复杂程度以及游戏程序编码</span></p></span><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="http://asoft.blogbus.com/logs/2355317.html">手机游戏编程</a> 2006-04-26</div><div><a href="http://asoft.blogbus.com/logs/1422351.html">C++游戏编程</a> 2005-09-09</div><div><a href="/logs/2303775.html">中国最让美不安的五种武器</a> 2006-04-20</div><div><a href="/logs/1429999.html">delphi中的流</a> 2005-09-12</div><div><a href="/logs/1429992.html">用JDOM处理XML文档</a> 2005-09-12</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fasoft.blogbus.com%2Flogs%2F2355337.html&title=KM3D%E5%BC%95%E6%93%8E%E5%8A%9F%E8%83%BD%E6%8F%8F%E8%BF%B0">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br /><br />]]></description>
   <link>http://asoft.blogbus.com/logs/2355337.html</link>
   <author></author>
   <pubDate>Wed, 26 Apr 2006 10:00:06 +0800</pubDate>
  </item>
  <item>
   <title>手机游戏编程</title>
   <description><![CDATA[<SPAN class=f14>手机就是一台网络计算机，基于手机的网络游戏将会成为IT最后的金矿.....</SPAN><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="http://asoft.blogbus.com/logs/2355337.html">KM3D引擎功能描述</a> 2006-04-26</div><div><a href="http://asoft.blogbus.com/logs/1422351.html">C++游戏编程</a> 2005-09-09</div><div><a href="/logs/2025994.html">java经典学习网站</a> 2006-03-09</div><div><a href="/logs/1429999.html">delphi中的流</a> 2005-09-12</div><div><a href="/logs/1429977.html">j2sdk1.4.0中bin目录下程序用法</a> 2005-09-12</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fasoft.blogbus.com%2Flogs%2F2355317.html&title=%E6%89%8B%E6%9C%BA%E6%B8%B8%E6%88%8F%E7%BC%96%E7%A8%8B">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br /><br />]]></description>
   <link>http://asoft.blogbus.com/logs/2355317.html</link>
   <author></author>
   <pubDate>Wed, 26 Apr 2006 09:54:13 +0800</pubDate>
  </item>
  <item>
   <title>中国最让美不安的五种武器</title>
   <description><![CDATA[中国最让美不安的五种武器<nobr><a class="iAs" oncontextmenu="function anonymous()
{
return false;
}" onmousemove="function anonymous()
{
kwM(8);
}" onmouseover="function anonymous()
{
kwE(event,8);
}" style="COLOR: #006699; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="function anonymous()
{
return kwC();
}" onmouseout="function anonymous()
{
kwL(event);
}" target="_blank">装备</a></nobr> <br /><br />中国的<nobr><a class="iAs" oncontextmenu="function anonymous()
{
return false;
}" onmousemove="function anonymous()
{
kwM(2);
}" onmouseover="function anonymous()
{
kwE(event,2);
}" style="COLOR: #006699; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="function anonymous()
{
return kwC();
}" onmouseout="function anonymous()
{
kwL(event);
}" target="_blank">军事</a></nobr>科学<nobr><a class="iAs" oncontextmenu="function anonymous()
{
return false;
}" onmousemove="function anonymous()
{
kwM(5);
}" onmouseover="function anonymous()
{
kwE(event,5);
}" style="COLOR: #006699; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="function anonymous()
{
return kwC();
}" onmouseout="function anonymous()
{
kwL(event);
}" target="_blank">技术</a></nobr>，有不少已经令美国军方发怵，台海战争一旦打响，这些军事<nobr><a class="iAs" oncontextmenu="function anonymous()
{
return false;
}" onmousemove="function anonymous()
{
kwM(7);
}" onmouseover="function anonymous()
{
kwE(event,7);
}" style="COLOR: #006699; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="function anonymous()
{
return kwC();
}" onmouseout="function anonymous()
{
kwL(event);
}" target="_blank">科学</a></nobr>技术就成为解放军克敌制胜的法宝，就是美军介入，也只能是自取其辱：<br /><br />一是大功率激光技术。据报道由哈尔滨工业大学、中国科学院院士马祖光研制的大功率激光武器已经装备部队，并且形成强大的战斗力，可以用来击毁来犯的导弹，包括太空中的GPS通讯卫星。只要把美国的GPS通讯卫星和预警卫星击毁，美国的所有导航设备就都变成聋子瞎子，所谓的信息战优势就荡然无存。<br /><br />二是飞行器小动量变轨技术。中国掌握的尖端技术，已经在&quot;神五&quot;飞船上<nobr><a class="iAs" oncontextmenu="function anonymous()
{
return false;
}" onmousemove="function anonymous()
{
kwM(4);
}" onmouseover="function anonymous()
{
kwE(event,4);
}" style="COLOR: #006699; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="function anonymous()
{
return kwC();
}" onmouseout="function anonymous()
{
kwL(event);
}" target="_blank">成功</a></nobr>使用。利用这一技术，中国的导弹可以在飞行中随意改变轨道，让对方的拦截导弹扑空。这样，美国的导弹拦截系统－&quot;天网&quot;（N<nobr><a class="iAs" oncontextmenu="function anonymous()
{
return false;
}" onmousemove="function anonymous()
{
kwM(0);
}" onmouseover="function anonymous()
{
kwE(event,0);
}" style="COLOR: #006699; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="function anonymous()
{
return kwC();
}" onmouseout="function anonymous()
{
kwL(event);
}" target="_blank">MD</a></nobr>－国家防御系统）就形同虚设。而且，美国的****的防空系统，也无法对付装备小动量变轨技术的中国地对舰或者空对舰导弹的攻击。<br /><br />三是多弹头重入大气层分导技术。一个洲际导弹，可以带3～5个核弹头，在进入大气层时分导瞄准不同的战略目标。中国多次发射一箭<nobr><a class="iAs" oncontextmenu="function anonymous()
{
return false;
}" onmousemove="function anonymous()
{
kwM(3);
}" onmouseover="function anonymous()
{
kwE(event,3);
}" style="COLOR: #006699; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="function anonymous()
{
return kwC();
}" onmouseout="function anonymous()
{
kwL(event);
}" target="_blank">双星</a></nobr>、一箭<nobr><a class="iAs" oncontextmenu="function anonymous()
{
return false;
}" onmousemove="function anonymous()
{
kwM(1);
}" onmouseover="function anonymous()
{
kwE(event,1);
}" style="COLOR: #006699; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="function anonymous()
{
return kwC();
}" onmouseout="function anonymous()
{
kwL(event);
}" target="_blank">三星</a></nobr>的大功率<nobr><a class="iAs" oncontextmenu="function anonymous()
{
return false;
}" onmousemove="function anonymous()
{
kwM(6);
}" onmouseover="function anonymous()
{
kwE(event,6);
}" style="COLOR: #006699; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="function anonymous()
{
return kwC();
}" onmouseout="function anonymous()
{
kwL(event);
}" target="_blank">火箭</a></nobr>，以及卫星回收试验，而且每次都获得成功，说明中国的这项技术已经相当成熟。<br /><br />四是导弹核潜艇水下发射技术。也被称为第二次核打击力量，在所有陆基导弹发射系统全部被敌人摧毁的情况下，只要有一艘导弹核潜艇潜伏在水下，就可以实施核报复，12个导弹从水下近距离发射，每个导弹带3～5个核弹头，可以把敌方大部分战略目标摧毁。<br /><br />五是潜艇超静定技术。利用目前的反潜探测设备都无法测出潜伏在水下的我国超静定潜艇，中国潜艇在**公海潜伏多日，却没有被发现，直到潜艇浮出水面才大吃一惊，实际上是给**和美国一个警告，是一种***.<!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="/logs/2355337.html">KM3D引擎功能描述</a> 2006-04-26</div><div><a href="/logs/2025935.html">Java行业的圣经</a> 2006-03-09</div><div><a href="/logs/1429999.html">delphi中的流</a> 2005-09-12</div><div><a href="/logs/1429991.html">java连接access数据库</a> 2005-09-12</div><div><a href="/logs/1429970.html">HTTP协议状态码的含义</a> 2005-09-12</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fasoft.blogbus.com%2Flogs%2F2303775.html&title=%E4%B8%AD%E5%9B%BD%E6%9C%80%E8%AE%A9%E7%BE%8E%E4%B8%8D%E5%AE%89%E7%9A%84%E4%BA%94%E7%A7%8D%E6%AD%A6%E5%99%A8">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br /><br />]]></description>
   <link>http://asoft.blogbus.com/logs/2303775.html</link>
   <author></author>
   <pubDate>Thu, 20 Apr 2006 12:09:23 +0800</pubDate>
  </item>
  <item>
   <title>java经典学习网站</title>
   <description><![CDATA[java经典学习网站<!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="http://asoft.blogbus.com/logs/2025935.html">Java行业的圣经</a> 2006-03-09</div><div><a href="http://asoft.blogbus.com/logs/1429977.html">j2sdk1.4.0中bin目录下程序用法</a> 2005-09-12</div><div><a href="/logs/2355337.html">KM3D引擎功能描述</a> 2006-04-26</div><div><a href="/logs/2355317.html">手机游戏编程</a> 2006-04-26</div><div><a href="/logs/1429991.html">java连接access数据库</a> 2005-09-12</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fasoft.blogbus.com%2Flogs%2F2025994.html&title=java%E7%BB%8F%E5%85%B8%E5%AD%A6%E4%B9%A0%E7%BD%91%E7%AB%99">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br /><br />]]></description>
   <link>http://asoft.blogbus.com/logs/2025994.html</link>
   <author></author>
   <pubDate>Thu, 09 Mar 2006 11:05:04 +0800</pubDate>
  </item>
  <item>
   <title>Java行业的圣经</title>
   <description><![CDATA[<P>《Design patterns》</P>
<P>《Refactoring: Improving the Design of Existing Code》</P>
<P>《AntiPatterns: Refactoring Software, Architectures, and Projects in Crisis》</P>
<P>《Extreme Programming Explained: Embrace Change》</P><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="http://asoft.blogbus.com/logs/2025994.html">java经典学习网站</a> 2006-03-09</div><div><a href="http://asoft.blogbus.com/logs/1429977.html">j2sdk1.4.0中bin目录下程序用法</a> 2005-09-12</div><div><a href="/logs/2355337.html">KM3D引擎功能描述</a> 2006-04-26</div><div><a href="/logs/2355317.html">手机游戏编程</a> 2006-04-26</div><div><a href="/logs/1429991.html">java连接access数据库</a> 2005-09-12</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fasoft.blogbus.com%2Flogs%2F2025935.html&title=Java%E8%A1%8C%E4%B8%9A%E7%9A%84%E5%9C%A3%E7%BB%8F">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br /><br />]]></description>
   <link>http://asoft.blogbus.com/logs/2025935.html</link>
   <author></author>
   <pubDate>Thu, 09 Mar 2006 10:58:14 +0800</pubDate>
  </item>
  <item>
   <title>delphi中的流</title>
   <description><![CDATA[<p>        什么是流？流,简单来说就是建立在面向对象基础上的一种抽象的处理数据的工具。在流中，定义了一些处理数据的基本操作，如读取数据，写入数据等，程序员是对流进行所有操作的，而不用关心流的另一头数据的真正流向。流不但可以处理文件，还可以处理动态内存、网络数据等多种数据形式。如果你对流的操作非常熟练，在程序中利用流的方便性，写起程序会大大提高效率的。<br />  下面，笔者通过四个实例:EXE文件加密器、电子贺卡、自制OICQ和网络屏幕传输来说明Delphi编程中“流”的利用。这些例子中的一些技巧曾经是很多软件的秘密而不公开的，现在大家可以无偿的直接引用其中的代码了。<br />  “万丈高楼平地起”，在分析实例之前，我们先来了解一下流的基本概念和函数，只有在理解了这些基本的东西后我们才能进行下一步。请务必认真领会这些基本方法。当然，如果你对它们已经很熟悉了，则可以跳过这一步。</p><p>一、Delphi中流的基本概念及函数声明<br />在Delphi中，所有流对象的基类为TStream类，其中定义了所有流的共同属性和方法。<br />TStream类中定义的属性介绍如下：<br />1、Size:此属性以字节返回流中数据大小。<br />2、Position:此属性控制流中存取指针的位置。<br />Tstream中定义的虚方法有四个：<br />1、Read:此方法实现将数据从流中读出。函数原形为：<br />Function Read(var Buffer;Count:Longint):Longint;virtual;abstract;<br />参数Buffer为数据读出时放置的缓冲区，Count为需要读出的数据的字节数，该方法返回值为实际读出的字节数，它可以小于或等于Count中指定的值。<br />2、Write:此方法实现将数据写入流中。函数原形为：<br />Function Write(var Buffer;Count:Longint):Longint;virtual;abstract;<br />参数Buffer为将要写入流中的数据的缓冲区，Count为数据的长度字节数，该方法返回值为实际写入流中的字节数。<br />3、Seek:此方法实现流中读取指针的移动。函数原形为：<br />Function Seek(Offset:Longint;Origint:Word):Longint;virtual;abstract;<br />参数Offset为偏移字节数,参数Origint指出Offset的实际意义，其可能的取值如下：<br />soFromBeginning:Offset为移动后指针距离数据开始的位置。此时Offset必须大于或者等于零。<br />soFromCurrent:Offset为移动后指针与当前指针的相对位置。<br />soFromEnd:Offset为移动后指针距离数据结束的位置。此时Offset必须小于或者等于零。该方法返回值为移动后指针的位置。<br />4、Setsize:此方法实现改变数据的大小。函数原形为：<br />Function Setsize(NewSize:Longint);virtual;<br />另外，TStream类中还定义了几个静态方法：<br />1、ReadBuffer:此方法的作用是从流中当前位置读取数据。函数原形为：<br />Procedure ReadBuffer(var Buffer;Count:Longint);<br />参数的定义跟上面的Read相同。注意：当读取的数据字节数与需要读取的字节数不相同时，将产生EReadError异常。<br />2、WriteBuffer:此方法的作用是在当前位置向流写入数据。函数原形为：<br />Procedure WriteBuffer(var Buffer;Count:Longint);<br />参数的定义跟上面的Write相同。注意：当写入的数据字节数与需要写入的字节数不相同时，将产生EWriteError异常。<br />3、CopyFrom:此方法的作用是从其它流中拷贝数据流。函数原形为：<br />Function CopyFrom(Source:TStream;Count:Longint):Longint;<br />参数Source为提供数据的流，Count为拷贝的数据字节数。当Count大于0时，CopyFrom从Source参数的当前位置拷贝Count个字节的数据；当Count等于0时，CopyFrom设置Source参数的Position属性为0,然后拷贝Source的所有数据；<br />TStream还有其它派生类，其中最常用的是TFileStream类。使用TFileStream类来存取文件，首先要建立一个实例。声明如下：<br />constructor Create(const Filename:string;Mode:Word);<br />Filename为文件名（包括路径）,参数Mode为打开文件的方式，它包括文件的打开模式和共享模式，其可能的取值和意义如下：</p><p>打开模式：<br />fmCreate :用指定的文件名建立文件，如果文件已经存在则打开它。<br />fmOpenRead :以只读方式打开指定文件<br />fmOpenWrite :以只写方式打开指定文件<br />fmOpenReadWrite:以写写方式打开指定文件<br />共享模式：<br />fmShareCompat :共享模式与FCBs兼容<br />fmShareExclusive:不允许别的程序以任何方式打开该文件<br />fmShareDenyWrite:不允许别的程序以写方式打开该文件<br />fmShareDenyRead :不允许别的程序以读方式打开该文件<br />fmShareDenyNone :别的程序可以以任何方式打开该文件</p><p>TStream还有一个派生类TMemoryStream，实际应用中用的次数也非常频繁。它叫内存流，就是说在内存中建立一个流对象。它的基本方法和函数跟上面是一样的。<br />好了，有了上面的基础后，我们就可以开始我们的编程之行了。<br />-----------------------------------------------------------------------<br />二、实际应用之一：利用流制作EXE文件加密器、捆绑、自解压文件及安装程序</p><p>  我们先来说一下如何制作一个EXE文件加密器吧。 <br />  EXE文件加密器的原理：建立两个文件，一个用来添加资源到另外一个EXE文件里面，称为添加程序。另外一个被添加的EXE文件称为头文件。该程序的功能是把添加到自己里面的文件读出来。Windows下的EXE文件结构比较复杂，有的程序还有校验和，当发现自己被改变后会认为自己被病毒感染而拒绝执行。所以我们把文件添加到自己的程序里面，这样就不会改变原来的文件结构了。我们先写一个添加函数，该函数的功能是把一个文件当作一个流添加到另外一个文件的尾部。函数如下：</p><p>Function Cjt_AddtoFile(SourceFile,TargetFile:string):Boolean;<br />var<br />Target,Source:TFileStream;<br />MyFileSize:integer;<br />begin<br />try<br />Source:=TFileStream.Create(SourceFile,fmOpenRead or fmShareExclusive);<br />Target:=TFileStream.Create(TargetFile,fmOpenWrite or fmShareExclusive);<br />try<br />Target.Seek(0,soFromEnd);//往尾部添加资源<br />Target.CopyFrom(Source,0);<br />MyFileSize:=Source.Size+Sizeof(MyFileSize);//计算资源大小，并写入辅程尾部<br />Target.WriteBuffer(MyFileSize,sizeof(MyFileSize));<br />finally<br />Target.Free;<br />Source.Free;<br />end;<br />except<br />Result:=False;<br />Exit;<br />end;<br />Result:=True;<br />end;<br />有了上面的基础，我们应该很容易看得懂这个函数。其中参数SourceFile是要添加的文件,参数TargetFile是被添加到的目标文件。比如说把a.exe添加到b.exe里面可以：Cjt_AddtoFile('a.exe',b.exe');如果添加成功就返回True否则返回假。<br />根据上面的函数我们可以写出相反的读出函数：<br />Function Cjt_LoadFromFile(SourceFile,TargetFile :string):Boolean;<br />var<br />Source:TFileStream;<br />Target:TMemoryStream;<br />MyFileSize:integer;<br />begin<br />try<br />Target:=TMemoryStream.Create;<br />Source:=TFileStream.Create(SourceFile,fmOpenRead or fmShareDenyNone);<br />try<br />Source.Seek(-sizeof(MyFileSize),soFromEnd);<br />Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));//读出资源大小<br />Source.Seek(-MyFileSize,soFromEnd);//定位到资源位置<br />Target.CopyFrom(Source,MyFileSize-sizeof(MyFileSize));//取出资源<br />Target.SaveToFile(TargetFile);//存放到文件<br />finally<br />Target.Free;<br />Source.Free;<br />end;<br />except<br />Result:=false;<br />Exit;<br />end;<br />Result:=true;<br />end;<br />  其中参数SourceFile是已经添加了文件的文件名称,参数TargetFile是取出文件后保存的目标文件名。比如说Cjt_LoadFromFile('b.exe','a.txt');在b.exe中取出文件保存为a.txt。如果取出成功就返回True否则返回假。<br />打开Delphi，新建一个工程，在窗口上放上一个Edit控件Edit1和两个Button:Button1和Button2。Button的Caption属性分别设置为“确定”和“取消”。在Button1的Click事件中写代码:<br />var S:string;<br />begin<br />S:=ChangeFileExt(Application.ExeName,'.Cjt');<br />if Edit1.Text='790617' then <br />begin<br />Cjt_LoadFromFile(Application.ExeName,S);<br />{取出文件保存在当前路径下并命名&quot;原文件.Cjt&quot;}<br />Winexec(pchar(S),SW_Show);{运行&quot;原文件.Cjt&quot;}<br />Application.Terminate;{退出程序}<br />end<br />else <br />Application.MessageBox('密码不对,请重新输入！','密码错误',MB_ICONERROR+MB_OK);<br />  编译这个程序，并把EXE文件改名为head.exe。新建一个文本文件head.rc,内容为: head exefile head.exe,然后把它们拷贝到Delphi的BIN目录下，执行Dos命令Brcc32.exe head.rc,将产生一个head.res的文件，这个文件就是我们要的资源文件，先留着。<br />  我们的头文件已经建立了，下面我们来建立添加程序。<br />  新建一个工程，放上以下控件：一个Edit,一个Opendialog,两个Button1的Caption属性分别设置为&quot;选择文件&quot;和&quot;加密&quot;。在源程序中添加一句:{$R head.res}并把head.res文件拷贝到程序当前目录下。这样一来就把刚才的head.exe跟程序一起编译了。<br />  在Button1的Cilck事件里面写下代码：<br />if OpenDialog1.Execute then Edit1.Text:=OpenDialog1.FileName;<br />  在Button2的Cilck事件里面写下代码：<br />var S:String;<br />begin<br />S:=ExtractFilePath(Edit1.Text);<br />if ExtractRes('exefile','head',S+'head.exe') then<br />if Cjt_AddtoFile(Edit1.Text,S+'head.exe') then<br />if DeleteFile(Edit1.Text) then<br />if RenameFile(S+'head.exe',Edit1.Text) then<br />Application.MessageBox('文件加密成功!','信息',MB_ICONINFORMATION+MB_OK)<br />else<br />begin<br />if FileExists(S+'head.exe') then DeleteFile(S+'head.exe');<br />Application.MessageBox('文件加密失败!','信息',MB_ICONINFORMATION+MB_OK)<br />end;<br />end;<br />其中ExtractRes为自定义函数，它的作用是把head.exe从资源文件中取出来。<br />Function ExtractRes(ResType, ResName, ResNewName : String):boolean;<br />var<br />Res : TResourceStream;<br />begin<br />try<br />Res := TResourceStream.Create(Hinstance, Resname, Pchar(ResType));<br />try<br />Res.SavetoFile(ResNewName);<br />Result:=true;<br />finally<br />Res.Free;<br />end;<br />except<br />Result:=false;<br />end;<br />end;<br />   注意：我们上面的函数只不过是简单的把一个文件添加到另一个文件的尾部。实际应用中可以改成可以添加多个文件，只要根据实际大小和个数定义好偏移地址就可以了。比如说文件捆绑机就是把两个或者多个程序添加到一个头文件里面。那些自解压程序和安装程序的原理也是一样的，不过多了压缩而已。比如说我们可以引用一个LAH单元，把流压缩后再添加，这样文件就会变的很小。读出来时先解压就可以了。另外，文中EXE加密器的例子还有很多不完善的地方，比如说密码固定为&quot;790617&quot;，取出EXE运行后应该等它运行完毕后删除等等，读者可以自行修改。</p><p>---------------------------------------------------------------------<br />三、实际应用之二：利用流制作可执行电子贺卡</p><p>  我们经常看到一些电子贺卡之类的制作软件，可以让你自己选择图片，然后它会生成一个EXE可执行文件给你。打开贺卡时就会一边放音乐一边显示出图片来。现在学了流操作之后，我们也可以做一个了。 <br />  添加图片过程我们可以直接用前面的Cjt_AddtoFile，而现在要做的是如何把图像读出并显示。我们用前面的Cjt_LoadFromFile先把图片读出来保存为文件再调入也是可以的，但是还有更简单的方法，就是直接把文件流读出来显示，有了流这个利器，一切都变的简单了。<br />  现在的图片比较流行的是BMP格式和JPG格式。我们现在就针对这两种图片写出读取并显示函数。</p><p>Function Cjt_BmpLoad(ImgBmp:TImage;SourceFile:String):Boolean;<br />var<br />Source:TFileStream;<br />MyFileSize:integer;<br />begin<br />Source:=TFileStream.Create(SourceFile,fmOpenRead or fmShareDenyNone);<br />try<br />try<br />Source.Seek(-sizeof(MyFileSize),soFromEnd);<br />Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));//读出资源<br />Source.Seek(-MyFileSize,soFromEnd);//定位到资源开始位置<br />ImgBmp.Picture.Bitmap.LoadFromStream(Source);<br />finally<br />Source.Free;<br />end;<br />except<br />Result:=False;<br />Exit;<br />end;<br />Result:=True;<br />end;<br />  上面是读出BMP图片的，下面的是读出JPG图片的函数，因为要用到JPG单元，所以要在程序中添加一句:uses jpeg。</p><p>Function Cjt_JpgLoad(JpgImg:Timage;SourceFile:String):Boolean;<br />var<br />Source:TFileStream;<br />MyFileSize:integer;<br />Myjpg: TJpegImage;<br />begin<br />try<br />Myjpg:= TJpegImage.Create;<br />Source:=TFileStream.Create(SourceFile,fmOpenRead or fmShareDenyNone);<br />try<br />Source.Seek(-sizeof(MyFileSize),soFromEnd);<br />Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));<br />Source.Seek(-MyFileSize,soFromEnd);<br />Myjpg.LoadFromStream(Source);<br />JpgImg.Picture.Bitmap.Assign(Myjpg);<br />finally<br />Source.Free;<br />Myjpg.free;<br />end;<br />except<br />Result:=false;<br />Exit;<br />end;<br />Result:=true;<br />end;<br />  有了这两个函数，我们就可以制作读出程序了。下面我们以BMP图片为例：<br />  运行Delphi，新建一个工程，放上一个显示图像控件Image1。在窗口的Create事件中写上一句就可以了：<br />Cjt_BmpLoad(Image1,Application.ExeName);<br />  这个就是头文件了，然后我们用前面的方法生成一个head.res资源文件。<br />下面就可以开始制作我们的添加程序了。全部代码如下：<br />unit Unit1;</p><p>interface</p><p>uses<br />Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br />ExtCtrls, StdCtrls, ExtDlgs;</p><p>type<br />TForm1 = class(TForm)<br />Edit1: TEdit;<br />Button1: TButton;<br />Button2: TButton;<br />OpenPictureDialog1: TOpenPictureDialog;<br />procedure FormCreate(Sender: TObject);<br />procedure Button1Click(Sender: TObject);<br />procedure Button2Click(Sender: TObject);<br />private<br />Function ExtractRes(ResType, ResName, ResNewName : String):boolean;<br />Function Cjt_AddtoFile(SourceFile,TargetFile:string):Boolean;<br />{ Private declarations }<br />public<br />{ Public declarations }<br />end;</p><p>var<br />Form1: TForm1;</p><p>implementation</p><p>{$R *.DFM}<br />Function TForm1.ExtractRes(ResType, ResName, ResNewName : String):boolean;<br />var<br />Res : TResourceStream;<br />begin<br />try<br />Res := TResourceStream.Create(Hinstance, Resname, Pchar(ResType));<br />try<br />Res.SavetoFile(ResNewName);<br />Result:=true;<br />finally<br />Res.Free;<br />end;<br />except<br />Result:=false;<br />end;<br />end;<br />Function TForm1.Cjt_AddtoFile(SourceFile,TargetFile:string):Boolean;<br />var<br />Target,Source:TFileStream;<br />MyFileSize:integer;<br />begin<br />try<br />Source:=TFileStream.Create(SourceFile,fmOpenRead or fmShareExclusive);<br />Target:=TFileStream.Create(TargetFile,fmOpenWrite or fmShareExclusive);<br />try<br />Target.Seek(0,soFromEnd);//往尾部添加资源<br />Target.CopyFrom(Source,0);<br />MyFileSize:=Source.Size+Sizeof(MyFileSize);//计算资源大小，并写入辅程尾部<br />Target.WriteBuffer(MyFileSize,sizeof(MyFileSize));<br />finally<br />Target.Free;<br />Source.Free;<br />end;<br />except<br />Result:=False;<br />Exit;<br />end;<br />Result:=True;<br />end;<br />procedure TForm1.FormCreate(Sender: TObject);<br />begin<br />Caption:='Bmp2Exe演示程序.作者:陈经韬';<br />Edit1.Text:='';<br />OpenPictureDialog1.DefaultExt := GraphicExtension(TBitmap);<br />OpenPictureDialog1.Filter := GraphicFilter(TBitmap);</p><p>Button1.Caption:='选择BMP图片';<br />Button2.Caption:='生成EXE';<br />end;</p><p>procedure TForm1.Button1Click(Sender: TObject);<br />begin<br />if OpenPictureDialog1.Execute then<br />Edit1.Text:=OpenPictureDialog1.FileName;<br />end;</p><p>procedure TForm1.Button2Click(Sender: TObject);<br />var<br />HeadTemp:String;<br />begin<br />if Not FileExists(Edit1.Text) then<br />begin<br />Application.MessageBox('BMP图片文件不存在，请重新选择!','信息',MB_ICONINFORMATION+MB_OK)<br />Exit;<br />end;<br />HeadTemp:=ChangeFileExt(Edit1.Text,'.exe');<br />if ExtractRes('exefile','head',HeadTemp) then<br />if Cjt_AddtoFile(Edit1.Text,HeadTemp) then<br />Application.MessageBox('EXE文件生成成功!','信息',MB_ICONINFORMATION+MB_OK)<br />else<br />begin<br />if FileExists(HeadTemp) then DeleteFile(HeadTemp);<br />Application.MessageBox('EXE文件生成失败!','信息',MB_ICONINFORMATION+MB_OK)<br />end;<br />end;<br />end.<br />  怎么样？很神奇吧:)把程序界面弄的漂亮点，再添加一些功能，你会发现比起那些要注册的软件来也不会逊多少吧。<br />-----------------------------------------------------------------------<br />实际应用之三：利用流制作自己的OICQ</p><p>  OICQ是深圳腾讯公司的一个网络实时通讯软件，在国内拥有大量的用户群。但OICQ必须连接上互联网登陆到腾讯的服务器才能使用。所以我们可以自己写一个在局部网里面使用。<br />  OICQ使用的是UDP协议，这是一种无连接协议，即通信双方不用建立连接就可以发送信息，所以效率比较高。Delphi本身自带的FastNEt公司的NMUDP控件就是一个UDP协议的用户数据报控件。不过要注意的是如果你使用了这个控件必须退出程序才能关闭计算机，因为TNMXXX控件有BUG。所有nm控件的基础 PowerSocket用到的ThreadTimer，用到一个隐藏的窗口（类为TmrWindowClass）处理有硬伤。<br />出问题的地方：<br />Psock::TThreadTimer::WndProc(var msg:TMessage)<br />if msg.message=WM_TIMER then<br />他自己处理<br />msg.result:=0<br />else<br />msg.result:=DefWindowProc(0,....)<br />end <br />  问题就出在调用 DefWindowProc时，传输的HWND参数居然是常数0，这样实际上DefWindowProc是不能工作的，对任何输入的消息的调用均返回0，包括WM_QUERYENDSESSION，所以不能退出windows。由于DefWindowProc的不正常调用，实际上除WM_TIMER，其他消息由DefWindowProc处理都是无效的。<br />解决的办法是在 PSock.pas<br />在 TThreadTimer.Wndproc 内<br />Result := DefWindowProc( 0, Msg, WPARAM, LPARAM );<br />改为：<br />Result := DefWindowProc( FWindowHandle, Msg, WPARAM, LPARAM );<br />  早期低版本的OICQ也有这个问题，如果不关闭OICQ的话，关闭计算机时屏幕闪了一下又返回了。<br />  好了，废话少说，让我们编写我们的OICQ吧,这个实际上是Delphi自带的例子而已:)<br />  新建一个工程，在FASTNET面版拖一个NMUDP控件到窗口，然后依次放上三个EDIT,名字分别为EditIP、EditPort、EditMyTxt，三个按钮BtSend、BtClear、BtSave，一个MEMOMemoReceive，一个SaveDialog和一个状态条StatusBar1。当用户点击BtSend时，建立一个内存流对象，把要发送的文字信息写进内存流，然后NMUDP把流发送出去。当NMUDP有数据接收时，触发它的DataReceived事件，我们在这里再把接收到的流转换为字符信息，然后显示出来。<br />  注意：所有的流对象建立后使用完毕后要记得释放(Free)，其实它的释构函数应该为Destroy，但如果建立流失败的话，用Destroy会产生异常，而用Free的话程序会先检查有没有成功建立了流，如果建立了才释放，所以用Free比较安全。<br />  在这个程序中我们用到了NMUDP控件，它有几个重要的属性。RemoteHost表示远程电脑的IP或者计算机名，LocalPort是本地端口，主要监听有没有数据传入。而RemotePort是远程端口，发送数据时通过这个端口把数据发送出去。理解这些已经可以看懂我们的程序了。</p><p>全部代码如下：<br />unit Unit1;</p><p>interface</p><p>uses<br />Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls, ComCtrls,NMUDP;</p><p>type<br />TForm1 = class(TForm)<br />NMUDP1: TNMUDP;<br />EditIP: TEdit;<br />EditPort: TEdit;<br />EditMyTxt: TEdit;<br />MemoReceive: TMemo; <br />BtSend: TButton;<br />BtClear: TButton;<br />BtSave: TButton;<br />StatusBar1: TStatusBar; <br />SaveDialog1: TSaveDialog;<br />procedure BtSendClick(Sender: TObject);<br />procedure NMUDP1DataReceived(Sender: TComponent; NumberBytes: Integer;<br />FromIP: String; Port: Integer);<br />procedure NMUDP1InvalidHost(var handled: Boolean);<br />procedure NMUDP1DataSend(Sender: TObject);<br />procedure FormCreate(Sender: TObject);<br />procedure BtClearClick(Sender: TObject);<br />procedure BtSaveClick(Sender: TObject);<br />procedure EditMyTxtKeyPress(Sender: TObject; var Key: Char);<br />private<br />{ Private declarations }<br />public<br />{ Public declarations }<br />end;</p><p>var<br />Form1: TForm1;</p><p>implementation</p><p>{$R *.DFM}</p><p>procedure TForm1.BtSendClick(Sender: TObject);<br />var<br />MyStream: TMemoryStream;<br />MySendTxt: String;<br />Iport,icode:integer;<br />Begin<br />Val(EditPort.Text,Iport,icode);<br />if icode&lt;&gt;0 then<br />begin<br />Application.MessageBox('端口必须为数字，请重新输入!','信息',MB_ICONINFORMATION+MB_OK);<br />Exit;<br />end;<br />NMUDP1.RemoteHost := EditIP.Text; {远程主机}<br />NMUDP1.LocalPort:=Iport; {本地端口}<br />NMUDP1.RemotePort := Iport; {远程端口}<br />MySendTxt := EditMyTxt.Text;<br />MyStream := TMemoryStream.Create; {建立流}<br />try<br />MyStream.Write(MySendTxt[1], Length(EditMyTxt.Text));{写数据}<br />NMUDP1.SendStream(MyStream); {发送流}<br />finally<br />MyStream.Free; {释放流}<br />end;<br />end;</p><p><br />procedure TForm1.NMUDP1DataReceived(Sender: TComponent;<br />NumberBytes: Integer; FromIP: String; Port: Integer);<br />var<br />MyStream: TMemoryStream;<br />MyReciveTxt: String;<br />begin<br />MyStream := TMemoryStream.Create; {建立流}<br />try<br />NMUDP1.ReadStream(MyStream);{接收流}<br />SetLength(MyReciveTxt,NumberBytes);{NumberBytes为接收到的字节数}<br />MyStream.Read(MyReciveTxt[1],NumberBytes);{读数据}<br />MemoReceive.Lines.Add('接收到来自主机'+FromIP+'的信息:'+MyReciveTxt);<br />finally<br />MyStream.Free; {释放流}<br />end;<br />end;</p><p>procedure TForm1.NMUDP1InvalidHost(var handled: Boolean);<br />begin<br />Application.MessageBox('对方IP地址不正确，请重新输入!','信息',MB_ICONINFORMATION+MB_OK);<br />end;</p><p>procedure TForm1.NMUDP1DataSend(Sender: TObject);<br />begin<br />StatusBar1.SimpleText:='信息成功发出!';<br />end;</p><p>procedure TForm1.FormCreate(Sender: TObject);<br />begin<br />EditIP.Text:='127.0.0.1';<br />EditPort.Text:='8868';<br />BtSend.Caption:='发送';<br />BtClear.Caption:='清除聊天记录';<br />BtSave.Caption:='保存聊天记录';<br />MemoReceive.ScrollBars:=ssBoth;<br />MemoReceive.Clear;<br />EditMyTxt.Text:='在这里输入信息,然后点击发送.';</p><p>StatusBar1.SimplePanel:=true;<br />end;</p><p>procedure TForm1.BtClearClick(Sender: TObject);<br />begin<br />MemoReceive.Clear;<br />end;</p><p>procedure TForm1.BtSaveClick(Sender: TObject);<br />begin<br />if SaveDialog1.Execute then MemoReceive.Lines.SaveToFile(SaveDialog1.FileName);<br />end;</p><p>procedure TForm1.EditMyTxtKeyPress(Sender: TObject; var Key: Char);<br />begin<br />if Key=#13 then BtSend.Click;<br />end;<br />end.<br />  上面的程序跟OICQ相比当然差之甚远，因为OICQ利用的是Socket5通信方式。它上线时先从服务器取回好友信息和在线状态，发送超时还会将信息先保存在服务器，等对方下次上线后再发送然后把服务器的备份删除。你可以根据前面学的概念来完善这个程序，比如说再添加一个NMUDP控件来管理在线状态，发送的信息先转换成ASCII码进行与或运行并加上一个头信息，接收方接收信息后先判断信息头正确与否，如果正确才把信息解密显示出来，这样就提高了安全保密性。<br />  另外，UDP协议还有一个很大的好处就是可以广播，就是说处于一个网段的都可以接收到信息而不必指定具体的IP地址。网段一般分A、B、C三类,<br />1~126.XXX.XXX.XXX (A类网) :广播地址为XXX.255.255.255<br />128~191.XXX.XXX.XXX(B类网):广播地址为XXX.XXX.255.255<br />192~254.XXX.XXX.XXX(C类网):广播地址为XXX.XXX.XXX.255<br />  比如说三台计算机192.168.0.1、192.168.0.10、192.168.0.18，发送信息时只要指定IP地址为192.168.0.255就可以实现广播了。下面给出一个转换IP为广播IP的函数，快拿去完善自己的OICQ吧^-^.</p><p>Function Trun_ip(S:string):string;<br />var s1,s2,s3,ss,sss,Head:string;<br />n,m:integer;<br />begin<br />sss:=S;<br />n:=pos('.',s);<br />s1:=copy(s,1,n);<br />m:=length(s1);<br />delete(s,1,m);<br />Head:=copy(s1,1,(length(s1)-1));<br />n:=pos('.',s);<br />s2:=copy(s,1,n);<br />m:=length(s2);<br />delete(s,1,m);<br />n:=pos('.',s);<br />s3:=copy(s,1,n);<br />m:=length(s3);<br />delete(s,1,m);<br />ss:=sss;<br />if strtoint(Head) in [1..126] then ss:=s1+'255.255.255'; //1~126.255.255.255 (A类网)<br />if strtoint(Head) in [128..191] then ss:=s1+s2+'255.255';//128~191.XXX.255.255(B类网)<br />if strtoint(Head) in [192..254] then ss:=s1+s2+s3+'255'; //192~254.XXX.XXX.255(C类网)<br />Result:=ss; <br />end;</p><p>-----------------------------------------------------------------------<br />五、实际应用之四：利用流实现网络传输屏幕图像</p><p>  大家应该见过很多网管程序，这类程序其中有一个功能就是监控远程电脑的屏幕。实际上，这也是利用流操作来实现的。下面我们给出一个例子，这个例子分两个程序，一个服务端，一个是客户端。程序编译后可以直接在单机、局部网或者互联网上使用。程序中已经给出相应注释。后面我们再来作具体分析。<br />  新建一个工程，在Internet面版上拖一个ServerSocket控件到窗口，该控件主要用于监听客户端，用来与客户端建立连接和通讯。设置好监听端口后调用方法Open或者Active:=True即开始工作。注意：跟前面的NMUDP不同，当Socket开始监听后就不能再改变它的端口，要改变的话必须先调用Close或设置Active为False，否则将会产生异常。另外，如果该端口已经打开的话，就不能再用这个端口了。所以程序运行尚未退出就不能再运行这个程序，否则也会产生异常，即弹出出错窗口。实际应用中可以通过判断程序是否已经运行，如果已经运行就退出的方法来避免出错。<br />  当客户端有数据传入，将触发ServerSocket1ClientRead事件，我们可以在这里对接收的数据进行处理。在本程序中，主要是接收客户端发送过来的字符信息并根据事先的约定来进行相应操作。<br />程序全部代码如下：</p><p>unit Unit1;{服务端程序}<br />interface<br />uses<br />Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, JPEG,ExtCtrls, ScktComp;<br />type<br />TForm1 = class(TForm)<br />ServerSocket1: TServerSocket;<br />procedure ServerSocket1ClientRead(Sender: TObject;Socket: TCustomWinSocket);<br />procedure FormCreate(Sender: TObject);<br />procedure FormClose(Sender: TObject; var Action: TCloseAction);<br />private<br />procedure Cjt_GetScreen(var Mybmp: TBitmap; DrawCur: Boolean);<br />{自定义抓屏函数,DrawCur表示抓鼠标图像与否}<br />{ Private declarations }<br />public<br />{ Public declarations }<br />end;<br />var<br />Form1: TForm1;<br />MyStream: TMemorystream;{内存流对象} <br />implementation<br />{$R *.DFM}<br />procedure TForm1.Cjt_GetScreen(var Mybmp: TBitmap; DrawCur: Boolean);<br />var<br />Cursorx, Cursory: integer;<br />dc: hdc;<br />Mycan: Tcanvas;<br />R: TRect;<br />DrawPos: TPoint;<br />MyCursor: TIcon;<br />hld: hwnd;<br />Threadld: dword;<br />mp: tpoint;<br />pIconInfo: TIconInfo;<br />begin<br />Mybmp := Tbitmap.Create; {建立BMPMAP }<br />Mycan := TCanvas.Create; {屏幕截取}<br />dc := GetWindowDC(0);<br />try<br />Mycan.Handle := dc;<br />R := Rect(0, 0, screen.Width, screen.Height);<br />Mybmp.Width := R.Right;<br />Mybmp.Height := R.Bottom;<br />Mybmp.Canvas.CopyRect(R, Mycan, R);<br />finally<br />releaseDC(0, DC);<br />end;<br />Mycan.Handle := 0;<br />Mycan.Free;<br />if DrawCur then {画上鼠标图象}<br />begin<br />GetCursorPos(DrawPos);<br />MyCursor := TIcon.Create;<br />getcursorpos(mp);<br />hld := WindowFromPoint(mp);<br />Threadld := GetWindowThreadProcessId(hld, nil);<br />AttachThreadInput(GetCurrentThreadId, Threadld, True);<br />MyCursor.Handle := Getcursor();<br />AttachThreadInput(GetCurrentThreadId, threadld, False);<br />GetIconInfo(Mycursor.Handle, pIconInfo);<br />cursorx := DrawPos.x - round(pIconInfo.xHotspot);<br />cursory := DrawPos.y - round(pIconInfo.yHotspot);<br />Mybmp.Canvas.Draw(cursorx, cursory, MyCursor); {画上鼠标}<br />DeleteObject(pIconInfo.hbmColor);{GetIconInfo 使用时创建了两个bitmap对象. 需要手工释放这两个对象}<br />DeleteObject(pIconInfo.hbmMask);{否则,调用他后,他会创建一个bitmap,多次调用会产生多个,直至资源耗尽}<br />Mycursor.ReleaseHandle; {释放数组内存}<br />MyCursor.Free; {释放鼠标指针}<br />end; <br />end;<br />procedure TForm1.FormCreate(Sender: TObject);<br />begin<br />ServerSocket1.Port := 3000; {端口}<br />ServerSocket1.Open; {Socket开始侦听}<br />end;<br />procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);<br />begin<br />if ServerSocket1.Active then ServerSocket1.Close; {关闭Socket}<br />end;<br />procedure TForm1.ServerSocket1ClientRead(Sender: TObject;<br />Socket: TCustomWinSocket);<br />var<br />S, S1: string;<br />MyBmp: TBitmap;<br />Myjpg: TJpegimage;<br />begin<br />S := Socket.ReceiveText;<br />if S = 'cap' then {客户端发出抓屏幕指令}<br />begin<br />try<br />MyStream := TMemorystream.Create;{建立内存流}<br />MyBmp := TBitmap.Create;<br />Myjpg := TJpegimage.Create;<br />Cjt_GetScreen(MyBmp, True); {True表示抓鼠标图像}<br />Myjpg.Assign(MyBmp); {将BMP图象转成JPG格式,便于在互联网上传输}<br />Myjpg.CompressionQuality := 10; {JPG文件压缩百分比设置,数字越大图像越清晰,但数据也越大}<br />Myjpg.SaveToStream(MyStream); {将JPG图象写入流中}<br />Myjpg.free;<br />MyStream.Position := 0;{注意:必须添加此句}<br />s1 := inttostr(MyStream.size);{流的大小}<br />Socket.sendtext(s1); {发送流大小}<br />finally<br />MyBmp.free;<br />end;<br />end;<br />if s = 'ready' then {客户端已准备好接收图象}<br />begin<br />MyStream.Position := 0;<br />Socket.SendStream(MyStream); {将流发送出去}<br />end;<br />end;<br />end.</p><p>  上面是服务端，下面我们来写客户端程序。新建一个工程，添加Socket控件ClientSocket、图像显示控件Image、一个 Panel 、一个Edit、两个 Button和一个状态栏控件StatusBar1。注意：把Edit1和两个 Button放在Panel1上面。ClientSocket的属性跟ServerSocket差不多，不过多了一个Address属性，表示要连接的服务端IP地址。填上IP地址后点“连接”将与服务端程序建立连接，如果成功就可以进行通讯了。点击“抓屏”将发送字符给服务端。因为程序用到了JPEG图像单元，所以要在Uses中添加Jpeg.<br />全部代码如下：<br />unit Unit2{客户端};<br />interface<br />uses<br />Windows,Messages,SysUtils,Classes,Graphics,Controls,Forms,Dialogs,StdCtrls,ScktComp,ExtCtrls,Jpeg, ComCtrls;<br />type<br />TForm1 = class(TForm)<br />ClientSocket1: TClientSocket;<br />Image1: TImage;<br />StatusBar1: TStatusBar;<br />Panel1: TPanel;<br />Edit1: TEdit;<br />Button1: TButton;<br />Button2: TButton;<br />procedure Button1Click(Sender: TObject);<br />procedure ClientSocket1Connect(Sender: TObject;<br />Socket: TCustomWinSocket);<br />procedure Button2Click(Sender: TObject);<br />procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;<br />ErrorEvent: TErrorEvent; var ErrorCode: Integer);<br />procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);<br />procedure FormCreate(Sender: TObject);<br />procedure FormClose(Sender: TObject; var Action: TCloseAction);<br />procedure ClientSocket1Disconnect(Sender: TObject;<br />Socket: TCustomWinSocket);<br />private<br />{ Private declarations }<br />public<br />{ Public declarations }<br />end;<br />var<br />Form1: TForm1;<br />MySize: Longint;<br />MyStream: TMemorystream;{内存流对象}<br />implementation<br />{$R *.DFM}<br />procedure TForm1.FormCreate(Sender: TObject);<br />begin<br />{-------- 下面为设置窗口控件的外观属性 ------------- }<br />{注意:把Button1、Button2和Edit1放在Panel1上面}<br />Edit1.Text := '127.0.0.1';<br />Button1.Caption := '连接主机';<br />Button2.Caption := '抓屏幕';<br />Button2.Enabled := false;<br />Panel1.Align := alTop;<br />Image1.Align := alClient;<br />Image1.Stretch := True;<br />StatusBar1.Align:=alBottom;<br />StatusBar1.SimplePanel := True;<br />{----------------------------------------------- }<br />MyStream := TMemorystream.Create; {建立内存流对象}<br />MySize := 0; {初始化}<br />end;<br />procedure TForm1.Button1Click(Sender: TObject);<br />begin<br />if not ClientSocket1.Active then<br />begin<br />ClientSocket1.Address := Edit1.Text; {远程IP地址}<br />ClientSocket1.Port := 3000; {Socket端口}<br />ClientSocket1.Open; {建立连接}<br />end;<br />end;<br />procedure TForm1.Button2Click(Sender: TObject);<br />begin<br />Clientsocket1.Socket.SendText('cap'); {发送指令通知服务端抓取屏幕图象}<br />Button2.Enabled := False;<br />end;<br />procedure TForm1.ClientSocket1Connect(Sender: TObject;<br />Socket: TCustomWinSocket);<br />begin<br />StatusBar1.SimpleText := '与主机' + ClientSocket1.Address + '成功建立连接!';<br />Button2.Enabled := True;<br />end;<br />procedure TForm1.ClientSocket1Error(Sender: TObject;<br />Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;<br />var ErrorCode: Integer);<br />begin<br />Errorcode := 0; {不弹出出错窗口}<br />StatusBar1.SimpleText := '无法与主机' + ClientSocket1.Address + '建立连接!';<br />end;<br />procedure TForm1.ClientSocket1Disconnect(Sender: TObject;<br />Socket: TCustomWinSocket);<br />begin<br />StatusBar1.SimpleText := '与主机' + ClientSocket1.Address + '断开连接!';<br />Button2.Enabled := False;<br />end;<br />procedure TForm1.ClientSocket1Read(Sender: TObject;<br />Socket: TCustomWinSocket);<br />var<br />MyBuffer: array[0..10000] of byte; {设置接收缓冲区}<br />MyReceviceLength: integer;<br />S: string;<br />MyBmp: TBitmap;<br />MyJpg: TJpegimage;<br />begin<br />StatusBar1.SimpleText := '正在接收数据......';<br />if MySize = 0 then {MySize为服务端发送的字节数，如果为0表示为尚未开始图象接收}<br />begin<br />S := Socket.ReceiveText;<br />MySize := Strtoint(S); {设置需接收的字节数}<br />Clientsocket1.Socket.SendText('ready'); {发指令通知服务端开始发送图象}<br />end<br />else<br />begin {以下为图象数据接收部分}<br />MyReceviceLength := socket.ReceiveLength; {读出包长度}<br />StatusBar1.SimpleText := '正在接收数据,数据大小为:' + inttostr(MySize);<br />Socket.ReceiveBuf(MyBuffer, MyReceviceLength); {接收数据包并读入缓冲区内}<br />MyStream.Write(MyBuffer, MyReceviceLength); {将数据写入流中}<br />if MyStream.Size &gt;= MySize then {如果流长度大于需接收的字节数，则接收完毕}<br />begin<br />MyStream.Position := 0;<br />MyBmp := tbitmap.Create;<br />MyJpg := tjpegimage.Create;<br />try<br />MyJpg.LoadFromStream(MyStream); {将流中的数据读至JPG图像对象中}<br />MyBmp.Assign(MyJpg); {将JPG转为BMP}<br />StatusBar1.SimpleText := '正在显示图像';<br />Image1.Picture.Bitmap.Assign(MyBmp); {分配给image1元件 }<br />finally {以下为清除工作 }<br />MyBmp.free;<br />MyJpg.free;<br />Button2.Enabled := true;<br />{ Socket.SendText('cap');添加此句即可连续抓屏 }<br />MyStream.Clear;<br />MySize := 0;<br />end;<br />end;<br />end;<br />end;<br />procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);<br />begin<br />MyStream.Free; {释放内存流对象}<br />if ClientSocket1.Active then ClientSocket1.Close; {关闭Socket连接}<br />end;<br />end.</p><p>  程序原理：运行服务端开始侦听，再运行客户端，输入服务端IP地址建立连接，然后发一个字符通知服务端抓屏幕。服务端调用自定义函数Cjt_GetScreen抓取屏幕存为BMP，把BMP转换成JPG，把JPG写入内存流中，然后把流发送给客户端。客户端接收到流后做相反操作，将流转换为JPG再转换为BMP然后显示出来。<br />  注意：因为Socket的限制，不能一次发送过大的数据，只能分几次发。所以程序中服务端抓屏转换为流后先发送流的大小，通知客户端这个流共有多大，客户端根据这个数字大小来判断是否已经接收完流，如果接收完才转换并显示。<br />  这个程序跟前面的自制OICQ都是利用了内存流对象TMemoryStream。其实，这个流对象是程序设计中用得最普遍的，它可以提高I/O的读写能力，而且如果你要同时操作几个不同类型的流，互相交换数据的话，用它作“中间人”是最好不过的了。比如说你把一个流压缩或者解压缩，就先建立一个TMemoryStream对象，然后把别的数据拷贝进去，再执行相应操作就可以了。因为它是直接在内存中工作，所以效率是非常高的。有时侯甚至你感觉不到有任何的延迟。<br />  程序有待改进的地方：当然可以加一个压缩单元，发送前先压缩再发送。注意：这里也是有技巧的，就是直接把BMP压缩而不要转换成JPG再压。实验证明：上面程序一幅图像大小大概为40-50KB，如果用LAH压缩算法处理一下便只有8-12KB，这样传输起来就比较快。如果想更快的话，可以采用这样的方法：先抓第一幅图像发送，然后从第二幅开始只发跟前一幅不同区域的图像。外国有一个程序叫Remote Administrator，就是采用这样的方法。他们测试的数据如下：局部网一秒钟100-500幅，互联网上，在网速极低的情况下，一秒钟传输5-10幅。说这些题外话只想说明一个道理：想问题，特别是写程序，特别是看起来很复杂的程序，千万不要钻牛角尖，有时侯不妨换个角度来想。程序是死的，人才是活的。当然，这些只能靠经验的积累。但是一开始就养成好习惯是终身受益的！<br /></p><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="/logs/2025994.html">java经典学习网站</a> 2006-03-09</div><div><a href="/logs/2025935.html">Java行业的圣经</a> 2006-03-09</div><div><a href="/logs/1429991.html">java连接access数据库</a> 2005-09-12</div><div><a href="/logs/1429977.html">j2sdk1.4.0中bin目录下程序用法</a> 2005-09-12</div><div><a href="/logs/1429970.html">HTTP协议状态码的含义</a> 2005-09-12</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fasoft.blogbus.com%2Flogs%2F1429999.html&title=delphi%E4%B8%AD%E7%9A%84%E6%B5%81">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br /><br />]]></description>
   <link>http://asoft.blogbus.com/logs/1429999.html</link>
   <author></author>
   <pubDate>Mon, 12 Sep 2005 11:33:04 +0800</pubDate>
  </item>
  <item>
   <title>用JDOM处理XML文档</title>
   <description><![CDATA[<P>用JDOM处理XML文档(转载)<BR>关键词：Java、JDOM、XML、JAXB </P>
<P>（一）JDOM的介绍以及与JAXB的比较 </P>
<P>Java + XML = JDOM ！ <BR>这就是JDOM设计者的目标。如果你曾经使用过烦人的SAX或是DOM来处理XML，你就会知道为什么要有JDOM或者是JAXB。在今年（2002）的JavaOne会议上JDOM的主要创始人Jason Hunter有一篇精彩的演讲介绍了JDOM技术，题目就是JDOM Makes XML Easy。 <BR>在那篇文档里，JDOM被拿来与DOM比较，而我更愿意拿它同JAXB比较。因为JAXB和JDOM都是为了在Java中提供比DOM和SAX更为方便的XML处理接口而开发的，并且通过完全不同的途径来解决这个问题。JDOM的处理方式是与DOM类似的树操作。而JAXB通过DTD和绑定模式来生成访问XML文档的Java代码，将XML映射成了Java对象来操作。你可以根据项目的需要和个人喜好来决定采用哪一个。 <BR>JDOM与JAXB的比较，从本身的特点来看： <BR>1) JDOM比JAXB更容易上手。使用JAXB首先要会编写DTD，然后还要会编写绑定模式。JDOM没有这样的要求，如果你会Java和XML，甚至可以说光是看JDOM的javadoc文档就能够使用JDOM。 <BR>2) JAXB编写好DTD和绑定模式以后，XML文档被映射成了Java对象，其数据就是Java对象的属性，连数据类型都做好了转换，因此，访问XML文档比JDOM要简便，可以说是一劳永逸。 <BR>3) JAXB由某个DTD和绑定模式生成的代码只能访问该DTD所约束的文档。如果想要访问其他XML文档，需要再编写DTD和绑定模式。JDOM可以处理任何XML文档，包括受约束的和不受约束的。 </P>
<P>目前JDOM和JAXB都没有正式版本。JDOM的最新版本是beta8，JAXB是1.0 early access，其规范版本是0.21。相对而言，JDOM更成熟一些。例如JAXB不支持名字空间、不能向XML文档写入处理指令，有时我们需要保留的换行符和首尾空格在JAXB中自动过滤掉了，就连放在里面也不能幸免。JDOM就没有这些限制。如果说以上的3点比较是JDOM和JAXB本身的特点所决定的，几乎不可能改变，那么这里表明，JAXB还需要更多的工作。 </P>
<P>（二）获得并安装JDOM <BR>在<A href="http://jdom.org">http://jdom.org</A>可以下载JDOM的最新版本。以JDOM beta8的2进制版本为例。下载后解压缩，JDOM的jar文件就是build目录下的文件jdom.jar，将之加入类路径。另外JDOM还需要lib目录下那些jar文件如xerces.jar的支持。如果在使用中出现以下错误： <BR>java.lang.NoSuchMethodError <BR>或 <BR>java.lang.NoClassDefFoundError: org/xml/sax/SAXNotRecognizedException <BR>你需要保证xerces.jar文件在CLASSPATH中位于其他XML类，如JAXP或Crimson之前，这些类文件，包括以前老版本的xerces，可能不支持SAX2.0或DOM Level 2。于是导致了上面的错误。 </P>
<P>（三）一个简单的例子 <BR>JDOM的处理方式有些类似于DOM，但它主要是用SAX实现的，你不必担心处理速度和内存的问题。另外，JDOM中几乎没有接口，的类全部是实实在在的类，没有类工厂类的。其最重要的一个包org.jdom中主要有以下类： <BR>? Attribute <BR>? CDATA <BR>? Comment <BR>? DocType <BR>? Document <BR>? Element <BR>? EntityRef <BR>? Namespace <BR>? ProcessingInstruction <BR>? Text <BR>数据输入要用到XML文档要通过org.jdom.input包，反过来需要org.jdom.output。如前面所说，关是看API文档就能够使用。 <BR>我们的例子读入XML文件exampleA.xml，加入一条处理指令，修改第一本书的价格和作者，并添加一条属性，然后写入文件exampleB.xml： <BR>//exampleA.xml <BR><?xml version="1.0" encoding="GBK"?><BR><BOOKLIST><BR>&nbsp;&nbsp; <BOOK><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <NAME>Java编程入门</NAME> <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <AUTHOR>张三</AUTHOR> <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <PUBLISHDATE>2002-6-6</PUBLISHDATE> <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <PRICE>35.0</PRICE> <BR>&nbsp;&nbsp; </BOOK><BR>&nbsp;&nbsp; <BOOK><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <NAME>XML在Java中的应用</NAME> <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <AUTHOR>李四</AUTHOR> <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <PUBLISHDATE>2002-9-16</PUBLISHDATE> <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <PRICE>92.0</PRICE> <BR>&nbsp;&nbsp; </BOOK><BR></BOOKLIST></P>
<P>//testJDOM.java <BR>import org.jdom.*; <BR>import org.jdom.output.*; <BR>import org.jdom.input.*; <BR>import java.io.*; <BR>public class TestJDOM{ <BR>&nbsp;&nbsp; public static void main(String args[])throws Exception{ <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAXBuilder sb = new SAXBuilder(); </P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //从文件构造一个Document，因为XML文件中已经指定了编码，所以这里不必了 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Document doc = sb.build(new FileInputStream("exampleA.xml")); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //加入一条处理指令 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ProcessingInstruction pi = new ProcessingInstruction <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ("xml-stylesheet","href=\"bookList.html.xsl\" type=\"text/xsl\""); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doc.addContent(pi); </P>
<P><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Element root = doc.getRootElement(); //得到根元素 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.util.List books = root.getChildren(); //得到根元素所有子元素的集合 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Element book = (Element)books.get(0); //得到第一个book元素 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //为第一本书添加一条属性 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Attribute a = new Attribute("hot","true");&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; book.setAttribute(a); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Element author = book.getChild("author"); //得到指定的字元素 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; author.setText("王五"); //将作者改为王五 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //或 Text t = new Text("王五");book.addContent(t); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Element price = book.getChild("price"); //得到指定的字元素 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //修改价格，比较郁闷的是我们必须自己转换数据类型，而这正是JAXB的优势 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; author.setText(Float.toString(50.0f)); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </P>
<P><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String indent = "&nbsp;&nbsp;&nbsp; "; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean newLines = true; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XMLOutputter outp = new XMLOutputter(indent,newLines,"GBK"); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outp.output(doc, new FileOutputStream("exampleB.xml")); </P>
<P>&nbsp;&nbsp; } <BR>}; </P>
<P>执行结果exampleB.xml： <BR><?xml version="1.0" encoding="GBK"?><BR><BOOKLIST><BR>&nbsp;&nbsp; <BOOK hot="”true”"><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <NAME>Java编程入门</NAME> <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <AUTHOR>50.0</AUTHOR> <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <PUBLISHDATE>2002-6-6</PUBLISHDATE> <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <PRICE>35.0</PRICE> <BR>&nbsp;&nbsp; </BOOK><BR>&nbsp;&nbsp; <BOOK><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <NAME>XML在Java中的应用</NAME> <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <AUTHOR>李四</AUTHOR> <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <PUBLISHDATE>2002-9-16</PUBLISHDATE> <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <PRICE>92.0</PRICE> <BR>&nbsp;&nbsp; </BOOK><BR></BOOKLIST><BR><?xml-stylesheet href="bookList.html.xsl" type="text/xsl"?></P>
<P>在默认情况下，JDOM的Element类的getText()这类的方法不会过滤空白字符，如果你需要过滤，用setTextTrim() 。 </P>
<P><BR>（四）参考文档 <BR>1) JDOM Makes XML Easy (<A href="http://www.servlets.com/speaking/jdom-javaone.pdf">http://www.servlets.com/speaking/jdom-javaone.pdf</A>) <BR>2) The Java ™ Architecture for XML Binding User’s Guide (<A href="http://java.sun.com/xml/jaxb/jaxb-docs.pdf">http://java.sun.com/xml/jaxb/jaxb-docs.pdf</A>) <BR>3) Web Services Made Easier. The Java TM APIs and Architectures for XML, A Technical White Paper (<A href="http://java.sun.com/xml/webservices.pdf">http://java.sun.com/xml/webservices.pdf</A> )</P>
<P></P><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="/logs/2355317.html">手机游戏编程</a> 2006-04-26</div><div><a href="/logs/2303775.html">中国最让美不安的五种武器</a> 2006-04-20</div><div><a href="/logs/2025994.html">java经典学习网站</a> 2006-03-09</div><div><a href="/logs/1429970.html">HTTP协议状态码的含义</a> 2005-09-12</div><div><a href="/logs/1422351.html">C++游戏编程</a> 2005-09-09</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fasoft.blogbus.com%2Flogs%2F1429992.html&title=%E7%94%A8JDOM%E5%A4%84%E7%90%86XML%E6%96%87%E6%A1%A3">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br /><br />]]></description>
   <link>http://asoft.blogbus.com/logs/1429992.html</link>
   <author></author>
   <pubDate>Mon, 12 Sep 2005 11:30:00 +0800</pubDate>
  </item>
  <item>
   <title>java连接access数据库</title>
   <description><![CDATA[<P>有三种办法<BR><BR>第一种是用access的JDBC驱动程序，到<A href="http://industry.java.sun.com/products/jdbc/drivers">http://industry.java.sun.com/products/jdbc/drivers</A>这个网站上查找并下在access的jdbc驱动程序。<BR><BR>第二个办法是你用下面的代码试试<BR>con = DriverManager.getConnection("jdbc:odbc:Driver={MicroSoft Access Driver (*.mdb)};DBQ=C:/data/Access/test1.mdb","dba","sql");<BR><BR>后面的代码一样。这样你就可以访问access数据库了。<BR></P>
<P>第三个是用sun的jdbcodbc桥，这个大家用的多了，在此就不写了<BR></P>
<P>&nbsp;</P><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="/logs/2355317.html">手机游戏编程</a> 2006-04-26</div><div><a href="/logs/2303775.html">中国最让美不安的五种武器</a> 2006-04-20</div><div><a href="/logs/1429992.html">用JDOM处理XML文档</a> 2005-09-12</div><div><a href="/logs/1429977.html">j2sdk1.4.0中bin目录下程序用法</a> 2005-09-12</div><div><a href="/logs/1429970.html">HTTP协议状态码的含义</a> 2005-09-12</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fasoft.blogbus.com%2Flogs%2F1429991.html&title=java%E8%BF%9E%E6%8E%A5access%E6%95%B0%E6%8D%AE%E5%BA%93">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br /><br />]]></description>
   <link>http://asoft.blogbus.com/logs/1429991.html</link>
   <author></author>
   <pubDate>Mon, 12 Sep 2005 11:27:53 +0800</pubDate>
  </item>
  <item>
   <title>j2sdk1.4.0中bin目录下程序用法</title>
   <description><![CDATA[<P>java.exe以及javac.exe等用法</P><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="http://asoft.blogbus.com/logs/2025994.html">java经典学习网站</a> 2006-03-09</div><div><a href="http://asoft.blogbus.com/logs/2025935.html">Java行业的圣经</a> 2006-03-09</div><div><a href="/logs/2355337.html">KM3D引擎功能描述</a> 2006-04-26</div><div><a href="/logs/1429991.html">java连接access数据库</a> 2005-09-12</div><div><a href="/logs/1406697.html">Java多线程基本概念</a> 2005-09-02</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fasoft.blogbus.com%2Flogs%2F1429977.html&title=j2sdk1.4.0%E4%B8%ADbin%E7%9B%AE%E5%BD%95%E4%B8%8B%E7%A8%8B%E5%BA%8F%E7%94%A8%E6%B3%95">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br /><br />]]></description>
   <link>http://asoft.blogbus.com/logs/1429977.html</link>
   <author></author>
   <pubDate>Mon, 12 Sep 2005 11:22:13 +0800</pubDate>
  </item>
  <item>
   <title>HTTP协议状态码的含义</title>
   <description><![CDATA[<P>HTTP协议状态码的含义 <BR></P>
<P>号码 含义 <BR>----------------------------------------- <BR>"100" : Continue <BR>"101" : witching Protocols <BR>"200" : OK <BR>"201" : Created <BR>"202" : Accepted <BR>"203" : Non-Authoritative Information <BR>"204" : No Content <BR>"205" : Reset Content <BR>"206" : Partial Content <BR>"300" : Multiple Choices <BR>"301" : Moved Permanently <BR>"302" : Found <BR>"303" : See Other <BR>"304" : Not Modified <BR>"305" : Use Proxy <BR>"307" : Temporary Redirect <BR>"400" : Bad Request <BR>"401" : Unauthorized <BR>"402" : Payment Required <BR>"403" : Forbidden <BR>"404" : Not Found <BR>"405" : Method Not Allowed <BR>"406" : Not Acceptable <BR>"407" : Proxy Authentication Required <BR>"408" : Request Time-out <BR>"409" : Conflict <BR>"410" : Gone <BR>"411" : Length Required <BR>"412" : Precondition Failed <BR>"413" : Request Entity Too Large <BR>"414" : Request-URI Too Large <BR>"415" : Unsupported Media Type <BR>"416" : Requested range not satisfiable <BR>"417" : Expectation Failed <BR>"500" : Internal Server Error <BR>"501" : Not Implemented <BR>"502" : Bad Gateway <BR>"503" : Service Unavailable <BR>"504" : Gateway Time-out <BR>"505" : HTTP Version not supported</P><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="/logs/2355337.html">KM3D引擎功能描述</a> 2006-04-26</div><div><a href="/logs/2355317.html">手机游戏编程</a> 2006-04-26</div><div><a href="/logs/1429999.html">delphi中的流</a> 2005-09-12</div><div><a href="/logs/1429992.html">用JDOM处理XML文档</a> 2005-09-12</div><div><a href="/logs/1422351.html">C++游戏编程</a> 2005-09-09</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fasoft.blogbus.com%2Flogs%2F1429970.html&title=HTTP%E5%8D%8F%E8%AE%AE%E7%8A%B6%E6%80%81%E7%A0%81%E7%9A%84%E5%90%AB%E4%B9%89">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br /><br />]]></description>
   <link>http://asoft.blogbus.com/logs/1429970.html</link>
   <author></author>
   <pubDate>Mon, 12 Sep 2005 11:19:00 +0800</pubDate>
  </item>
 </channel>
</rss>
