NetBios通信程序设计基础

来源:互联网 发布:c语言op用法 编辑:程序博客网 时间:2024/05/01 05:49

 1. 概述:

  NetBios是PC机网络中用得最为广泛的网络协议之一,大多数的局域网(LAN)产品,如Microsoft LAN Manager,Novell NetWare和Banqan Vines都支持NetBios。因此,将NetBios作为网络协议的优点是:基于NetBios网络应用程序并不需修改便能在其它各种网络环境下运行,用户将享受到极大的灵活性,既使改用了其它网络也能继续使用原先的应用程序,避免了重复投入。本文就NetBios协议及Windows下NetBios的编程作些探讨。
 
  2.NetBios原则:

  NetBios(NetWork Basic Input Output System,即网络基本输入输出系统)规格说明最初是由IBM定义的,现已成为网络应用程序的事实标准。但是,术语“NetBios”现仍用来代表下面三个概念:

  ·网络通信开放系统互连(OSI)模型中的会话层

  ·用来在会话层和更高层之间传递数据和命令的协议

  ·由特定的程序设计接口组成的协议的实现
 
  NetBios提供了会话层

  NetBios提供了OSI模型的会话层接口(有关OSI模型的详细介绍,参见IBM局域网技术参考手册)。OSI是由OSI(International Standards Organization,国际标准化组织)提出的参考模型。该模型按层次抽象出了网络软件和硬件,它建立在两个简单的概念上。第一个概念是同层通信,即每一层都假定它正同远程机器上的对应层进行通信。也就是说,每一层都不知道远程机器上其他层的情形,它只管同远程机器上对应层按照标准的或协商好的协议进行通信。第二个概念是网络中的每一层为其上一层提供服务。每一层都提供了一系列上一层的接口,但隐藏了实现细节。一台机器上的所有层加在一起,便成了一个栈。

  同层通信是通过数据封装实现的。发送数据时,第一台机器上栈中的每一层(服务请求者)都将要发送的数据组织成一帧,并将其传给低一层(服务提供者),帧中含有只有第二台远程机器上对应层才明白的头信息。第二台机器上的对应层接收到一帧后,将读取其中含有的头信息并进行解释,再据此进行相应的控制。最后,对应层将从帧中去掉头信息,还可能将包中的其余内容传送给上一层,如图所示:
 
  每一层都可为上一层提供连接式服务或非连接式服务。连接式服务类似于打电话的两个人都不知道居于其间的电话网的电话连接,提供给他们使用的是“虚连接”,信息就在虚连接上来回传递,并且秩序井然,全无差错。也就是说明,连接式服务提供了发送方和接收方之间的虚电路。

  而非连接式服务则类似于邮政服务所采用的方法。在这种方法下,每一封信都是独立地送达接收方,彼此之间没有关系。事实上,在同一时刻发出的寄往同一个收信人的两封信,其传递路线可能截然不同。非连接式服务提供了“数据表”(datagram)服务。每一个数据表包在网络中的传递方式都是独立的,不受下一包或上一包的影响。

  下面摘要列出OSI模型每一层的功能,具体如下:

  ·物理层负责通过物理通信介质,如微波、双绞线或同轴电缆等,传送数据。网络的拓扑结构也是物理层的一部分。在物理层上传送数据可能会发生差错,差错检测和修正服务由较高层提供。

  ·数据链路层在物理层上传送数据,并通过差错控制方法达到传送无差错的目的。

  ·网络层负责决定完整的网络传送路线,通信双方要么是同一LAN中的两个通信站,要么是不同网络中的两个通信站。

  ·传输层为会话层提供了“一端到另一端”或“源到目标”式的数据传输信道,隐去了网络本身的细节。它能将一个数据包分成多个包,以适应网络层的限制。它还能将在同一物理信道上传输的多个数据流组合起来。

  ·会话层为两个通信处理(位于表示层上),提供了“会话能力”。它首先通过传输层服务连接到远程处理上,然后再为上一层管理会话。因此,尽管传输层可能只提供非连接式服务,但会话层能为上一层提供连接式服务。简而言之,NetBios提供的就是会话层服务。

  ·表示层主要与数据的表达与变换有关,其作用是使数据能在不同平台上来回传送(例如,在Digital VAX系统和IBM System/360间来回传送)。

  ·应用层含有的是诸如FTP或Telenet之类的应用程序,这些应用程序要使用其他层提供的服务。

  OSI模型勾勒出了复杂网络的框架,它能用来连接任何两台或更多台计算机。大多数个人机和UNIX工作站都彼此相连,构成了一个个局域网。但是,目前的大多数局域网都采用了修改后的OSI模型。对于OSI模型的最底两层,它们采用的是ANSI/IEEE 802-1995标准,甚至是更为简单的802标准。该标准先是被ISO采纳,后又批准作为国际标准(ISO 8802:1989)使用。图比较了802标准和OSI模型的最底两层。(ANSI代表美国国家标准化学会,IEEE代表电子电气工程师学会)

  802标准实际上是一个标准集,其中每一个标准都详细描述了通用局域网的一个特定部分。综合介绍802标准的部分称为802.1,它包括了所有802标准。802.2标准称为逻辑链路控制(LLC)标准,它为在两个网络中的物理站之间建立“逻辑”链路而定义了低层协议。网络拓扑结构由介质访问控制(MAC)层定义,具体可定义成CSMA/CD,Token Bus或Token Ring,这三者在802标准中分别称为802.3,802.4和802.5。Ethernet是一种很流行的CSMA/CD拓扑结构,它兼容于802.3标准。对应于802.X标准ISO已经相应发布了8802.X标准。虽然802标准没有定义数据链路层以上的各层,但是,事实上存在着一个标准,该标准就是NetBios,它定义了一个协议,并提供了会话层服务。

