2006年4月1日星期六

微软卫星地图

  微软终于也耐不住寂寞,推出了Beta版的微软卫星地图(Windows Live Local),用以对抗日益强大的Google卫星地图

  这是微软在本地搜索与地图服务方面对Google的一次反击。去年年初,Google推出了自己的卫星地图服务,在业界可算风头出尽,并且引起了世界各国军方和政府的关注。

  微软于是也不甘落后,推出了新版的Windows Live Local微软地图),其实也是基於地理资讯服务的一个地图查询系统。新版的微软地图美化了界面,显得比以前漂亮了不少,另外,地图界面也显得更加详实,清晰。

  值得注意的是,微软的这个地图不仅仅是卫星图片,还增加了鸟瞰的功能,图片数据据说来源于高清晰航拍照片,这样微软地球就能够提供比Google Earth更高解析度和更高品质的图像。用户可以把图像放的更大,可以旋转视图从东西南北4各不同方向观看地貌。这些航空照片品质非常高,解析度已经小於0.1米,视角高度距地面最小近约23米(25yds),也就如同站在20多米的楼顶看地面的效果,立体感的效果是卫星照片无法比拟的。

自由女神像鸟瞰图,清晰地令人震惊

纽约曼哈顿岛的一角,汽车和行人都依稀可见

  然而,这些鸟瞰图片是不连贯的,仅仅也覆盖了美国主要的地址,没有中国的鸟瞰图(估计中国政府也不会让微软去拍),中国的卫星图片的解析度也很低,不如Google的卫星图片,可以说,对于中国用户来说用处还是不大的。

  这种鸟瞰图的成本一定很高,微软为了和Google竞争也是花了血本了。希望微软也推出类似Google Earth的客户端软件,那样用起鸟瞰功能可能会感觉好一些,速度应该也会快一些。

  微软地图的地址是:http://local.live.com

2006年3月31日星期五

计算机病毒的通用清除技术

  这篇文章是我十年前写的第二篇在杂志上发表的文章。发表在微电脑世界1997年的第三期上。

  那个年代我对计算机病毒也非常感兴趣。在九二年我刚上大学时候,对计算机病毒其实一点概念也没有,只是感觉计算机病毒是很神秘很高深的东西。对于病毒程序能够在不同电脑之间传播,那时感觉很不可思议。

  那的确是个很古老的时代,我们用的操作系统是DOS 3.31,学的是TRUE BASIC,电脑是33M主频的PC/AT,286是当时最先进的机器。那时候的电脑病毒也很有意思,比如小球病毒,就是一个活蹦乱跳的小圆点,不停地运动,当碰到屏幕边沿就立刻反弹。雨点病毒则是一些下落的雨点或字符。64/Bloody病毒则是在屏幕上显示血红的Bloody文字。

  计算机系的大学老师们对病毒其实也很感兴趣,记得一个老师曾经指着小球病毒的汇编代码跟我们说:整个中国会编这个病毒的人不超过10个。

  最开始的病毒破坏力都很小,在现在看来,甚至有些可爱。我估计都是一些高手在编写病毒,写病毒的目的大概是为了炫耀自己的编程能力。DOS病毒几乎全是用汇编写的代码,汇编语言其实和二进制机器语言差不多,用那个东西写程序可真是一场噩梦啊,我曾经写过一个八百多行的汇编程序,写的我头晕脑涨,我知道,用汇编来写一个病毒的确不是一件容易的事情,特别是一些病毒甚至还有自身加密、变种的功能,因此,那些人也的确值得炫耀一下的。不过现在,汇编语言我都快忘光了,原因很简单,用机器代码写程序的可维护性很差,自然用的人也肯定会越来越少。

  大学毕业后的几年,我逐渐对这些失去了兴趣,主要因为一些计算机业的害群之马影响了我的心情,CIH病毒开了一个恶劣的开头,对电脑用户的资料信息甚至硬件进行恶性破坏,而后的病毒似乎在比谁更不要脸,现在互联网的普及,以及一些脚本语言的流行,编写木马病毒门槛非常低了,菜鸟都可以写木马病毒了,而现在的木马病毒清一色全是恶性病毒,不是偷密码、弹广告就是改IE,甚至还出了HAO123这样依靠木马病毒发家的“成功案例”,但这些病毒的编写目的都令我感到恶心,对于那些低劣的病毒编写者,我只觉得他们可怜,让他们继续为了他们那低劣的理想和愿望而编写病毒吧,我还有更重要的事情要做呢。

  下面是我写的论文,其目前已经没有实际意义,因为外部环境发生了巨大变化,我写那篇论文的前提是“计算机病毒大部分不是恶性病毒”的基础上,甚至执行病毒代码来还原恢复原始程序,现在的环境下这已经不可能了,现在是什么世道?谁敢运行病毒啊!

 

计算机病毒的通用清除技术

 

摘要   本文就当前流行的文件型病毒出发,分析介绍了从文件结构特性入手清除计算机病毒的一种技术.

关键字   病毒  传染  加载执行(EXEC)  文件前缀段(PSP)  进程

 

第一章  引言

   计算机病毒的发展历史悠久,从80年代中后期广泛传播开来.时至今日,据统计世界上已存在的计算机病毒有5000余种,并且每月以平均几十种的速度增加.计算机病毒的发展一定程度上影响了反病毒产品的发展,原有的反病毒技术在新型病毒面前显得陈旧而无能为力.病毒检测产品是以病毒的特征码为基础的针对具体病毒的判断技术,因此,病毒的变种以及未知病毒给检测软件带来较大的困难.病毒的清除是建立在病毒检测的基础上,目前病毒的清除实际上是针对已知病毒.这种被动式的方法使反病毒技术总是落后于病毒技术,虽然这类反病毒产品对病毒的抑制是不容忽视的,但它所暴露出来的漏洞却越来越多.新一代的开放式反病毒技术应运而生,这种开放式反病毒技术将病毒的结构用一个统一的数据结构加以描述,用户可以根据自身对病毒进行分析,并具有更加灵活的升级优势,对于新一代具有反跟踪,加密技术的多维变异病毒,这种方法显示出其灵活及高效的特色,这种广谱型的查毒杀毒系统将逐渐成为反病毒产品的发展趋势.

   下面,本文将介绍一种基于可执行文件结构特性的通用杀毒技术.

第二章 计算机病毒的机理

   首先,我们先了解一下计算机病毒的结构特点以及其工作原理.

   计算机病毒的结构决定了计算机病毒的特点,大致归纳如下:

   (1) 计算机病毒是一段可执行的程序

   计算机病毒和其它合法程序一样,是一种可存储可执行的非法程序,它可以直接或间接地运行,可以隐蔽在可执行程序和数据文件中而不易被人们察觉和发现.在病毒程序运行时,其与合法程序争夺系统的控制权.

   (2) 计算机病毒的广泛传染性

   由于病毒一词来源于“生物学”,传染也相应成为计算机病毒的一个重要特性.传染性是衡量一种程序是否为病毒的首要条件.计算机病毒的传染性是计算机病毒的再生机制,病毒程序一旦进入系统与系统中的程序接在一起,它就会在运行这一被传染的程序之后开始传染其它程序.这样一来,病毒就会很快地传染到整个计算机系统.

   (3) 计算机病毒的潜伏性

   计算机病毒的潜伏性是具有依附于其它媒体而寄生的能力.一个编制巧妙的计算机病毒程序,可以在几周或者几个月甚至几年内隐藏在合法文件之中,对其它系统进行传染,而不被人们发现.计算机病毒的潜伏性于传染性相辅相成,潜伏性越好,其在系统中存在的时间就会越长,病毒的传染范围也就会越大.

   (4) 计算机病毒的可触发性

   计算机病毒一般都有一个触发条件:或者触发其传染,或者在一定条件下激活计算机病毒的表现部分或破坏部分.触发实质上是一种条件控制,一个病毒程序可以按照设计者的要求,在某个点上激活并对系统发起攻击.

   (5) 计算机病毒的针对性

   现在世界上出现的计算机病毒,并不是对所有计算机系统都进行传染的.例如,有针对IBM PC及其兼容机的,有针对APPLE公司的Macintosh的以及针对Unix操作系统的.现在流行的绝大多数计算机病毒都是针对基于MS DOS系统的IBM PC及其兼容机的.

   (6) 计算机病毒的衍生性

   由于计算机病毒本身是一段计算机系统可执行的文件(程序),所以这种程序反映了设计者的一种设计思想.同时,又由于计算机病毒本身也是由几部分组成的,如安装部分,传染部分和破坏部分等,因此这些模块很容易被病毒本身或其它模仿者所修改,使之成为一种不同于原病毒的计算机病毒.[1]

   计算机病毒按链接方式可分为以下几类:

   (1)源码型病毒 (Source Code Virus) (2)入侵型病毒 (Intrusive Virus) (3)操作系统病毒 (Operating System Virus)  (4)外壳型病毒 (Shell Virus).

   (1)(2)攻击的是高级语言编写的源文件及目标文件,在微机上很少见, (3)即引导区病毒,主要攻击计算机的Boot区,其诊治方法较为简单,一般用DEBUG或NU等工具就能方便地清除.本文所提的病毒专指目前在PC在机上流行最广的攻击可执行文件的外壳型病毒.

   计算机外壳型病毒是将其自己包围在主程序的四周,对原来的程序不作修改.外壳型病毒易于编写,也较为常见,但诊治却较为麻烦.

   外壳型病毒具有以下特点:

   自身复制在目标文件外围(即文件尾部);不修改原来正常文件[2];运行时病毒抢先进入内存.病毒执行完后,转回原文件入口运行(隐蔽性).

   在基于DOS操作系统PC机上,外壳型病毒主要攻击的目标是两类可执行文件:COM文件与EXE文件.COM文件结构比较简单,解毒比较容易.而广泛流行的EXE文件相对复杂,但操作却更灵活,适合于超过64K的程序,更易与将来的操作系统兼容,因此得到广泛的使用.

