在C++Builder操作NetBIOS举办编程
副标题#e#
NetBIOS是网络根基的输入/输出系统,是一个应用于措施接口,用于数据源与目标地之间的数据互换。即可以或许会见支持计较机应用措施和设备通信时要用到的各类处事,具有明晰而简朴的通信协议,必需用非凡的呼吁序列来挪用NetBIOS处事。
首先我们来相识一下NetBIOS的根基常识。
一.NetBIOS 的基本
1。在网络条理中,NetBIOS是处于暗示层和会话层之间,是参考模子的高层。因此其接口措施的应用在很洪流平上而且从本质上与较低条理的各类勾当隔分开。它支持IEEE802.2 的逻辑链路节制(LLC)协议。此刻NetBIOS正迅速地成为差异操纵系统情况下普遍利用的数据通信平台,这些操纵系统包罗PC DOS,OS/2,UNIX 和Windows。
2。NetBIOS的呈现是在1984年8月IBM PC的网络适配器中,是由Sytek公司为IBM设计的。它回收宽带同轴电缆,提供每秒2MB的数据传输突发率,利用了风行的家产尺度CSMA/CD(多会见载波侦听/载波检测)作为会见协议,这种协议首次呈此刻IEEE 802.3 以太网尺度中。
3。NetBIOS的应用处事:NetBIOS提供四种应用处事,它们别离为:定名支持,数据报支持,会话支持和通用呼吁。
(1).定名支持:每个NetBIOS 网络积适配器在网络中都利用一个或多个网络名来标识本身,以区别于其他的网络适配器。网络名由16个字符构成。
(2).数据报支持:当一个适配器在网络中激活后,在计较机上的应用措施就可以用NetBIOS与驻留在同一个或差异计较机上的其他应用通信。它们之间的应用通信可以利用数据报来举办。
数据报是一条短信息,它的长度随NetBIOS实现要领的差异而差异,不能担保数据的正确传输。也不吸收来自吸收方的指示,如:在存在,未加电或不吸收数据报,这样 在网络产生妨碍时,发出的数据报大概不会被任何计较机吸收到。
数据报有两种类:广播型和定向型。广播型是完全不区分吸收者的数据报,可以利用NetBIOS的Send Broadcast Datagram呼吁来发送数据,吸收方可挪用NetBIOS Receive Broadcaset Datagram呼吁来吸收数据。定向型是指定命据报吸收者的组名,任何一方都可以挪用NetBIOS Send Datagram呼吁发送数据,吸收方可以挪用NetBIOS Receive Datagram呼吁来吸收发送过来的数据。
(3).会话支持:在NetBIOS应用通信中的第二种形式是会话通信了,它支持可以在两个应用措施之间建设一个靠得住的双向数据通信毗连,并能保持较长时间。这种毗连有时也称为虚电路。彼此通信的应用可以驻留在同一台计较机上(当地会话)或驻留在差异的计较机上(长途会话)。
会话通信比数据报通信的利益有:对付每个被发送的信息,发送前能得知对方吸收筹备环境,而数据报通信只提供信息的发送状态。
可以利用NetBIOS的Listen呼吁来建设会话,Listen呼吁引用NetBIOS呼吁表中的一个名字。另一端则使NetBIOS Call 呼吁,Call呼吁要用到其NetBIOS定名表中的名字,这个名字必需与另一端的的应用措施所用的名字相匹配,这样双方的名字相匹配是两个应用建设会话的依据,在Listen 呼吁和 Call 呼吁执行完后,就成立会话了。留意的是:首先挪用 Listen呼吁,然后再挪用 Call 呼吁,这个顺序不能颠倒。
会话建设后,每个客户端都收到一个会话已建设的指示,获得一个字节的无标记返回值,暗示会话与适配器之间的联。建设会话后,每个客户端都可以挪用NetBIOS的Send和Receive呼吁来传输和吸收数。
(4).通用呼吁:NetBIOS的通用呼吁提供了五项NetBIOS处事,别离是:Reset(复位适配器),Adapter Status(显示适配器状态),Cancel and Unlink(除掉及断开呼吁),Find Name(匹配名字)和 Trace(跟踪呼吁)。
1).Reset 呼吁强迫适配器进入初始化状态,终止所有的会话,并删除NetBIOS 定名表中除永久节点名以外的所有名字。
2).Adapter Status 呼吁用来查询NetBIOS适配器,以获取有关操纵信息,如:发明LAN 错误数和适配器NetBIOS定名表,用于知道长途计较机和适配器是否都被挂起,照旧只有计较机被挂起。这是对长途适配器的状态举办查询的一个很好的实现要领。
3).Cancel and Unlink:Cancel 呼吁是使应用措施竣事尚未执行完的呼吁。Unlink呼吁是答允RPL引导的PC Network LAN 适配器,从RPL处事器上脱开,它只对根基适配器有效,凡是返回一个 0 值,表白请求乐成。4).Find Name 呼吁用于找出一个由Find Name 呼吁指定的标记名的适配器,在多个适配器共用一个组名时,它们都可以同时都应答,可是只有一个应答将返回给发出请求的应用端。
5).Trace 呼吁将激活对所有发向NetBIOS 接口的呼吁举办跟踪,其根基用途是为诊断措施提供支持。
#p#副标题#e#
4.NetBIOS呼吁的挪用:
#p#分页标题#e#
在应用措施中挪用 NetBIOS 呼吁之前,将内存的一个64 字节区域先清空为 0 ,这样防备内存原有的数据导致NetBIOS 呼吁竣事时,NetBIOS 错误地进入其他内存区域。应用措施利用这个区域建设一个 NetBIOS 节制块(NCB)。挪用 NetBIOS 呼吁时,要按照呼吁的要求,填充节制块的域,所以假如没有正确填充这些NCB域,会导致用户计较机运行的挂起,这样会粉碎整个系统。
NetBIOS 中操作的一个函数就是 Netbios(),此函数用于讲解和执行指定的信息节制块(NCB)。函数界说如下:UCHAR Netbios(PNCB pncb);参数 pncb 用于描写网络节制块布局的指针。
NCB 布局的界说如下:
typeddf struct_NCB{
UCHAR ncb_command; //呼吁码
UCHAR ncb_retcode; //返回码
UCHAR ncb_lsn; //当地会话编码
UCHAR ncb_num; //数据报
ADD NAME (增加名)表进口
PUCHAR ncb_buffer; //信息缓冲区
WORD ncb_length; //信息缓冲区长度
UCHAR ncb_callname[NCBNAMSZ]; //CALL 的长途系统名
UCHAR neb_name[NCBNAMSZ]; //当地适配器网络名
UCHAR ncb_rto; //以 1/2s 为单元的吸收超时UCHAR ncb_sto; //以 1/2s 为单元的发送超时void(*ncb_post)(struct_NCB*); //POST 例程指针
UCHAR ncb_lana_num; //执行呼吁的网络适配器编号
UCHAR ncb_cmd_cplt; //0XFF 呼吁挂起,不然呼吁竣事
UCHAR ncb_reserve[10]; //保存值
HANDLE ncb_event; //事件句柄
}NCB;
NCB 呼吁域包括用于期望操纵的 NetBIOS 的呼吁码,假如呼吁码的高价位是 0 ,NetBIOS 吸收这个请求,而且当呼吁执行完成后,返回到应用措施,在这里这叫期待选择。每次只能有一个期待选择呼吁被挂起.固然Reset,Cancel和Unlink 这些呼吁能担保执行完毕,可是其他一些呼吁仅仅在某些环境下才会竣事。假如这样一个呼吁不竣事,则NetBIOS 将不返回,而且计较机因为 NetBIOS 在期待竣事的无限轮回中而挥霍资源。如要制止产生这样的环境,应用措施可以将除Reset,Cancel和Unlink 呼吁外所有呼吁的呼吁域的高价位配置为 1 ,这叫不期待选择。 NCB 返回码最终会包括呼吁的最终返回码值,如在呼吁竣事后,其值为 0 ,则暗示该呼吁乐成地竣事。不然,表白呈现了错误。
NCB 的当地会话编码域包括着与一条呼吁相接洽的当地会话编号。NCB 的名字编号域包括着与一条呼吁相联的 NetBIOS 呼吁表格中的名字编号。
NCB 的缓冲区域是一个指向信息缓冲区的指针。NCB 的缓冲区长度域记录了由NCB 的缓冲区域所指向的缓冲区的巨细。NCB 的挪用名域为16字节长,它包括着同该请求相关的一个长途名。
NCB 的当地名域包括着与请求相关的一个当地名。
NCB 的接管超时域与CALL 和 LISTEN 呼吁一起利用,它以 1/2s的时距离断为单元。NCB 的发送超时域与CALL 和 LISTEN 呼吁一起利用,它以 1/2s的时距离断为单元。
现把 Netbios() 函数的返回值先容如下:
00h : 乐成地完成,乐成返回
01h : 无效的缓冲区
03h : 无效的呼吁
05h : 呼吁超时
06h : 不完整地吸收动静
07h : 当地No-Ack呼吁失败
08h : 无效的当地会话
09h : 没有可利用的资源
0Ah : 会话已封锁
0Bh : 呼吁已除掉
0Dh : 当地NetBIOS定名表中名字反复
0Eh : NetBIOS定名表满
0Fh : 名字具有勾当会话,现被除掉挂号
11h : NetBIOS 当地会话表满了
12h : 没有挂起的Listen 呼吁,所有拒绝断开会话
13h : 犯科名字编号
14h : 不能找到被挪用名字或无答复
15h : 找不到呼吁,或不能把*号或00h指定ncb_name的首字节,或名字已被除掉而不能再利用
17h : 名字已被删除18h : 会话非正常竣事
19h : 检测到名字斗嘴
1Ah : 不兼容的长途设备
21h : 接口忙
22h : 挂起的呼吁太多
23h : 在ncb_lana_num域中无效的编号
24h : 发生打消时,呼吁已完成
25h : 字节组名呼吁指定了保存名字
26h : 呼吁不能被除掉
30h : 被另一个历程界说了名字
34h : NetBIOS情况未被界说
35h : 所用的操纵系统资源用尽
36h : 超出最大应用个数
37h : NetBIOS无可以利用的SAP
38h : 无可以利用的请求资源
40h : 系统错误
41h : 检测到长途适配器的热载波
42h : 检测到当地适配器的热载波
43h : 未检测到载波
4Eh : 状态位12、14、或15被置位的时间高出 1 min
4Fh : 状态位8–11中的一个或多个被置位
50h–F6h: 适配器产生妨碍
F7h : 隐式DIR-INITIALIZE错误
F8h : 隐式DIR-OPEN-ADAPTER 错误
F9h : IBM LAN支持措施内部错误
FAh : 适配器查抄
FBh : NetBIOS 措施未被装入PC
FCh : DIR-OPEN-ADAPTER 或 DIR-OPEN-SAP失败
FDh : 不期望封锁适配器
FFh : 呼吁挂起状态
为了更好地讲解NetBIOS 的编程,现设计一个用 NetBIOS 来编写获取网络适配器信息的措施
二、建设措施例子
#p#分页标题#e#
在C++Builder 5.0 中选择File / New ,打开“New Items”对话框,在对框中选择Consol Wizard.随后弹出“Consol Application Wizard”对话框,在Windows Type 中选择Consol,在ExecutionType中选择EXE,然后选择Finish,生成一个新的节制台应用措施。
//“Project1.cpp”源代码如下:
#pragma hdrstop
#include <condefs.h>;
#include <windows.h>;
#include <stdio.h>;
typedef struct _ASTAT
{
ADAPTER_STATUS adapt;
NAME_BUFFER NameBuffer[30];
} ASTAT, *PASTAT;ASTAT Adapter;//自界说复位适配器函数
bool ClearAdapter(NCB ncb);
//---------------------------------------------------------------------------
//#pragma argsused
int main()
{
NCB ncb;
UCHAR uRetCode;//先复位网络适配器ClearAdapter(ncb);memset(&;ncb,0,sizeof(ncb));//呼吁码为显示适配器状态
ncb.ncb_command=NCBASTAT;
ncb.ncb_lana_num=0;
strcpy((char *)ncb.ncb_callname,"* ");
ncb.ncb_buffer=(unsigned char *) &;Adapter;
ncb.ncb_length=sizeof(Adapter);
uRetCode=Netbios(&;ncb);
printf("The NCBASTAT returned code is OX%x\n",uRetCode);if(uRetCode==0)
{
printf( "The Ethernet Number is: %02x_%02x_%02x_%02x_%02x_%02x\n",
Adapter.adapt.adapter_address[0],
Adapter.adapt.adapter_address[1],
Adapter.adapt.adapter_address[2],
Adapter.adapt.adapter_address[3],
Adapter.adapt.adapter_address[4],
Adapter.adapt.adapter_address[5] );
if(Adapter.adapt.adapter_type==0xFF)
printf("The adapter is Token Ring adapter.\n");
else if(Adapter.adapt.adapter_type==0xFE)
printf("The adapter is Ethernet adapter.\n");printf("The software-release level is %d.%d\n",Adapter.adapt.rev_major,Adapter.adapt.rev_minor);
printf("The number of names in the local names table is %d\n",Adapter.adapt.name_count);
for(int i=0;i<;Adapter.adapt.name_count;i++)
printf("%s\n",Adapter.NameBuffer[i].name);
}//留意下面措施代码存心堕落误
char Remote[16]="202.112.87.221";//先复位网络适配器
ClearAdapter(ncb);
memset(&;ncb,0,sizeof(ncb));//呼吁码为发送数据
ncb.ncb_command=NCBSEND;
ncb.ncb_lana_num=0;
ncb.ncb_lsn=4;
ncb.ncb_sto=2;
strcpy(ncb.ncb_callname,Remote);
//strcpy((char *)ncb.ncb_callname,"* ");
ncb.ncb_buffer=(unsigned char *) &;Adapter;
ncb.ncb_length=sizeof(Adapter);
uRetCode=Netbios(&;ncb);
printf("The NCBASTAT returned code is OX%x\n",uRetCode);
printf("The number of FRMR frames received is %d\n",Adapter.adapt.frmr_recv);
printf("The number of FRMR frames transmitted is %d\n",Adapter.adapt.frmr_xmit);getchar();
return 0;
}
//---------------------------------------------------------------------------
//复位网络适配器 bool ClearAdapter(NCB ncb)
{
memset(&;ncb,0,sizeof(ncb));
ncb.ncb_command=NCBRESET;
ncb.ncb_lana_num=0;
Netbios(&;ncb);
return true;
}
以上实例操作网络根基输入/输出系统NetBIOS建设了一个能获取主机 MAC (网络适配器)信息及其他一些信息的应用措施。由于作者程度有限,有不妥之处请凉解。本文但愿能起到抛砖引玉的浸染。