NetBios协议

  我们已经说过,NetBios提供了会话层服务,它按对应层能理解的特定协议同远程机器上对应层进行通信。因此,NetBios还指定了一系列协议命令和网络层协议,以允许两台远程机器进行通信。我们将这些协议的实现称为NetBios驱动程序。NetBios驱动程序可以是能够按照指定的NetBios协议同另一远程NetBios驱动程序进行通信的任一程序,处理或设备驱动程序等。下面将要介绍,NetBios驱动程序还提供了NetBios接口。
NetBios协议由一系列协议命令组成,每一条协议命令都对应于要在网络上传送的一帧。如图所示,每一个NetBios帧都要封装在LLC帧中,而LLC帧又要封装在MAC帧中。每一条NetBios驱动程序命令都将导致驱动程序向一个或多个已知或未知的接收方NetBios驱动程序发出这样的一个或多个NetBios包。
 
  NetBios接口

  前面已介绍过,NetBios层提供的是会话层服务,其实现称为NetBios驱动程序。但是,如果只有这些驱动程序或NetBios层本身,并不能实现通信。若想实现通信,NetBios层的客户机应当访问NetBios提供的服务具体访问可经由程序设计接口完成。

  NetBios提供了一系列标准的程序设计接口,应用程序可以利用这些接口在局域网间进行通信。大多数局域网软件商(例如Microsoft,IBM和Novell)都提供具有这些接口的NetBios驱动程序。因为这些接口事实上已成了标准,所以,将基于NetBios的应用程序从一个局域网软件环境不加修改或稍加修改地移至另一个局域网软件环境中运行是可行的。再说一遍,支持这些接口是NetBios驱动程序的义务,由NetBios驱动程序负责将每一个NetBios接口调用转换成相应的一个或多个NetBios的协议包。

  下面按照它们所提供的服务分类介绍一下NetBios接口。说明一下,这里所说的实体是指,利用NetBios接口同其他实体(包括本身)进行通信的任何处理,或关联着NetBios名的任何处理。NetBios名是个16安节域,多余部分用空格(20H)填充。
 
  命令服务

  NetBios为在网络上增加、删除、查找已命名NetBios实体提供了相应的接口。任何NetBios实体都可通过NetBios Add Name(增加名)接口使自己同一个NetBios名关联起来,该名在整个网络中具有唯一性。比如说,注册进入网络的每一个用户通常都有一个唯一的NetBios名,以便彼此之间能够区分开来。同时,一个实体可以登记成一个组名的一部分,多个实体可以将它们自己同这个组名相关联。例如,某一公司财务科的所有会计可以共享一个组名(或称别名),如“ACCOUNTS”,其后,发往该组名的消息将同时发往所有会计。当然,每一个会计还可有一个唯一的名(如注册ID或用户ID),以便发送和接收其个人消息。
 
  会话服务

  NetBios为创建、破坏或使用设置在任二个NetBios实体之间的会话提供了一系列接口。若想使用会话管理工具,NetBios实体首先应当通过Add Name接口将自己同一个唯一名关联起来。在两个实体间设置了会话后,他们可以使用各自喜好的Send和Receive接口发送和接收数据缓冲区,缓冲区最大可达128KB-2字节=131070字节。大多数NetBios应用程序都利用这些服务来发送和接收数据包。
 
  数据表服务

  NetBios提供了一系列接口,来发送和接收称为数据表(datagram)的数据包。并不能保证数据表一定能成功地发送和接收,NetBios只是简单地尽其最大的能力发送和接收实体所提供的数据表。数据表最大可有64KB-1字节=65535字节长。可发送给一个实体,也可以广播方式了送给网络中所有实体。
 
  杂务服务

  为获取安装在结点上的网络适配器卡的状态和动态复位适配器提供了相应的接口,它还为取消实体先前发出的命令提供了相应的接口。
 
  NetBios程序设计

  前面根据OSI模型讨论了一般的网络规则以及NetBios提供的服务,还介绍了NetBios提供的网络应用程序可用来进行网络通信的大量接口(由NetBios驱动程序实现),这里,再介绍一下如何在Windows应用程序中使用这些接口。

  NetBios程序设计中最容易混淆的是,并不是每个NetBios接口都有一个API函数,取而代之的是,Windows只提供了一个函数(NETBIOSCALL),这个函数以一个数据结构作为输入,虽然数据结构中的字段是固定的,但程序设计人员可以通过一个特定字段? ? 称为命令字段? ? 的值,来表明想使用哪一个NetBios服务。下面列出数据结构中的诸字段,说明每一个字段的含义,并给出一个使用NETBIOSCALL的样本代码段,最后还要讨论一下NetBios命令的异步和同步执行。
 
  NetBios控制块

  NetBios控制块(NCB)是所有NetBios应用程序都要用来访问NetBios服务的一个程序设计结构,并且是唯一的一个。设备驱动程序也使用类似的结构。NetBios控制块的C结构如下:

typedef struct tagNCB {
BYTE ncb_command;
BYTE ncb_retcode;
BYTE ncb_lsn;
BYTE ncb_num;
DWORD ncb_buffer;
WORD ncb_length;
BYTE ncb_callName[16];
BYTE ncb_name[16];
BYTE ncb_rto;
BYTE ncb_sto;
BYTE ncb_post;
BYTE ncb_lana_num;
BYTE ncb_cmd_cplt;
BYTE ncb_reserved[14];
} NCB, * PNCB;

  下面介绍每一个字段的具体含义。
 
  ncb_command字段

  每一个发往NetBios的NCB都代表一项要执行的动作,具体执行哪项动作,由ncb_command字段的取值决定。NetBios命令的使用方式有两种,即同步和异步,同步命令将阻止提交处理的执行,直到该命令执行完毕。而异步命令由NetBios在内部排队,并不阻止执行。命令执行完后,最终的返回码存放在NCB结构的ncb_cmd_cplt字段中。
 
  ncb_retcode字段

  命令提交给NetBios驱动程序后,该命令的成功与否即在该字段中反映出来。若ncb_retcode字段值为00h,则表示命令成功。对于异步NetBios命令NetBios将立即在ncb_retcode字段中返回值FFh,表明该命令已经排队,即将执行。命令执行完毕后,同ncb_cmd_cplt一样,ncb_retcode将置成最终的返回码。
 
  ncb_lsn字段

  同远程应用程序处理建立了会话后,NetBios驱动程序将相应设置该字段(局部会话号)。在随后的通信中,若想同远程处理进行通信,本地处理只需在NCB结构中指明局部会话号,不再需要在ncb_callname字段中指定完整的远程处理逻辑名。

  单就一个适配器而言,工作站上和每一个处理一次至多能进行254个会话,只要指定相关的局部会话号,就能达到会话的目的。系统保留值0和255,不将它们作为局部会话号使用。
 
  ncb_num字段

  工作站上的每一个处理最多可向名表中加进254个逻辑名。成功地将一名加进局域网适配器的私有名表后,NetBios将置ncb_num字段值成该名在名表中的索引值(索引值称为名号),在以后的同远程处理进行的非连接式通信中,可使用这个名号。

  名号0和255亦为系统保留,适配器的物理地址总在名表第1项(例如Name_Number=1)中。
 
  ncb_buffer字段

  该字段的值是,要发送的数据缓冲区的地址,或者要在其中存放接收到的数据的缓冲区的地址。
 
  ncb_length字段

  ncb_length字段指定的是,由ncb_buffer字段指定的缓冲区的长度。接收到一块数据时,NetBios将相应设置该字段。
 
  ncb_callname字段

  这是一个由应用程序设置的16字节字段,其值是远程处理的逻辑名。应用程序设置一个连接或向远程处理发送一个数据表包时,将相应设置该字段。所有的字节均有用。在远程驱动程序连接正期待着接收连接呼叫的本地处理时,NetBios将填写该字段。因此,接收呼叫的处理能够找出远程呼叫方的名。
 
  ncb_name字段

  这是由应用程序设置的16字节字段,其值是本地处理的逻辑名,应用程序设置一个连接或向远程处理发送一个数据表包时,将相应设置该字段。所有的字节均有用。该字段的第一个字节不能是二进制0或“*”,另外,IBM保留了头三个字节,所以头三个字节不能是“IBM”。第16个字节不能是00h到1Fh之间的值。在局域网管理器环境下,最后一个字节(即第16个字节)有特殊的含义,具体如下:

最后一个字节含义20h服务器名00h重定向名03h用户名05h转寄名 
  ncb_rto字段

  在期望从一个或数个远程处理接收到一包时,应用程序可在ncb_rto(接收时间限制)字段中指定等待的最大时间。若超过了指定时间仍未接收到包,则NetBios驱动程序将在ncb_retcode字段中返回错误。
若ncb_rto字段值为00h,则表示阻止执行,直到本地处理接收到一包。
 
  ncb_sto字段

  ncb_sto(发送时间限制)字段类似于ncb_rto字段,但它指定的是等待NetBios连接式命令,Send,完成的时间。若超过了指定时间,则将返回错误。

  若ncb_sto字段值为00h,则表示不为发送操作指定时间限制。此时,命令将阻止执行,直到要么成功地发送了一包,要么NetBios层停止了重试。
 
  ncb_post字段

  在提交异步命令时,应用程序可以设置该字段。在MS-DOS中,应用程序将后处理例程的地址填在该字段中。所谓后处理例程,即命令执行完毕后NetBios驱动程序将要调用的例程。

  ncb_lana_num字段

  因为一台工作站上可能有不止一个局域网网络适配器卡,所以,NCB中相应也有一个字段,用来指明应用程序想使用哪一个网络适配器。该字段称为LAN适配器号或LANA号,LANA号从0开始。

  在像Microsoft LAN Manager这样的网络软件环境中,可以同时装入多个传输驱动程序(例如,TCP/IP,NetBios或XNS),其中每一个驱动程序都提供了一个NetBios接口。另外,一台工作站可能有不止一个LAN适配器卡,此时,ncb_lana-number字段指定的是某一特定对,即应用程序想使用的传输驱动程序和LAN适配器卡。
 
  ncb_cmd_cplt字段

  NetBios驱动程序利用该字段来表明异步命令已完成。起先,当应用程序提交一条异步命令时,NetBios将置该字段值为FFh。待命令执行完毕后,再将最终值填入该字段。也就是说,提交了一条异步命令后,应用程序可以监视(轮询)该字段的取值,直到其值不再是Ffh为止。
 
  提交一个NCB

  若想使用Windows提供的NETBIOSCALL函数,则应当从类似于图所示的汇编语言代码段中调用该函数的关键是,在远程调用NETBIOSCALL之前,要先将NCB结构的地址进入寄存器对ES:BX。这同在MS-DOS环境下提交NCB不同。在MS-DOS环境下提交NCB,是通过调用INT 5C或INT 2A实现的。当然,NCB结构的地址也要送入ES:BX。

  弄清楚提交上去的NCB是如何导致一包或数包被送至网络,以及NetBios是如何适应OSI模型的,总是有益的。下表给出了各自利用NETBIOSCALL来发送和接收包的发送方和接收方。