第三章 COM病毒的清除

一  实现原理

   COM文件是DOS的一种二进制代码的可执行文件,COM文件结构比较简单,加载过程十分迅速.整个程序只有一个段.因此全部代码长度必须小于64K,其入口代码地址是CS:100H. DOS装入COM文件时,先在内存建立一个长度为100H的程序前缀段(PSP,由DOS建立,是DOS用户程序和命令行之间的接口),然后将整个文件装载于PSP上端,不进行重定位操作,接着将四个段地址寄存器DS(Data Segment),CS(Code Segment),SS(Stack Segment),ES(Extra Segment)初始化为程序前缀段(PSP)的段地址,最后将程序的控制权交于CS:100H处.如表1所示.

                表1:  COM文件的装入执行

地址 内容  
XXXX:0000 PSP ← CS,DS,ES,SS
XXXX:0100 程序代码 ← IP
  数据  
  堆栈 ← SP

   寄生于COM文件的病毒,大部分是采用保存文件头若干字节,并将第一条指令改为”JMP 病毒入口”,以确保病毒最先执行,也有部分病毒附加在文件首部,病毒执行完后恢复寄生程序原先的状态,并用JMP FAR等指令使程序再次回到CS:100H处,以确保寄生程序与PSP的一致.

   可见,病毒执行完后,必将会恢复并运行原文件,以便传播,当其将原文件参数全部恢复后,会将控制权交于CS:100H处.因此,判别COM文件的真正入口的标准是:最后一次在CS:100H处执行的程序段(CS=当前PSP段地址,IP=100H).

   于是,可以设想出这样一种跟踪器,每执行一条指令,便判断上述条件是否满足,如果满足,则此时CS:100H处的代码便是原文件的影像,由于COM文件只有一个段,因此此时内存的影像既是磁盘文件的内容.将CS:100H处的代码写回原文件,此病毒即被消除了,如果知道病毒的长度,还可将文件尾的无用代码去掉,这样病毒就物理上消除了.

二  实现方案

   设想的跟踪器的实现是核心问题,也是主要的难点.事实上单步陷阱中断(INT 1)完全符合跟踪器的条件,但由于目前的计算机病毒广泛采取破坏单步断点的技术,因此这种跟踪器在具体实现上还有一定难度.

   目前有一种比较方便的替代方法,即DOS的EXEC(INT 21H的功能4BH,加载执行)功能,此功能有一个有趣的现象,即执行完加载程序后,它会将所有寄存器恢复到执行前的状态,并且它不清除内存,此方法易于实现,操作简便,但对所处理的文件有一定的要求及限制.

   具体实现是,先保存中断向量表,然后在分配一块内存,调用DOS的EXEC功能执行被感染的COM文件.执行结束后,重写中断向量表以清除内存中的病毒,然后将内存偏移100H上的代码写入文件,文件长度为原文件长度,最后,在知晓病毒长度的情况下去掉文件尾的病毒代码,清除工作结束.

   这种技术可以对付任何一种文件型病毒,但对于COM文件却有一定的要求:即文件在执行过程中不可以修改代码段的内容,未被加密或压缩的文件一般均可满足此条件.

四  使用调试器DEBUG.COM的EXEC功能

   更简单的方法是用DEBUG来实现,先用L命令装入一个文件,再用G命令运行,EXEC功能结束后,返回寄存器与运行前完全一样,此时用W命令存盘,这时病毒便被清除了.(全过程只用了三条命令)

 

第四章 EXE病毒的清除

一  实现原理

   EXE文件是DOS系统最为常见且灵活的可执行文件,其应用十分广泛.但EXE文件的结构要比COM文件复杂得多.EXE文件由文件头(Header)和装入模块(Load Module)两大部分组成.文件头由格式化区(Format Area)和重定位表(Relocation Table)组成.装入模块为程序代码部分,从位移量100H字节开始.DOS系统在调用EXE文件时,先在内存块底部建立一个程序前缀段(PSP),再将装入模块读入内存指定区域(PSP上方),DS和ES初始化为PSP段地址,CS,IP,SS,SP由文件头格式化区确定,并通过重定位参数调整.然后根据重定位项修改代码数据,最后将程序的控制权由CS:IP传递给目标程序. (如表2所示)

                表2:  EXE文件的装入执行

地址 内容  
XXXX:0000 PSP ← DS,ES
XXXX:0100 数据  
  程序代码 ← CS:IP
  堆栈 ← SS:SP

   对于EXE文件而言,计算机病毒主要是附着于宿主文件的尾部,由于它必须首先获得程序的控制权,因此它必须对文件头进行修改.一般来说,只要恢复了正确的文件头,便可达到杀毒的目的.

   EXE文件被加载时,系统根据EXE文件头的CS:IP参数确定第一条执行语句,因此病毒只需将CS:IP地址指针修改,便可首先执行,事实上,大多数病毒仅仅只修改了文件头,而未修改原文件内容.这便为完整地恢复原程序代码提供了条件.

   从上面的分析可知,感染病毒的EXE文件尾部形成明显的层次,CS:IP指向病毒体,不管病毒采取什么样的措施,它最终必定会在内存中恢复宿主程序所有的真实参数,并且用一条长跳转指令返回原程序.这时,我们便可直接提取出正确的CS:IP和SS:SP参数指针,用它修改文件头后,再将外层病毒代码去掉,这便彻底地恢复了原EXE文件.

   问题在于如何找到EXE文件的正确入口.判断EXE文件的真正入口是十分复杂的,但对于基于DOS系统的病毒来说,其编写语种基本上是汇编语言,因此便具有一些独特的特点.经过大量分析看出,一般情况下,当EXE病毒执行到真正的文件开头时,其CS和DS均要改变,并且DS内容必定是PSP段地址,SS:SP指针被初始化,对于不修改重定位表的病毒来说,CS:IP指针应处于重定位区域内.

   于是,可以再设想出这样一种跟踪器,每执行一条指令,便判断上述条件是否满足,如果满足,则此时CS:IP处的代码便是原文件的影像,根据CPU各个寄存器的内容便可正确地恢复EXE文件头,以达到杀毒的目的.

二  实现方案

   同COM文件杀毒一样,这种理论上的跟踪器实际上是很难奏效的.因此,我们又要求助于我们的老朋友--EXEX功能.

   MS DOS的功能4B有两个重要的子功能:4B00为装入并执行,4B01为装入不执行(未公开的文档功能),4B00用于执行所有的可执行程序,4B01则用于DEBUG调试器中的装入功能.(关于4B01功能的具体参数见附录1).

   由于问题的关键在于如何找到原程序的第一条指令,也就是说在执行到原程序的第一条指令时发生中断,因此我们可以人为地将第一条指令改为中断指令.为了完成这种功能,只需用4B01功能来仿真4B00功能.

   具体是这样做的,当系统调用加载执行功能4B00时,先用功能4B01加载,并初试化所有参数,这时内存的影像应如表3所示.

               表3:  EXE 染毒程序内存影像

地址 内容
  原程序代码区
  CS:IP→ 病毒代码区

   假定病毒的第一条指令处于病毒代码的最前端,原程序的内存影像应为PSP:100~CS:IP(病毒的第一条指令),将这部分区域全部用ASCII码CD填充.这样,原程序的每一条指令都变成了中断指令INT CD(不用INT 3断点中断是因为大部分病毒都具有破坏单步断点中断的功能),也就是说,无论从原程序的任何地址开始运行,所执行的第一条指令都是INT CD.这样,一旦病毒代码执行完毕,打算用长跳转指令返回原程序执行时,都会触发软中断INT CD,而通过INT CD的中断服务程序便可取得EXE文件头真正的初始化CS:IP和SS:SP指针.

   另外值得注意的是,修改后的INT 21必须是可递归的,因为有些病毒(如新世纪病毒)是通过第二次加载原程序来返回的,因此,内存填充要进行两次.4B01也被调用了两次.

   此方法的效率和准确度要远远高于用DEBUG等工具逐步跟踪分析的手工杀毒法.可以为各种染上已知或未知病毒的文件去除病毒外壳.与RCOPY等去壳程序不同的是,这种方法对EXE程序的恢复是全真的恢复,它并不改变原EXE文件的任何内容.它所恢复的EXE程序代码应与原EXE程序代码完全一样.另外,此法由于采用了剥壳还原法,因此还可以用来清除交叉感染的病毒,方法是从外到内逐层脱壳,最后彻底恢复最内层的宿主文件.

 

第五章 结论

   本文所论述的这种清除病毒的方法的实现原理是非常独特的.当然,文中所给出的实现方案并不能清除所有的计算机病毒,但它却给出了一种思想,即抛弃以前那种一个杀毒算法只能杀一个病毒,而是一个算法可以杀一类病毒.根据这种思想,笔者已用C语言和汇编语言编写出这个通用杀病毒程序,并且用大量的病毒对它进行了测试,效果良好.当然,病毒是五花八门的,因此一个统一的病毒对抗软件应接受广泛的考验.其具体的功效还需要多方面的验证,笔者也仅仅希望这种思想能够在反病毒领域发挥出积极的作用.

 

参考文献

1.  李向宇 著   <<计算机病毒概论>>      IDG国际数据集团  1990

2.  Ray Dancan  <<高水平MS DOS程序设计>>   电子工业出版社  1988

   Ray Dancan  Advanced MS-DOS Programing   Microsoft Press  1988

3 . Ray Dancan   <<MS DOS百科全书>>     电子工业出版社  1990

   Ray Duncan  the MS-DOS Encyclopedia    Microsoft Press  1990

  附录:MS-DOS EXEC功能详解

  翻译人:William Long 于1996年 译自:MS DOS百科全书(Ray Duncan: the MS-DOS Encyclopedia)

  MS-DOS系统的加载,即把磁盘上的COM及EXE文件装入内存并执行,可以被任何程序使用MS-DOS功能(功能4BH,加载执行)产生.DOS的命令解释程序COMMAND.COM使用EXEC装入它的外部命令,如CHKDSK,或其它应用程序.许多流行的商业软件,例如数据库和字处理,都使用EXEC执行辅助程序(例如拼写检查),或是装入COMMAND.COM的另一个副本,这就允许用户在不失去当前工作上下文时运行一个辅助程序或打入MS-DOS命令.

  当EXEC被一个程序(父进程)调用并加载另一个程序(子进程),父进程可以通过一串字符即环境块,命令行及两个文件控制块,来传输一定的信息给子进程.子进程同样继承了父进程的MSDOS标准设备及其它父进程打开的设备的句柄(除非打开的操作有"非继承性"的选择).任何操作都可被子进程的继承句柄执行,例如定位或文件输入输出,而且还影响着与父进程句柄联系着的文件指针.子进程也可装入另一程序,如此循环直至系统内存溢出.

  因为MSDOS并非一个多任务的操作系统,子进程直到运行结束才交出系统控制权,父进程此时被挂起,这种进程操作有时也叫做同步执行.当子进程中止,父进程得到控制权并可用另一个系统功能调用(INT 21H功能4DH)取回子进程的返回码并检查子进程的中止是否正常,或是一个重大的硬件错误,比如用户按了Ctrl-C.

  除了装入子进程外,EXEC还可以被用来装入由于用汇编或高级语言写成而不能包含在其库文件中的子程序或应用程序的覆盖文件,这种类型的覆盖文件不能单独运行,多数需要主程序的段内的"帮助"工作或数据.

  EXEC功能仅存在MSDOS 2.0版以上,在MSDOS 1.X版中,父进程可以用INT 21H的功能26H建立一个子进程的程序前缀段,但必须自己完成装载,重定位,执行代码的过程,而不是依靠操作系统的帮助.

  EXEC是怎样工作的

  当EXEC功能接到一个执行程序的请求时,它首先试图打开并定位指定的程序文件.如果文件没有找到,EXEC立刻失败并返回调用者一个错误码.

  如果文件存在,EXEC打开此文件,确定它的大小,并检查文件的首块.如果块的头两个字节是ASCII码MZ,文件便设定为一个EXE装入模式.程序代码段,数据段,堆栈段的大小可以从文件头获得.否则,整个文件便设定为一个决对装入影像(COM程序).实际的文件名后缀(COM或EXE)在这个测试中被忽略.

  此时,内存所需要装入程序的大小是知道的,假如有足够的空间装入程序,EXEC便在内存分配两个块:一个包括新程序的环境块,另一个包括程序的代码段,数据段和堆栈段.不同类型的程序实际分配的大小不同.COM程序得到系统中全部的空余内存(除非内存空间过早形成碎块),而分配给EXE程序的空间大小是由文件头的两个字段控制,MINALLOC和MAXALLOC,它是由LINK设置的.

  EXEC接着将父进程的环境块拷入子进程的环境块,在子进程内存块的底部建立一个程序前缀段(PSP).并将命令行及缺省文件控制块拷入PSP.以前的终止地址(INT 22H),Ctrl-C(INT 23H)

  及严重错误(INT 24H)中断向量的目录存入新的PSP,终止地址向量被更新,以便子进程终止或失败时控制能够返回到父进程.

  接着子进程的实际代码和部分数据便由磁盘文件读到新PSP结构上方的程序内存块.如果子程序是一个EXE文件,文件头的重定位表常用于在程序里定位参考段以便反映出它实际的装入地址.

  最后,EXEC功能建立为程序的CPU寄存器和堆栈并将控制传给程序.COM文件的入口指针常是程序内存块中偏移100H(PSP后第一个字节).而EXE文件的入口地址由文件头指定,可以在程序中任何位置.

  当EXEC用于装入并执行一个覆盖文件而不是子程序时,它的操作会比上述更为简单.对于覆盖文件,EXEC并不试图分配内存或建立PSP及环境块,它只简单地将文件的内容装入调用文件所指定的地址,并执行一些必要的重定位(如果覆盖文件有一个EXE文件头).使用的段值也是由调用者提供.EXEX接着并不是将控制传给最新装入文件的代码,而是返回所产生的程序,请求程序负责在适当的位置调用覆盖.

  使用EXEC装入程序

  当一个程序装入并执行另一个程序时,它必须执行以下几步:

  1.确认有足够的空闲内存来装入子进程的代码,数据和堆栈.

  2.建立EXEC和子进程所需要的信息.

  3.调用MSDOS的EXEC功能运行子进程.

  4.恢复并测试子进程的结束及返回码.

  分配内存

  MSDOS典型地分配给被加载的COM或EXE文件所有可用的内存.一个不常见的例外是当一个由/CPARMAXALLOC开关联接或被EXEMOD修改的EXE程序会由它先前驻留的数据或代码分裂一个短小的程序块.所以,当一个程序要装入另一个程序之前,它必须释放所有它本身代码数据堆栈所不用的内存.

  释放多余的内存是调用MSDOS的重分配内存块功能(INT 21H,功能4AH).此时,ES寄存器置父进程的PSP段地址,BX寄存器置程序自身必须使用的内存块数,如预期的父进程是COM程序,且它减少它的内存分配数低于64K时,它必须移动它的堆栈到一个安全的空间.

  准备EXEC的参数

  当使用装入和执行一程序时,必须提供EXEC功能两条参数:

  1.子程序路径名的地址.

  2.参数块地址.

  参数块依次包括子程序所需信息的地址.

  程序名

  子程序的路径名必需是明确的,零结尾(ASCIIZ),规定文件名(没有非识别字符).如果没有包含路径,便在当前目录下寻找程序,如果无驱动器名,则使用默认驱动器.

  参数块

  参数块包括四个数据项地址:

  1. 环境块

  2. 命令行

  3. 二个缺省文件控制块(FCBs)

  在参数块中为环境块指针准备的空间只有两个字节,包括一个段地址.这是因为环境块总是排在段落上(它的地址总可以被16整除).值0000H表示子进程的环境应被毫不改变地继承.余下的三个地址全是双字节地址,是标准的Intel格式,一个低字的段偏移,一个高字的段地址.

  环境块

  一个环境块总是从一个边界段开始,包含一系列的以0结尾的字符串(ASCIIZ),形式如下:

  name = variable   全部字符串的结尾以一个附加的0表示.

  如果在参数块中的环境块指针提供给一个EXEC的调用包含0,那么子进程只需简单地拷贝父进程的环境块.父进程能够提供一个不同或是增长一组字符串的段指针.另一方面,在MSDOS 3.0

  以后的版本里,EXEC使子程序的环境块具有完整的路径名.环境块最大为32字节.通过这种途径,这么大的信息也可被程序识别.

  最初的(或主控的)系统环境块属于系统接通或重新启动后的命令处理程序(通常是COMMAND.COM)所装入的.COMMAND.COM将字符串PATH,SHELL,PROMPT和SET命令的结果写入系统的主环境块.前两个通常使用的是默认值.例如,一个MSDOS 3.2版的系统从C驱启动,在AUTOEXEC.BAT文件中无PATH命令,CONFIG.SYS文件中也无SHELL命令,则主环境块将下面两行字符串写入:

  PATH =

  COMSPEC = C: COMMAND.COM

  COMMAND.COM为运行"外部"命令而寻找这些说明清单,同时也为了找到自身在磁盘上的可执行文件以便它能在必要的时候重新装入它的暂态部分.当PROMPT字串存在时(先前的PROMPT或SET PROMPT命令产生的结果),COMMAND.COM它来修订用户的提示显示.

  环境块中的其它字符串仅仅为了特殊程序提供信息,它不影响操作系统的操作.例如,Microsoft C 编译器和 Microsoft Object 连接器在环境块中寻找INCLUDE,LIB和TMP字符串,以确定头文件,库文件,临时文件的指定位置.图2给出了一个典型的环境块的十六进制显示图.

  命令行

  命令行是传给子进程的,它包括一字节指明余下命令行的长度,紧接着的ASCII字符串是以ASCII码回车(0DH)为结束的.回车码并不包含在长度值里.命令行可包括子进程可以检查到的所有开关,文件名,以及其它参数,用以影响程序的操作.命令行被拷贝到子进程PSP偏移80H处.

  当COMMAND.COM使用EXEC运行一个程序时,它的命令行包括除程序名或重定向参数外所有用户打下的命令.I/O的重定向是在COMMAND.COM内部处理的,它表明子进程继承了标准设备句柄的活动.其它程序使用EXEC来运行子进程必须自己做一些必要的重定向而且必须提供一个合适的命令行,以便子进程表现得如同被COMMAND.COM装入一样.

  确省的文件控制块

  EXEC参数块的二个确省的FCBs指向拷贝到子进程PSP的偏移5CH和6CH.

  当前只有极少数应用程序使用FCB作为文件和记录的I/O.这是因为FCBs不支持目录树结构.但有些程序检查确省的文件控制块作为分离前二个开关或其它命令行参数的快速的方法.然而,使它自己本身对子进程透明,父进程应该仿效COMMAND.COM那样把命令行前二个参数装入确省的文件控制块.这能使MSDOS的分析文件名功能(INT 21H,功能29H)能方便地使用.

  如果子进程不需要这二个确省的文件控制块,应用程序内存中的参数块中正确的地址会初始化指向二个空FCBs,这些空FCBs是由1字节0和11字节ASCII码空格(20H)组成.

  运行子进程

  当父进程构造完所必要的参数后,它就可以通过中断21H来调用EXEC,各寄存器设置如下:

  AH = 4BH

  AL = 00H (EXEC子功能,装入并执行程序)

  DS:DX = 程序路径名的段地址:偏移址

  ES:BX = 参数块的段地址:偏移址

  从以上软件中断返回后,父进程必须要测试一下进位标志,以此来检测子进程是否实际运行过.如果进位清楚,则成功装入并控制了子进程.如果进位置位,则EXEC功能失败,错误码返回在AX中,可检测原因.通常的原因是:

  指定文件没有找到

  文件找到,但没有足够的内存装入

  其它不常见的服务错误可以从整个系统感到其特征(如磁盘文件或内存中的MSDOS被损坏),使用MSDOS 3.0以后的版本,可以通过调用INT 21H功能59(取扩展错误信息)来获得EXEC更详细的失败原因.

  总的来说,提供给EXEC参数块一个无效地址或参数块本身地址无效并不会引起EXEC错误,但这将使子进程产生一些不可的后果.