发送方接收方BETBIOSCALLNETBIOSCALLWindows WindowsRedirectorRedirector传输(如NetBios)传输(如NetBios)MAC(如Token Ring)MAC(如Token Ring) 
  同步NetBios命令对异步NetBios命令

  所有的NetBios命令都可同步执行,并且大多数命令亦能异步执行。图示出了NetBios命令及其在NCB.H中定义的代码。
 
NetBios命令描述同步代码异步代码NCBRESET复位32h不允许NCBASTAT适配器状态33hB3hNCBCANCEL取消35h不允许NCBUNLINK取消链接70h不允许NCBADDNAME加入名称30hB0hNCBDELNAME删除名称31hBihNCBADDGRNAME加入组名36hB6hNCBFINDNAME寻找名称78HF8HNCBCALL呼叫10h90hNCBLISTEN侦听11h91hNCBHANGUP挂起12h92hNCBSEND发送14h94hNCBRECV接收15h95hNCBRECVANY全部接收16h96hNCBCHAINSEED链发送17h97hNCBCHAINSENDNA链发送(无回应)72hF2hNCBSSTAT状态34hB4hNCBDGSEND发送数据20hA0hNCBDGRECV接收数据21hA1hNCBDGSENDBC发送广播22hA2hNCBDGRECVBC接收广播23hA3h
  提交了一条同步命令处理将不再执行,直到所提交的同步命令执行完毕。而提交了一条异步命令的处理在等待这条命令执行完毕的同时还可以继续执行其他任务。具体使用哪一种命令,主要取决于手头要执行的任务及应用程序的性质。但是,在使用同步命令时要小心,特别是在命令完成时间不可确定的情况下。若在这种情况下使用同步命令,则应用程序将挂起。这种情况的害处在基于MS-DOS的系统中尤其明显,因为此时在命令执行完毕前不能进行任何其他活动。而windows环境下,将阻止用户切换进其他应用程序。也就是说,如果使用不小心的话,同步命令将导致应用程序对用户不友好。下面讨论一下异步命令的提交方式。

  为了进行异步调用,NCB命令应当同80hsh相或。另外,在命令执行完毕之前,所提交的NCB不应当被破坏或释放。必要的话,可通过NCB结构的ncb_rto和ncb_sto字段指定适当的超时限制。NCB命令执行完毕或超时后,NetBios驱动程序将相应设置NCB结构的ncb_retcode和ncb_cplt字段。

  提交后,异步命令可能立即完成。在这种情况下,NetBios驱动程序将设置ncb_retcode和ncb_cmd_cplt字段,NetBios调用将立即返回。NCB提交后立即进行的NCB处理,如果发现了错误,则将采取相同的处理,ncb_retocode字段值即为返回码。如果上述情况都没有发生,则NetBios驱动程序将把所提交的NCB在内部队列中排队,等待以后执行,并在ncb_retcode和ncb_cmd_cplt字段中返回FFh。

  可通过两种途径等待步命令执行完毕。第一种是在提交NCB时将ncb_post字段值置成FFh。此时,应用程序可以轮询NCB是否已执行完,具体方法就是查看ncb_cmd_cplt字段的取值。命令完成(成功、失败或超时)后,NetBios驱动程序将把最终的返回码填写在ncb_cmd_cplt字段中,最终的返回码决不会是FFh。第二种途径是,在提交NCB之前,先将后处理例程的地址送入NCB结构的ncb_post字段。在这种情况下当命令完成(成功、失败或超时)时,NetBios将调用该例程。后处理例程是NetBios驱动程序在中断时要调用的应用程序的一部分,因此,在NCB处理完成之前,代码应当留在同样的内存单元中