2006年3月30日星期四

局域网上的点对点通信

  整理旧文档,发现了这篇很陈旧的论文,这是我十年前写的第一篇论文,也是我第一篇在杂志上发表的论文,同时也是我大学的毕业设计论文。

  十年前,我写毕业设计论文的时候,为了写这篇论文也花费了我不少的时间和精力,整天都泡在图书馆里。今天再看这篇文章,竟然感觉如同隔世的感觉,那时候什么是网络呢?Windows95刚刚发布,WindowsNT和Windows2000都没有普及,网络在那时还是一个神秘而高深的技术,那时我们建立局域网用的一律都是Novell系统,没有图形环境,设置非常繁琐复杂。而现在,这些东西完全都过时了,那时候先进的TCP/IP现在面临其协议不安全、有漏洞的指责,NETBIOS和IPX就早已失传了,十年时间,竟然整个网络技术发生了如此天翻地覆的变化,慨叹,自己都已经快跟不上这个时代了。

  这篇文章还是重新发布一下,以做纪念。

 

局域网上的点对点通信

 

   摘要:本文讨论了在局域网络环境下,实现工作站之间的实时通信的三种方法.重点介绍了基于NetBIOS 及TCP/IP协议实现工作站之间的点对点通信(Peer to Peer), 并给出了设计的应用程序实例.

   关键词:局域网 点对点通信 NetBIOS TCP/IP IPX/SPX

 

一  引 言

   在信息化社会里,人们都希望以快速简的方法获取信息,计算机网络的出现,使人们的这个想法得以实现.通过计算机网络,人们可以方便地实现通讯和共享资源:计算机网络使信息传播和信息处理加工的设备和工具空前紧密地结合在一起,这种技术的进步和发展对提高人类社会信息化水平有着巨大的推动作用.

   但在实际的计算机网络中,往往需要互连来自不同厂家的机器,要具备异 种机的互联能力.由于各厂家的机器有其各自的总线结构,文件系统,输入输出系统和采用的字符集等,因而使这种互联成为一件十分困难的事情.

   另外,从局域网的运行情况来看,以Novell Netware网络为例,文件服务器是网络的核心,其上运行Netware操作系统软件,为网上工作站提供共享资源与服务.因此,文件服务器的好坏对网络的性能极其重要.随着网络的扩大,连接的工作站增多,服务请求也迅速增加,服务器的负载也相应加重,服务器有可能成为网络工作的"瓶茎".

   针对上述情况,本文利用网络上的点点通信思想,在不使用服务器的情况下实现不同工作站之间的文件传输和共享打印.

 

二  局 域 网 概 述

   随着微型计算机技术的迅猛发展和日益成熟,微型计算机的价格在不断下降,因此人们有条件的将十几台微机,外设依网络通信协议连接起来,形成局域网(Local Area Network).它具有以下几个特点:

   1) 采用基带传输,传输速度较高.

   2) 网络覆盖地域较小,可不用调制解调器.

   3) 传输误码率低.

   局域网的功能概括起来可归为以下几点:

   1) 资源共享.包括大容量硬盘,高速打印机,数据及软件.

   2) 电子邮件系统.

   3) 使用分布处理实现负载均衡.

   机算机网络中对于各种约定做了如下定义:将机算机网络同等层间的通信约定称为网络协议.将不同层的通信约定称为接口.到目前为止最有代表性的网络分层模型有两种.其一为国际标准化组织(ISO)所提出的开放系统互连(OSI)七层协议参考模型,其二为美国电气与电子工程师学会(IEEE)802委员会所提出的参考模型.

   (一) ISO/OSI七层协议及参考模型

   OSI参考模型的七层分层结构如图1所示.该模型是按逻辑组合功能来分层的,上一层是建立在下一层的基础上,较高层向较低层提供服务请求,而较低层为较高层提供服务.所谓开放系统是指按照这种模型所构成的网络是可以互连的,是彼此开放的,从而便于世界各地的网络互连.

   OSI模型各层定义如下:

    应用层       网中的网络应用软件在此层运行.

    表示层       辅助用户执行诸如文间传送,程序运行等任务.

    会话层       管理低层与用户之间的连接,是用户到网络的接口.

    传输层       检查网络数据的完整性,必要时将数据分组调整到正确的位   置.设置分组题头,以便将数据组发送到目的地.

    网络层       以分组形式,选择路径发送数据.各分组要穿过两个低层到达目的地.

    数据链路层     管理网络接口处的输入/输出.对原始数据进行组织和检察.

    物理层       定义在网络电缆连接及接线中用的规则与协议.包括例行联络处理及传输规范,还定义了使用的电缆类型及连接器.

   (二) IEEE 802标准局域网络参考模型

   IEEE 802标准遵循ISO/OSI参考模型的原则,解决了最低两层----物理层和数据链路层的功能以及与网络层的接口服务,网际互连有关的高层功能,IEEE 802 LAN 参考模型与ISO/OSI 参考模型的对应关系如图3所示.

   1 IEEE 802 的五个标准文件

    IEEE ( Institute of Electical and Electronics Engincers ),即电气和电子工程师学会,它是一个专业性质的学会.它对OSI模型的低两层即物理层及数据链路层的协议标准进行了大量的研究.IEEE 802标准制定目的是为了在不同的厂商所制造的设备间具有兼容性,从而为使用该网络的用户和设备制造者在付出较小的代价后就能顺利地在这些设备间进行通信.该学会在经过多年的研究和修订,于1984年正式提出了局域网标准的五个标准文件.

   IEEE 802.1     它阐述了802方案与ISO互连参考模型间的关系.

   IEEE 802.2     逻辑链路控制标准.

   IEEE 802.3     采用CSMA/CD访问的总线结构标准.

   IEEE 802.4     采用令牌访问方法的总线结构标准.

   IEEE 802 各标准间的关系如图2所示.

   2 IEEE 802 LAN 标准局域络参考模型 

   从对ISO参考模型的讨论中以然清楚的了解到物理层,数据链路层及网络层共同完成了报文分组的传输功能,因此物理层,数据链路层是必不可少的.但考虑到局域网络的特点,IEEE 802对OSI参考模型作了修正.IEEE 802将数据链路层分为两个子层,即逻辑链路子层(LLC)和介质访问控制子层(MAC).在MAC子层中CSMA/CD,令牌总线(Token Bus),令牌环(Token Ring)等几种介质访问控制方式.在数据链路层同网络层的接口设置了服务访问点(SAP).

 

三  网 络 通 信 及 实 例

   (一) 进程通信

   进程,指程序的一次执行.进程通信指各进程之间共享资源,相互进行数据传输的信息交换方式.OSI的传输层为进程通信提供了服务.

   进程通信的实现方法:

   1) 建立和拆除进程间的连接

   2) 信息传递与控制

   (二) 点对点通信

   从OSI参考模型的应用层来看,可认为网络是由工作站和服务器组成的,但从传输层和网络层的角度看,工作站和服务器没有本质的区别,它们都是连接到网络上的一台机器,都可以用网络地址或名称来代替.它们之间的通信,就是所谓的点对点通信,也叫对等通信.在局域网上,点点通信意味着两个工作站可以直接对话而不用经过文件服务器中转.

   (三) 实例:  Windows 95的点对点网络通信功能:

   Windows 95操作系统的Network Neighborhood(网络邻居)的三个重要的部分是:Netware的客户服务,点对点对等服务,Internet或/TCP/IP服务.

   在Windows 95内建的点对点对等网络功能,可以很容易地在一个小 工作组内共享文间和打印机,而不用文件服务器.Windows 95 比Windows for workgroup3.11最具特色的功能之一是:它有一个大大改进的安全方案,每个用户即可以在用户级又可以在资源级共享文件和打印机等资源.

   在Windows 95下,点对点的对等网络具有更大的灵活性,因为它可在Netware多用户(运行于IPX/SPX或TCP/IP协议下)之间建立点对点对等连接.Windows 95 能做Windows for workgroup 客户能做的每件事,还可以做得更好.

   无论用户选用什么样的平台,他们都可以利用Network Neighborhood非常方便地浏览网络资源.用户选中工作台面上的一个图标即可直接进入Network Neiborhood工作窗口,此后,用户不关心网络连接,驱动器映像,打印机队列等工作,即可连接到任意类型的网络服务器,浏览服务器中的文件或其它共享资源.

   安装对等网络服务功能具体是这样的,从Control Panel中打开Network对话窗口,移动其中的Configuration标签,点中add按扭后,在弹出窗口中选择Client.此后,会弹出一个Select Network Client(选择网络客户)的对话窗口,选中其中的Client for Microsoft Network后,点OK按扭.重新启动机器后,在Network Neighbour hood中将显示同一工作组中共享文件的所有客户.同时,在Network Neighborhood中也列出了网络中的Microsoft,Warp Connect以及IBM LAN Server域名,Microsoft工作组和Netware通过使用全局命名规则(Universal Naming Convention,UNC)而不是通过驱动器映射到的Netware网络服务器.

   文件共享在Configuration标签中设置File and Print Sharing(文件与打印共享)选择项,然后在Access Control(访问控制)标签中选中Share Level Access Control项,为了配置共享选择项,必须返回到Desk top或Explorer中,用鼠标右键在准备共享资源(如键盘,光驱)上点一下.此后,会弹出一共享设置Sharing对话框.如使用Netware网络,那么结果是:要么网络中其他用户都可以访问你的共享文件,要么无人可访问.

 

四  点 对 点 通 信 的 实 现

   局域网中工作站之间的通信程序的开发一般通过四种途径:第一种是通过改造网络原有通信软件来实现.但这种改造必须以对该软件充分了解为基础,否则改造后很难保证不影响网络的整体性能,甚至会造成系统运行不可靠,而改造后的通信质量不一定理想.第二种是利用Novell网本身的网络协议IPX/SPX来实现,由于这种方法开发比较麻烦,采用的并不多.第三种是通过NetBIOS功能调用来实现,NetBIOS是PC LAN的通信接口标准,广泛适用于多种微机网络,使得以它为基础的设计和应用开发可移植性好.它不依赖于任何网络硬件,是一个介于网络硬件和用户应用程序之间的接口协议.其通信原理是:两个要进行通信的工作站通过名字建立一个虚电路,然后向相应的虚电路号发送或接收信息,这样通过虚电路实现了两个工作站之间的对等通信.利用NetBIOS实现工作站之间的实时通信,功能比较强,编程实现比较容易,所以应用比较广泛.第四种是通过TCP/IP协议来实现.下面我们将详细讨论各种技术的实现.

   (一) 基于IPX/SPX 的实现技术

   由于IPX/SPX不能支持多协议之间的通信,因此本文略之.

   (二) 基于NetBIOS的编程接口

   NetBIOS是Network Basic Input/Output System 的缩写,即网络基本输入输出系统,它是一种应用程序的接口.用户可以调用各种NetBIOS功能,而无需涉及到各种最低层的通信协议,从而实现数据源地与数据目的地之间的信息交换.

   1 NetBIOS概述

   NetBIOS是IBM公司于1984年首次推出的.它可以支持各种著名的通信协议,如TCP/IP,MAP/TOP,XNS,IEEE和OSI等,不仅适用于DOS环境,还可以用在UNIX,OS/2,WINDOWS环境.

   NetBIOS作为一种网络支撑软件,在ISO的开放系统互联(OSI)模型中的位置如图3所示.

   2 NetBIOS的基本概念

   命令

   NetBIOS的功能是由执行一系列命令来完成的.有Wait和No_wait两种形式.

   名字

   NetBIOS是一种按名字工作的系统,每一网络工作站和服务器都有一个(或几个)名字,每个节点还有一个永久节点名,它是在网络适配卡上的6字节网络地址前面再添上10个字节0构成.

   数据报和会话

   数据报是一种无连接的服务,即各个数据报之间互相独立,单独传送.在网络上任意两个名字之间可以建立一个会话,或多个会话.

   网络控制块(NCB)

   应用程序调用NetBIOS命令,必须先构造一块网络控制块(NCB),然后执行一次5CH中断.

   信息帧

   在网络中传递的信息是以帧的形式组织的.NetBIOS根据用户的命令,NCB以及它所知道的有关会话和名字的情况自动生成和管理信息帧,用户不必直接过问.

   服务器报文块

   3 NetBIOS设计要点

   在设计两个或多个工作站之间对话的时候,要注意处理好以下几个问题:

   1) 选择通信方式

   网络中的通信可以采用数据报方式,也可以采用会话方式.

   会话方式的特点是由通信协议保证每一报文能够正确地送到目的地.如果报文在传送过程中发生了差错,则通信协议会自动地进行重发,加以改正.而且,如果你发出的报文不止一个,那么通信协议还能够保证接收到的报文次序和发送时的次序一致.这些保证都是对用户应用程序透明地进行的,用户完全不需操心.但是,会话方式的主要缺点是过程比较复杂,在发送报文之前先要建立会话,送完报文之后又要撤除会话.因此,会话方式比较适合于点到点的多次往复式的对话.

   数据报的特点正相反.它是把每一个报文作为一个独立的数据报处理,从而免除了建立和撤除会话的麻烦.但正因如此,它不能保证接收到的报文次序和发送次序一致,甚至不能保证每一个报文都能够正确无误地达到收方.在报文丢失或发生错误时,系统不向发送方提供出错信息.如果你所设计的对话环境由一系列互不相关的报文组成,或者每次对话都很简单,那么采用数据报传送可以大大加快对话的速度.另外,如果用数据报传送比较重要的报文,为了防止差错和丢失,可以在应用程序中为报文加上查错和序号功能.

   2) 选择命令返回方法

   执行NetBIOS命令可以采用等待方式和非等待方式.对于非等待方式,又可以有两种不同的做法:一种是轮询方法,即循环检查网络控制块(NCB)中的最终返回代码字段,当它的值从0xFF变为其它值时,表示该命令执行完毕. 另一种是异步事件处理方法,即告诉NetBIOS,在当前命令执行完毕后存放在NCB的POST程序地址字段中的程序指针,继续执行一个指定的程序段.需要指出的是,这两种做法虽然难易程度不同,但都是在后台进行.对于前后操作,都是立即返回用户程序,不必等待命令完成.它们的主要差别在于对网络负荷的影响.比如,一个工作站发出一条命令,要求另一个工作站执行一项比较费时的任务.如果这个工作站采用轮询方式,持续不断地询问对方是否完成,就会极大地增加网络的负荷.这时,尽管轮询比较容易编程,那也不是一种好的选择.

   4 NetBIOS基本程序

   1)调用NetBIOS

    要调用一NetBIOS功能,需要做以下三件事:

       (1) 构造一个NCB,包含所有需要告诉NetBIOS的信息.

 

#define USGC unsigned char

#define USGI unsigned int

#define USGL unsigned long

 

struct NCB  {

   USGC NcbCommand;

   USGC NcbRetCode;

   USGC NcbLsn;

   USGC NcbNum;

   char * NcbBufferOffset;

   USGI NcbBufferSegment;

   USGI NcbLength;

   char NcbCallName[16];

   char NcbName[16];

   USGC NcbRto;

   USGC NcbSto;

   char * NcbPostRtnOffset;

   USGI NcbPostRtnSegment;

   USGC NcbLanaNum;

   USGC NcbCmdCplt;

   char NcbReseredArea[14];

} ZeroNcb;

 

       (2) 把网络控制块地址写入ES:BX寄存器,作为指向该NCB的远程地址指针.

       (3) 执行5CH中断.执行中断时,NetBIOS自动进入ES:BX寄存器指定的地址,读出网络控制块,得知一切有关该操作的信息. 下面是设置指针和执行中断的程序段:

void NETBIOS  (struct NCB *NcbPtrNear)

 

{

   union REGS InRegs,OutRegs;

   struct NCB far *NcbPtrFar=(struct NCB far*)NcbPtrNear;

 

   segread(&SegRegs);

   SegRegs.es=FP_SEG(NcbPtrFar);

   InRegs.x.bx=FP_OFF(NcbPtrFar);

 

   int86x(NetbiosInt5c,&InRegs,&OutRegs,&SegRegs);

 

}

  

   2)定义NetBIOS命令

   在程序段中还包括对所有NetBIOS命令(包括WAIT和NO_WAIT)

   3) POST程序

   在执行非等待命令时,可以把一个POST程序的地址告诉NetBIOS,然后直接返回前台操作.当后台命令完成时,它会自动转去执行POST程序.从这段描述可以看出,我们必须把POST程序编成一个中断处理程序.

 

unsigned  es_reg,bx_reg,msg_received_flag;

NCB far *posted_ncb_ptr;

void interrupt POST (void)

{

    es_reg=_ES;

    bx_reg=_BX;

    posted_ncb_ptr=MK_FP (es_reg,bx_reg);

    msg_received_flag=TRUE;

}

 

   4)数据报服务

   假定A工作站和B工作站之间以数据报方式通信,其主要步骤如下:

    工作站A               工作站B

   增加名字A              增加名字B

   发送报文给B  ----------->      收到一个报文

   收到一个报文     <------------  发送报文给A

   删除名字A               删除名字B

   5)会话服务

   A工作站和B工作站之间以会话方式通信步骤如下:

    工作站A               工作站B

   增加名字A               增加名字B

   Listen                Call  A站

   发送报文给B  ----------->      收到一个报文

   收到一个报文     <------------  发送报文给A

   Hang up  B站             Hang up  A站

   删除名字A               删除名字B

 

    5 Windows 通信程序的特点

   在Windows中,由于它是非抢先多任务,所以NetBIOS最好用异步方式(非等待式),CPU发出NetBIOS调用后,处理其他消息, 当NetBIOS完成后会自动执行后置例程POST, POST 通过 PostMessage 把一条用户定义的消息放到合适的队列中.Windows 应用程序接到该消息后再处理接收到的网络数据.

   其次,由于Windows的代码段和数据段可移动,这对异步NetBIOS是致命的,当异步NetBIOS命令发出后,如果代码段或数据段移动,命令完成后,NCB所指示的缓冲区已发生变化.解决的方法是使代码段和数据段不可移动.在DEF文件中定义如下:

     CODE   PRELOAD   FIXED

     DATA   PRELOAD   FIXED   SINGLE

 

   6 点对点通信程序源代码. (基于NetBIOS)

   完整的源程序见附录.

 

   (三) 基于TCP/IP协议的编程接口

   1 TCP/IP简介

   TCP/IP的历史要追溯到70年代中期,当时ARPA为了实现异种网之间的互连(interconnection)与互通(intercommunication),大力资助网间网技术的研究和开发,于1977年到1979年推出目前形式的TCP/IP体系结构和协议规范.到今天,TCP/IP技术以及Internet网间网已经为广大计算机工作者,机算机厂商和机算机用户所接受.据统计,到1990年,Internet以包含遍布欧美的五千个活动网络,超过三十万台机算机.作为一种事实上的工标准,TCP/IP技术方兴未艾.

   2 TCP/IP的网络分层结构

   对TCP/IP协议来说,TCP提供传输层服务,IP提供网络层服务.TCP/IP协议组(或Internet协议组)的分层结构及其与OSI模型的对应关系如图4所示.图中有关协议的名称及其基本含义如下:

   (1) TCP.  为传输控制协议(Transmission Control Protocol).它是提供给用户进程的一个可靠的全双工字节流的面向连接的协议.大多数Internet应用程序使用TCP.因为TCP使用IP,所以整个Internet协议组也常称为TCP/IP协议组.

   (2) UDP. 为用户数据报协议 (User Datagram Protocol).

   (3) ICMP. 为网间报文控制协议 (Internet Control Message Protocol).

   (4) IP. 网间协议 (Internet Protocol). IP协议是为TCP,UDP和ICMP提供分组发送服务协议.

   (5) ARP. 地址转换协议.

   (6) RARP. 反向地址转换协议.

   3 Socket编程界面

   (1) Socket 原理

   Socket编程界面由4BSD UNIX首先提出,目的是解决网间网进程通信问题.Socket接口为进程间通信提供了一种新的手段,它不但能用于同一机器中的进程之间的通信,而且支持网络通信功能.Socket具有类型,反应了对用户透明的通信特性.

   一个完整的Socket连接用一个相关描述:

       { 协议,本地地址,本地端口,远地地址,远地端口 }

   Socket 是面向客户-服务器模型而设计的,针对客户和服务器程序提供不同的Socket系统调用.

   (2) Socket系统调用

   不管Socket内部机制如何,它提供给应用程序员的最终界面是一组系统功能调用.下面,我们一一给出重要的Socket系统调用.

     1. 创建 Socket ----- socket()

     调用格式如下:

       sockid = socket (af,type,protocol)

    af : 地址族,指本socket所用地址类型.

    type :  类型,指创建socket的应用程序所希望的通信服务器类型.

    protocol : 协议,指本socket请求的协议.

     2. 指定本地地址 ---- bind()调用

     bind()将本地socket地址与所创建的socket联系起来,即将本socket地址赋予socket,以指定本地半相关.bind()的作用相当于给socket命名,调用格式为:

         bind (sockid,localaddr,addrlen)

     sockid : socket号.

     localaddr : 本地socket地址.

     addrlen : 地址长度.

     3. 建立socket连接 ---- connect () 与 accept ()调用

     这两个系统调用用于完成整个相关的建立.其中connect用于建立连接 .调用格为:

         connect (sockid,destaddr,addrlen)

     destaddr : 指向对方socket地址(信宿地址)结构的指针.

     accept : 用于面向连接的服务器,其调用格式为:

         newsock = accept (sockid,clientaddr,paddrlen)

     clientaddr : 指向客户socket地址指针.

     paddrlen : 客户socket地址长度.

     4. listen() 调用

     此调用用于面向连接服务器,表明它愿意接收连接,listen()在accept()之前调用,格式为:  

         listen (sockid,quelen)

      quelen : 请求队列长度.

     5. 发送数据 ---- write(),writev(),send()与sendto(),sendmsg()

     用于socket数据发送的系统调用一共有五个,其中三个,write(),writev()和send()用于面向连接传输,其余两个用于无连接传输.面向连接的调用可以不指定信宿地址,而无连接的调用必须指定.假如无连接socket的双方均调用过connect(),可以认为是建立有连接的socket,也可以面向连接调用发送数据.

     三个面向连接调用三者的格式大致相同:

     write (sockid,buff,bufflen) : 缓冲发送

     writev (sockid,iovector,vectorlen) : 集中发送

     send (sockid,buff,bufflen,flags) : 可控缓冲发送

     其中buff指向发送缓冲区的指针,bufflen是发送缓冲区大小.

     用于无连接数据发送的调用有两个:

     sendto (sockid,buff,bufflen,flags,dsadd,addrlen)

     sendmsg (sockid,message,flags):可控集中无连接发送.

     6. 接收数据 ---- read(),readv(),recv()与recvfrom(),recvmsg()

     接收数据与发送数据系统调用是一一对应的,两者参数的最大区别是,前者buffer是一个指针,其所指单元初值为欲读数据长度,调用后的值是实际读出的值.

   4 客户--服务器模型的Socket实现框架

     1)客户--服务器模型时序图

     下图是面向连接客户--服务器模型的典型时序图

       服务器                 客户

       socket()                socket()

       bind()                bind()

       listen()                

      accept()   等待客户连接请求      

     阻塞   <━━━━━━━━━━━━━━━ connect()

       read() <━━━━━━━━━━━━━━━> write()

 

     2)服务器socket地址的确定

     在客户--服务器模型中,所有的作用者都是客户首先发起的(如连接请求,服务请求等),因此客户必须要知道服务器socket地址,另外,客户调用服务器之前,可以在命令行中给出服务器所在主机的域名,根据域名可以获得服务器主机的地址,系统调用为:hp=gethostbyname(host).其中host可以是服务器主机域名,返回hp是一个指向主机地址结构的指针.

 

五  结 论

   综上所述,TCP/IP对于异种机具有极强的互连能力,很可能成为未来网络协议的标准,其通信编程有一整套方便实用的工具.因此,用其开发通信软件方便,容易,可升级.

   而NetBIOS是一种可加载模块,其特点是可方便地实现不同协议之间的通信,其通用性极强,可方便地在不同局域网间移植.

   以上两种方法各侧重点不同,而近年来由于Internet的兴起,TCP/IP逐渐变得重要了。TCP/IP使得互连UNIX终端,WINDOWS终端以至MAC终端成为现实。成为世界上最大的网络。目前,世界上各大公司正争先恐后的开发Internet上的资源.因此可以预见在不久的将来,以TCP/IP为基础的点点通信必将成为网络通信的重要手段.

  

                参 考 文 献

1. 顾隽修 等编著   <<计算机局域网络原理与应用>>   中国广播电视出版社   1993

2. 陈洛资 等编著   <<计算机网络软件设计,开发与编程>>   科学出版社   1994

3. 汤毅坚 编著    <<计算机实用网络编程>>   人民邮电出版社   1993

4. 张公忠 等编著  <<Novell 网组网原理与实用技术>>   清华大学出版社   1992

5. 徐建平 岳东 编著  <<Novell 网络原理,操作及开发指南>>  电子工业出版社  1994

6. 汤岳清 编著   <<Novell 网络及其互联技术>>   电子工业出版社   1992

7. 周明天 编著   <<TCP/IP网络原理,操作及开发指南>>   清华大学出版社   1993

8. Tim Farrell,Runnoe Connally  <<Windows 3.1 编程指南>>   清华大学出版社  1994

9. Daniel Appleman  <<Visual Basic 与 Windows API 接口大全>>   电子工业出版社  1995

10. 陈佳海 等编著   <<Visual C++ 程序开发指南>>   科学出版社  1995

11. 唐文卫 鲍敏   Novell 网上的点对点通信   <<微计算机应用>>   1995(6)

12. 邱勇攀   基于IPX的工作站实时通信的实现   <<微计算机应用>>   1995(2)

2006年3月29日星期三

生成Feed的代码进行了修改

  今天我将主要的几个网站的Feed生成代码都进行了一些修改。

  我也是不得不这么做。因为我发现现有的Z-BLog写的TAG始终无法被technorati获取,然而别人用WordPress写的Blog里的TAG却可以被technorati获取,我自己也手动Ping了technorati,但发现也没有用,只好仔细分析其中的原因了。

  我仔细分析了一下WordPress和Z-Blog的代码,我发现在Feed生成上有一点不同,Z-Blog缺少了几个东西,有可能和这个有关,于是我就修改了一下Z-Blog的rss相关代码,生成和WordPress类似的feed,早上修改的代码,没想到晚上立刻就生效了,新发布的日志的TAG都被收录了,看来我修改的是正确的,只可惜过去一年多的日志里面的TAG都没有被收录。不过我也想到了补救办法,我打算自己再写一个程序,在以后的10天内分别将以前的四百多篇日志提交到technorati上。可惜啊,要是我一早发现这些原理,就不用这么麻烦了。

  另外我给我另外的网站也生成了Feed。Write100的feed原先是使用OBlog 3.12自带的,地址是http://feeds.feedburner.com/write100,但我发现OBlog的Feed生成代码根本写的就有问题,日期的格式不是RFC-822的日期格式,feed合法性校验都无法通过,我只好在手动修改一下里面的代码,同时也不由地感叹,国内地一些开发者总是在开发一些花里胡哨的东西,却在一些最基本的功能上马马虎虎,没有国外开发团队的那种专业性,这样只能和国外的系统比如WordPress差距越来越大。

  当然,对于feed能够产生的实际功效,很多人也在怀疑,而且feed是否是广告商的恶梦,是否能带来更大的流量,也是一个有争议的话题,不过,只要feed不给我的网站带来负面影响,我也是乐于将原先的WEB 1.0的网站增加上feed的。

  最后,介绍一个校验feed合法性的网站:http://feedvalidator.org/ ,用这个地址可以校验feed语法是否正确。

2006年3月27日星期一

祭父

  今天是我父亲的两周年祭日,两年前的今天,父亲突然瘁死在交大附属二院。

  我父亲做了几十年的大学老师,是一个典型的知识分子。具有知识分子的清高和自负。晚年工作上很不顺心,因为我父亲的正直,看不惯单位里的一些头头私设小金库,侵吞国有资产,而成为某些人心中的眼中钉。知识分子对于官场的黑暗和邪恶往往估计不足,我父亲吃了很多亏,心情十分不好。

  我父亲对自己身体太自信了,当一只眼暂时失明的时候才住进医院,住院才一星期,就花费了父亲数个月的工资,可惜的是医院依然没有放过我父亲,就在住院的第六天,我父亲就突然瘁死在病房中,终年59岁。我永远也忘不了那个医院-西安交大附属二院,从某种意义上来讲,西安交大附属医院和我有杀父之仇。

  我想不通,这世界发疯了吗?这些医院知道赚来的钱是沾满鲜血的吗?他们对得起自己的良心吗?他们感觉不到死尸的沉重吗?他们不怕这世界有报应吗?

  我们国家的很多改革都很不对劲,教育产业化让穷人上不起大学,医疗产业化让普通人看不起病。我父亲的命运也真验证了那句话:“小病忍、大病挨、重病才往医院抬”,“辛辛苦苦几十年,一病回到解放前”。医疗产业化所引发的种种问题,不得不让我们质疑:医院的存在究竟是为了救人还是为了杀人

  这的确是个邪恶的世界,什么样的魔鬼才能创造这样的邪恶帝国?恐怕撒旦也会自愧莫如,他们的灵魂是魔鬼缔造的,他们在毁灭我们几千年的中华文明,我们却无能为力。但人总有一死,那些双手沾满鲜血的刽子手们迟早难逃一死,希望那些老东西们快些下地狱吧。我们还有后代,我们不能让我们的后代也像我们这样生活,在谎言、欺骗、恐惧的白色恐怖下度过这一生。

2006年3月26日星期日

风之花-Windflowers

  今天翻看以前的文件,无意中发现了一首好听的老歌:齐秦齐豫版的Windflowers(风之花),查看了歌曲文件的日期,竟然是1998年的。

  传说希腊神话中有一个深得太阳女神阿波罗喜爱,名叫风信子的年轻美男子,被充满醋意的西风神苏菲洛误杀,风信子的血泊中片刻就长出了一种神奇美丽的花,心痛着的阿波罗女神把这朵盛开在血泊中的美丽的花朵命为风信子花,作为情侣间守节的信物。

  Windflowers的歌词中父亲以一过来人的身份,轻轻地告诉儿子,爱情虽然甜美却易逝去。

  “不要去靠近风之花,那种古老的风之花,一旦靠近了就会离不开它,就会时时地追逐它,使自己痛苦。但是我没有听话。果然,我如今再也离不开它了......”

  Windflowers,my father told me not to go near them,he said he feared them always,and he told me that they carried him away.

  Windflowers,beautiful windflowers, I couldn''t wait to touch them, to smell them I held them closely, and now I cannot break away ,their sweet bouquet disppears,like the vapor in the desert,so take a warning, son.

  Windflowers,Ancient windflowers, their beauty captures every young dreamer,who lingers near them, but Ancient windflowers,I love you.

  Windflowers,my father told me not to go near them,he feared them always, said they carried him away. windflowers,I couldn''t wait to touch them, to smell them,I held them closely, now,I cannot break away,their sweet bouquet disppears, like the vapor in the desert,take a warning,son. windflowers,their beauty captures every young dreamer, who lingers near them,Ancient windflowers,I love you.

  风之花,风之花,父亲对我说别走近它,他说他总有些害怕,他说他迷恋过它

  风之花,美丽的风之花,我急切地要抚摸它,贴近脸颊闻久嗅,如今我已无法自拔,它的芳香犹如水汽,沙漠中蒸发,所以,孩子,听句劝告吧

  风之花,古老的风之花,美丽迷惑了每个年轻的梦人,久久的徘徊在它的身旁,而我爱你,古老的风之花

  渥特豪斯 (John William Waterhouse 1849-1917) 的名画《Windflowers》风之花

Windflower

  美丽的少女在遍开花朵的林间采摘银莲花,头发和衣裙在风中飘拂,银莲花的希腊语是风的意思,风之花是一种凄凉而寂寞的花。

  《Windflowers》是一首古老的外国歌谣。这首歌曲的演唱者是Seals和Crofts,一个嗓音低沉,充满了沧桑感;一个天真烂漫,充满了梦幻和活力。先是的弦乐,风琴和键盘的合奏,然后一把带着俄罗斯民谣色彩的木吉他轻轻的和进来,民谣歌手充满感情的吟诵,演绎,梦幻般的柔情似水,清新,舒畅,纯净而荡埃涤尘。

  齐秦齐豫姐弟版低吟浅唱,婉转唯美,有如天籁,直触人心!

2006年3月25日星期六

Google和百度收录网站页面的比较

  Google和Baidu收录网站页面的标准是不同的。我用一句话来形容,就是Google更乐于收录大站的页面,百度则乐于收录新站的页面。

  为此我做一个实验:先申请了一个新域名,在上面放一个网站,然后不在其他任何网站做链接,而直接往百度和Google搜索引擎的提交页面进行提交。一个月过去了,百度收录的网页是24,900篇,Google收录的网页是0,这证实了我以前的猜测。

  这说明了什么呢?说明百度比Google好吗?绝对不是的。因为Baidu和Google收录页面的标准是完全不同的。

  Google是按照网页级别(PageRank)来收录的,只要网站有一定的网页级别,Google会快速收录的,而没有网页级别的网站,Google则坚决不去收录。Baidu则很夸张,采用的是来者不拒,多多益善的原则,无休止的进行收录。Baidu的这种不按网页级别的收录方式其实有很大的恶果,最主要的恶果是造成大量的垃圾网站流行,因为只要做一个垃圾站,Baidu就会立刻收录(25000页以内),这等于变相的鼓励大家去做垃圾站,去盲目采集。当垃圾站横行的时候,Baidu再通过人工的方式封站,甚至一些百度业务员对于大流量的网站还会要求其站长办理百度竞价排名。

百度谷歌

  这两种收录方式哪种更好呢?我个人认为Google的这种收录方式是比较科学的。因为互联网上的页面是个天文数字,收录应该是有选择的收录,好的网站则多收录,新站则应该少收录,等其慢慢知名了以后再多收录,这样也提高了效率,让用户搜索到更好的页面而不是更多的页面。如果对于新站不做分析就快速收录,那么会使得从技术上对抗恶意网站作弊(SEO)变得非常困难,Google通过给予新站给出一定的“考察期”来分析这个新站是否是作弊的垃圾站,而百度就只能依靠人工方式手动地删除垃圾站。对于收录网站的具体操作上,Google的爬虫显得较为“体贴”站长-Google爬虫占用服务器的资源非常少,通常是先用head来查看网页是否更新,如果更新了再抓取整个页面,这种方法耗费流量较少。而百度则不管三七二十一上来就抓整个站,有时甚至不遵守robots规则,而且其爬虫数量非常庞大,对于页面较多的网站通常会耗费惊人的流量,并且常常造成恶劣的后果。

  当然,百度这种“贪婪”爬虫抓取方法,虽然会让用户能够在百度搜索出一些Google里搜索不到的页面,但这实在是损人利己。其带给网站站长不少负面效果:服务器和带宽资源过度消耗,垃圾站被变相鼓励了,原创的有特色的网站则被边缘化,MP3音乐网站则更苦不堪言-自己的MP3被百度盗链后带来大量文件下载却没有带来页面访问。

  因此,中国的网民也出现了很奇怪的现象:大量的新网民和菜鸟新手喜欢用百度搜索,因为百度往往搜索到很多别处搜索不到的页面,但内容的匹配度则令人质疑,而专业人士和老鸟则更喜欢用Google,个人站长则普遍和百度有“个人恩怨”。因此百度在业界的Blog以及社区中口碑都不太好,但在普通的低层次的网民心中却不错,这些大量的普通网民给百度带来了大量流量。

  注:本文已发布于2006年4月17日第14期《计算机世界·华南市场》