计算机软件与应用NetBIOS_第1页
计算机软件与应用NetBIOS_第2页
计算机软件与应用NetBIOS_第3页
计算机软件与应用NetBIOS_第4页
计算机软件与应用NetBIOS_第5页
已阅读5页,还剩55页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

计算机软件与应用NetBIOSSUP-4NetBIOS网络编程技术课程描述NetBIOS(NETworkBasicInput/OutputSystem,网络基本输入/输出系统)定义了一种软件接口以及在应用程序和连接介质之间提供通信接口的标准方法。它可以提供名字服务、会话服务和数据库服务,基于NetBIOS的比较典型的应用是获取远程计算机的Mac地址、名称和所在工作组等信息。本章将对NetBIOS网络编程技术进行介绍。本章知识点SUP-4.1NetBIOS协议及应用SUP-4.2NetBIOS开发接口SUP-4.3在程序中实现NBTSTAT命令的功能SUP-4.1NetBIOS协议及应用SUP-4.1.1NetBIOS协议SUP-4.1.2使用NBTSTAT命令SUP-4.1.1NetBIOS协议NetBIOS协议最初由IBM开发,微软公司在此基础上对该协议进行了完善,并在Windows上提供了对NetBIOS协议的支持。网络邻居功能就是基于NetBIOS协议的。在Windows中安装TCP/IP协议的同时就会安装NetBIOS协议。下面介绍一下在Windows2003中启用和配置NetBIOS协议的方法。

配置NetBIOS右键单击桌面上的网络邻居图标,在弹出菜单中选择“属性”,打开“网络连接”窗口。右键单击“本地连接”图标,在弹出菜单中选择“属性”,打开“本地连接属性”对话框。

配置NetBIOS选中“Internet协议(TCP/IP)”项,单击“属性”按钮,打开“Internet协议(TCP/IP)”属性对话框。单击“高级”按钮,打开“高级TCP/IP设置”对话框。单击“WINS”选项卡,可以对NetBIOS协议进行设置。1.LANA编号LANA(LANAdapter,LAN适配器)编号是NetBIOS进行网络编程的关键,它对应于网卡及传输协议的唯一组合。例如,假定某个工作站安装了两块网卡,以及两种具有NetBIOS能力的传输协议(例如TCP/IP和NetBEUI),那么将共有下面4个LANA编号:表示“TCP/IP—网卡1”对。表示“NetBEUI—网卡1”对。表示“TCP/IP—网卡2”对。表示“NetBEUI—网卡2”对。2.名字服务NetBIOS协议支持建立名字服务器,负责查找目标主机对应的IP地址,并赋予一个NetBIOS名称。名字服务提供的主要功能如下:添加名字,即注册一个NetBIOS名字。添加组名,即注册一个NetBIOS组名。删除名字,即取消一个NetBIOS名字和组名的注册。查询名字,即在网络中搜索NetBIOS名字。3.会话服务会话服务提供的主要功能如下:调用,即打开一个到远程NetBIOS名字的会话。侦听,即侦听其他程序的连接请求。挂起,即关闭一个会话。发送,即向会话对端的计算机发送一个数据包,并等待对方确认。无确认发送,即向会话对端的计算机发送一个数据包,但不需要对方确认。接收,即等待从会话对端发送的数据包到达。4.数据报服务数据报服务提供的主要功能如下:发送数据报,即向远程NetBIOS名字发送一个数据报。发送广播数据报,即向网络中所有NetBIOS名字发送数据报。接收数据报,即等待从发送数据报操作中到达的数据。接收广播数据报,即等待从发送广播数据报操作中到达的数据。在Windows中,如果安装了NetBIOS协议,则系统将自动开放下列端口:137端口,主要作用是在局域网中提供计算机的名称或IP地址查询服务。138端口,主要作用是提供NetBIOS环境下的计算机名浏览功能。139端口,主要作用是提供文件和打印机共享的功能。SUP-4.1.2使用NBTSTAT命令在Windows命令窗口中执行NBTSTAT命令,可以获取指定远程计算机的基本信息,包括Mac地址、计算机名和所属工作组等。NBTSTAT命令的格式如下:

NBTSTAT[[-aRemoteName][-AIPaddress][-c][-n][-r][-R][-RR][-s][-S][interval]]NBTSTAT参数的具体说明参

数说

明-aRemoteName列出指定名称的远程机器的名称表,RemoteName表示指定的远程主机计算机名-AIPaddress列出指定

IP地址的远程机器的名称表,IPaddress表示用点分法表示的IP地址-c列出远程计算机名称及其IP地址的

NBT缓存-n列出本地的NetBIOS名称-r列出通过广播和经由WINS解析的名称-R清除和重新加载远程缓存名称表-RR将名称释放包发送到WINS,然后启动刷新-s列出将目标IP地址转换成计算机NetBIOS名称的会话表-S列出具有目标IP地址的会话表interval重新显示选定的统计、每次显示之间暂停的间隔秒数。按Ctrl+C停止重新显示统计实例NBTSTAT-aLEE-THINKPADSUP-4.2NetBIOS开发接口SUP-4.2.1NetBIOS操作SUP-4.2.2NCB结构体SUP-4.2.3其他常用NetBIOS结构体SUP-4.2.4Netbios()函数SUP-4.2.5获取LANA上的所有NetBIOS名字SUP-4.2.6获取网络适配器上的MAC地址SUP-4.2.1NetBIOS操作协议驱动程序对外公布NetBIOS接口,并将NetBIOS命令映射到协议驱动程序的内部命令。NetBIOS模拟器接收NetBIOS命令,将它们转换成TDI(TransportDriverInterface,传输驱动程序接口)调用,然后使用TDI接口将它们转发到传输驱动程序。在Windows2003、WindowsXP、Windows2000和WindowsNT操作系统中,NetBIOS操作的流程如下:SUP-4.2.2NCB结构体typedefstruct_NCB{UCHARncb_command;UCHARncb_retcode;UCHARncb_lsn;UCHARncb_num;PUCHARncb_buffer;WORDncb_length;UCHARncb_callname[NCBNAMSZ];UCHARncb_name[NCBNAMSZ];UCHARncb_rto;UCHARncb_sto;void(CALLBACK*ncb_post)(structNCB);UCHARncb_lana_num;UCHARncb_cmd_cplt;UCHARncb_reserve[X];HANDLEncb_event;}NCB,*PNCB;1.ncb_command命令编码可选值说

明NCBACTION非标准NetBIOS3.0命令NCBADDGRNAME向本地名字表中添加一个组名,组名在网络中必须是唯一的NCBADDNAME向本地名字表中添加一个唯一的名字NCBASTAT获取本地或远程网络适配器的状态。如果指定了此编码,则成员变量_buffer指向填充了ADAPTER_STATUS结构体和NAME_BUFFER结构体数组的缓冲区NCBCALL打开与其他名字之间的会话NCBCANCEL取消之前挂起的命令NCBCHAINSEND向指定的会话伙伴发送两个数据缓冲区的内容NCBCHAINSENDNA向指定的会话伙伴发送两个数据缓冲区的内容,并且不等待对方确认NCBDELNAME从本地名字表中删除一个名字NCBDGRECV获取来自任意名字的数据包NCBDGRECVBC获取来自任意名字的广播数据包NCBDGSEND向指定名字发送数据包NCBDGSENDBC向局域网中的所有计算机发送广播数据包NCBENUM用于枚举LANA编号。如果指定此编码,则成员变量ncb_buffer指定填充了LANA_ENUM结构体的缓冲区。NCBENUM不是标准的NetBIOS3.0命令NCBFINDNAME决定指定名字在网络中的位置。如果指定此编码,则成员变量_buffer指定填充了FIND_NAME_HEADER结构体和FIND_NAME_BUFFER结构体的缓冲区NCBHANGUP关闭指定的会话NCBLANSTALERT只对WindowsServer2003、WindowsXP、Windows2000和WindowsNT等操作系统有效,提示用户持续时间在1分钟以上的局域网故障NCBLISTEN允许一个会话可以被其他名字打开NCBRECV从指定的会话伙伴获取数据NCBRECVANY从指定名字对应的会话中获取数据NCBRESET复位局域网网络适配器NCBSEND向指定的会话伙伴发送数据NCBSENDNA向指定的会话伙伴发送数据,并且不等待对方确认NCBSSTAT获取会话的状态。如果指定了此参数,则成员变量_buffer指向填充了SESSION_HEADER和SESSION_BUFFER结构体的缓冲区NCBTRACE激活或取消NCB跟踪。此命令目前不被支持NCBUNLINK断开一个网络适配器的连接。此命令只为与之前版本的NetBIOS兼容而提供,但在Windows中无效2.ncb_retcode返回编码可选值说

明NRC_GOODRET操作成功NRC_BUFLEN提供了无效的缓冲区长度NRC_ILLCMD提供了无效的命令NRC_CMDTMO命令超时NRC_INCOMP消息不完整,应用程序正在执行其他命令NRC_BADDR缓冲区地址无效NRC_SNUMOUT会话编号越界NRC_NORES没有有效的资源NRC_SCLOSED会话已被关闭NRC_CMDCAN命令被取消NRC_DUPNAME在本地名字表中存在相同的名字NRC_NAMTFUL名字表已满NRC_ACTSES命令已执行完成,指定名字拥有活动的会话,并且不再注册NRC_LOCTFUL本地会话表已满NRC_REMTFUL远端会话表已满,打开会话的请求被拒绝NRC_ILLNN指定了无效的名称编号NRC_NOCALL系统没有发现调用的名字NRC_NOWILD成员变量ncb_name中不允许通配符NRC_INUSE名字已经在远程适配器上使用NRC_NAMERR名字已被删除NRC_SABORT会话非正常结束NRC_NAMCONF检测到名字冲突NRC_IFBUSY接口忙NRC_TOOMANY命令太多,应用程序将在稍后重试命令NRC_BRIDGE成员变量ncb_lana_num没有指定有效的网络编号NRC_CANOCCR执行取消操作后,命令已经结束NRC_CANCELNCBCANCEL命令无效,命令并未取消NRC_DUPENV名字已经被另一个本地进程占用NRC_ENVNOTDEF环境没有被定义,因此必须执行一个重置命令NRC_OSRESNOTAV操作系统资源被耗光,该命令稍候会重试NRC_MAXAPPS应用程序数量超过规定的最大值NRC_NOSAPS没有对NetBIOS有效的服务访问点(SAP,ServiceAccesPoints)NRC_NORESOURCES请求的资源无效NRC_INVADDRESSNCB地址无效NRC_INVDDIDNCBDDID无效NRC_LOCKFAIL尝试锁定用户区域失败NRC_OPENERR当设备驱动器执行打开操作时发生错误。错误编码并不在NetBIOS3.0中定义NRC_SYSTEM发生系统错误NRC_PENDING异步操作并未结束NCB结构体其他成员变量3.ncb_lsn表示本地会话编号。在指定环境中此编号唯一标识一个会话。调用Netbios()函数成功执行了NCBCALL命令后返回此编号。4.ncb_num指定本地网络名字编号。调用Netbios()函数成功执行了NCBADDNAME或者NCBADDGRNAME命令后返回此编号。此编号在所有数据包命令和NCBRECVANY命令中使用。5.ncb_buffer指向消息缓冲区。可以使用表中的命令访问消息缓冲区。命

令说

明NCBSEND发送消息NCBRECV接收消息NCBSSTAT接收请求状态信息NCB结构体其他成员变量6.ncb_length指定消息缓冲区的大小,单位为字节。对于接收命令,此成员变量由Netbios()函数设置,表示接收到的字节数。如果缓冲区长度不正确,则Netbios()函数返回NRC_BUFLEN错误编码。指定远端应用程序的名字。8.ncb_name指定应用程序可以识别的名字。9.ncb_rto指定会话执行接收操作的超时时间。将此成员变量指定为0,表示在执行NCBCALL和NCBLISTEN命令时没有超时。超时会影响随后执行的NCBRECV命令。10.ncb_sto指定会话执行发送操作的超时时间。将此成员变量指定为0,表示在执行NCBCALL和NCBLISTEN命令时没有超时。超时会影响随后执行的NCBSEND和NCBCHAINSEND命令。11.ncb_post指定异步命令完成后需调用的例程地址。12.ncb_lana_num指定LANA编号。13.ncb_cmd_cplt指定命令完成标识。14.ncb_reserve保留字段,必须为0。15.ncb_event指定事件对象的句柄。当执行异步命令时,事件对象被设置为未受信状态;当异步命令完成后,事件对象被设置为受信状态,这样就可以执行对应的事件处理程序了。SUP-4.2.3其他常用NetBIOS结构体1.LANA_ENUM结构体2.ADAPTER_STATUS结构体3.NAME_BUFFER结构体4.ASTAT结构体1.LANA_ENUM结构体LANA_ENUM结构体中包含当前逻辑网络适配器的数量。当一个物理网络适配器绑定到一个网络协议时,就对应一个逻辑网络适配器。执行NCB命令NCBENUM可以向LANA_ENUM结构体中填充逻辑网络适配器的个数和逻辑网络适配器编号,此时NCB结构体中的ncb_buffer成员变量指向LANA_ENUM结构体。LANA_ENUM结构体的定义代码如下:

typedefstruct_LANA_ENUM{UCHARlength;UCHARlana[MAX_LANA];}LANA_ENUM,*PLANA_ENUM;

参数说明如下:length,系统中包含的逻辑网络适配器数量。lana[MAX_LANA],系统中包含的逻辑网络适配器编号数组。2.ADAPTER_STATUS结构体ADAPTER_STATUS结构体中包含网络适配器的信息。NCB结构体的ncb_buffer成员变量指定该结构体。通常,ADAPTER_STATUS结构体的后面跟着很多NAME_BUFFER结构体。ADPATER_STATUS结构体的定义代码如下:

typedefstruct_ADAPTER_STATUS{UCHARadapter_address[6];UCHARrev_major;UCHARreserved0;UCHARadapter_type;UCHARrev_minor;WORDduration;WORDfrmr_recv;WORDfrmr_xmit;WORDiframe_recv_err;WORDxmit_aborts;DWORDxmit_success;DWORDrecv_success;

WORDiframe_xmit_err;WORDrecv_buff_unavail;WORDt1_timeouts;WORDti_timeouts;DWORDreserved1;WORDfree_ncbs;WORDmax_cfg_ncbs;WORDmax_ncbs;WORDxmit_buf_unavail;WORDmax_dgram_size;WORDpending_sess;WORDmax_cfg_sess;WORDmax_sess;WORDmax_sess_pkt_size;WORDname_count;}ADAPTER_STATUS,*PADAPTER_STATUS;

ADAPTER_STATUS结构体参数说明adapter_address,指定网络适配器的地址。rev_major,指定发布软件的主版本号。例如,如果发布版本号为,则rev_major的值为3。reserved0,保留字段,始终为0。adapter_type,指定网络适配器的类型。如果是令牌环适配器,则该值为0xFF;如果是以太网适配器,则该值为0xFE。rev_minor,指定发布软件的副版本号。例如,如果发布版本号为,则rev_minor的值为0。duration,指定报告的时间周期,单位为分钟。frmr_recv,指定接收到的FRMR(帧拒绝)帧数量。frmr_xmit,指定传送的FRMR帧数量。iframe_recv_err,指定接收到的错误帧数量。xmit_aborts,指定终止传输的包数量。xmit_success,指定成功传输的包数量。recv_success,指定成功接收的包数量。iframe_xmit_err,指定传输的错误帧数量。recv_buff_unavail,指定缓冲区无法为远程计算机提供服务的次数。t1_timeouts,指定DLC(DataLinkControl,数据链路控制)T1计时器超时的次数。ti_timeouts,指定ti非活动计时器超时的次数。t1计时器用于检测断开的连接。reserved1,保留字段,始终为0。free_ncbs,指定当前空闲的网络控制块的数量。max_dgram_size,指定数据包的最大大小,该值至少为512字节。pendingsess,指定挂起会话的数量。max_cfg_sess,指定配置的最大挂起会话数量。max_sess_pkt_size,指定会话数据包的最大大小。name_count,指定本地名字表中名字的数量。3.NAME_BUFFER结构体结构体NAME_BUFFER中包含本地网络名字信息。当应用程序执行NCBASTAT命令时,可以获取ADAPTER_STATUS结构体及其后面的NAME_BUFFER结构体。NAME_BUFFER结构体。typedefstruct_NAME_BUFFER{UCHARname[NCBNAMSZ];UCHARname_num;UCHARname_flags;}NAME_BUFFER,*PNAME_BUFFER;参数说明如下:name,指定本地网络名字,该值对应NCB结构体的ncb_name字段。name_num,指定本地网络名字的数量,该值对应NCB结构体的ncb_num字段。name_flags,指定名字表条目的当前状态。4.ASTAT结构体ASTAT结构体用于描述网络适配器的状态和名字信息,定义代码如下:

typedefstruct{ADAPTER_STATUSadapt;NAME_BUFFERNameBuff[30];}ASTAT;参数adapt表示网络适配器的状态信息,参数NameBuff表示网络适配器中保存的本地网络名字信息。SUP-4.2.4Netbios()函数Netbios()函数用于解释和执行指定的网络控制块(NCB),语法如下:

UCHAR

Netbios(__inPCNBpcnb);

参数pcnb是指定NCB结构体的指针,用于描述网络控制块。如果执行同步请求命令,则函数的返回值为NCB结构体的编码。该值也保存在NCB结构体的ncb_retcode字段中。

异步请求的返回值有以下两种情况:(1)如果Netbios()返回时异步命令已经完成,则返回值为NCB结构体的编码,这与同步请求的返回值相同。(2)如果Netbios()返回时异步命令尚未完成,则返回值为0。如果pncb参数中指定的地址无效,则返回NRC_BADNCB。如果NCB结构体中ncb_length字段指定的缓冲区长度不正确,或者缓冲区不允许执行写操作,则返回NRC_BUFLEN。SUP-4.2.5获取LANA上的所有NetBIOS名字【例】编写程序,向本地名字表中添加一个名字UNIQUENAME,然后列出指定LANA0中定义的所有NetBIOS名字。第1个名字是本地计算机名,第2个名字是本地计算机所属的工作组名,最后一个名字是新添加的NetBIOS名字。下面对本实例中的代码进行介绍。

1.引用的头文件和库文件#include""#include<>#include<>#include<>#include<Nb30.h>#pragmacomment(lib,"netapi32.lib")

其中是定义NetBIOS结构体和函数的头文件,而则是NetBIOS编程所需要的静态库文件。2.常量和宏定义#defineLANANUM0 //本实例中操作的LANA编号//本实例中添加的名字,注意不能与本地计算机重名#defineLOCALNAME"UNIQUENAME“#defineNBCheck(x)if(NRC_GOODRET!=){\printf("Line%d:Got0x%xfromNetBios()\n",\__LINE__,);\}在使用宏NBCheck时,使用ncb结构体为参数。ncb结构体的ncb_retcode参数表示调用Netbios()函数的返回值。如果返回值不等于NRC_GOODRET,则表示函数调用失败,需要输出发生错误的行号和函数返回值,以便用户定位问题。3.NBReset()函数BOOLNBReset(intnLana,intnSessions,intnNames){NCBncb;//初始化ncb结构体memset(&ncb,0,sizeof(ncb)); //清空ncb结构体=NCBRESET; //执行NCBRESET命令=0; //分配新的lana_num资源=nLana; //设置lana_num资源ncb.ncb_callname[0]=nSessions;//设置最大会话数ncb.ncb_callname[2]=nNames; //设置最大名字数Netbios(&ncb); //执行NCBRESET命令NBCheck(ncb); //如果执行结果不正确,则输出//如果成功返回TRUE,否则返回FALSEreturn(NRC_GOODRET==);}4.NBAddName()函数BOOLNBAddName(intnLana,LPCSTRszName){NCBncb;memset(&ncb,0,sizeof(ncb)); //清空ncb结构体=NCBADDNAME; //执行NCBDDNAME命令=nLana; //设置lana_num//将szName赋值到中MakeNetbiosName((char*),szName);Netbios(&ncb); //执行NCBRESET命令NBCheck(ncb);//如果执行结果不正确,则输出 //如果成功返回TRUE,否则返回FALSEreturn(NRC_GOODRET==);}MakenetbiosName()函数//将szSrc中的名字赋值到achDest中,名字的长度为NCBNAMESZ//如果不足,则使用空格补齐voidMakeNetbiosName(char*achDest,LPCSTRszSrc){intcchSrc;

cchSrc=lstrlen(szSrc);if(cchSrc>NCBNAMSZ)cchSrc=NCBNAMSZ;

memset(achDest,'',NCBNAMSZ);memcpy(achDest,szSrc,cchSrc);}

5.NBAdapterStatus()函数//获取指定LANA的网络适配器信息//nLana,LANA编号//pBuffer,获取到的网络适配器缓冲区//cbBuffer,缓冲区长度//szName,主机名字BOOLNBAdapterStatus(intnLana,PVOIDpBuffer,intcbBuffer,LPCSTRszName){NCBncb; memset(&ncb,0,sizeof(ncb)); //清空ncb结构体=NCBASTAT;//设置执行NCBASTAT命令=nLana;//设置LANA编号//将获取到的数据保存到参数pBuffer中=(PUCHAR)pBuffer;=cbBuffer;//设置缓冲区长度//设置参数MakeNetbiosName((char*),szName);Netbios(&ncb); //执行NetBIOS命令NBCheck(ncb); //如果执行不成功,则输出返回值//如果成功返回TRUE,否则返回FALSEreturn(NRC_GOODRET==);}6.NBListNames()函数BOOLNBListNames(intnLana,LPCSTRszName){intcbBuffer; //获取数据的缓冲区ADAPTER_STATUS*pStatus; //保存网络适配器的信息NAME_BUFFER*pNames; //保存本地名字信息HANDLEhHeap; //当前调用进程的堆句柄

//当前调用进程的堆句柄hHeap=GetProcessHeap();//分配可能的最大缓冲区空间cbBuffer=sizeof(ADAPTER_STATUS)+255*sizeof(NAME_BUFFER); //为pStatus分配空间pStatus=(ADAPTER_STATUS*)HeapAlloc(hHeap,0,cbBuffer);if(NULL==pStatus)returnFALSE;//获取本地网络适配器信息,结果保存到pStatus中if(!NBAdapterStatus(nLana,(PVOID)pStatus,cbBuffer,szName)){HeapFree(hHeap,0,pStatus);returnFALSE;}//列出跟在ADAPTER_STATUS结构体后面的名字信息pNames=(NAME_BUFFER*)(pStatus+1);for(inti=0;i<pStatus->name_count;i++)printf("\t%.*s\n",NCBNAMSZ,pNames[i].name); //释放分配的堆空间HeapFree(hHeap,0,pStatus);

returnTRUE;}6.NBListNames()函数程序的运行过程如下:获取当前进程的堆句柄,然后在堆上分配可能的最大缓冲区空间,即一个ADAPTER_STATUS结构体占用的空间加上255个NAME_BUFFER结构体占用的空间。在执行NCBASTAT命令时,可以返回一个ADAPTER_STATUS结构体和一组(最多255个)NAME_BUFFER结构体。调用NBAdapterStatus()函数,获取本地网络适配器信息,结果保存到pStatus结构体中。在pStatus结构体后面紧跟着的是一组NAME_BUFFER结构体,将pName指针指向第1个NAME_BUFFER结构体。pStatus->name_count中保存着pStatus后面NAME_BUFFER结构体的数量。使用for语句遍历这些结构体,输出NAME_BUFFER结构体中的名字信息。释放分配的堆空间。SUP-4._tmain()函数int_tmain(intargc,_TCHAR*argv[]){ //初始化 if(!NBReset(LANANUM,20,30)) return-1; //向本地名字表中添加UNIQUENAME if(!NBAddName(LANANUM,LOCALNAME)) return-1; //列出本地名字表中的名字 if(!NBListNames(LANANUM,LOCALNAME)) return-1; printf("Succeeded.\n"); system("pause"); return0;}SUP-4.2.6获取网络适配器上的MAC地址【例】编写程序,获取网络适配器上的MAC地址。1.引用的头文件和库文件#include""#include<>#include<>#include<Nb30.h>#pragmacomment(lib,"netapi32.lib")2.结构体ASTAT结构体ASTAT用于定义网络适配器状态和名字表信息,代码如下:

typedefstruct_ASTAT_{ADAPTER_STATUSadapt;NAME_BUFFERNameBuff[30];}ASTAT,*PASTAT;ASTATAdapter;

ASTAT结构体变量Adapter用于保存执行NCBASTAT命令获取到的网络适配器状态和名字表信息。3._tmain()函数int_tmain(intargc,_TCHAR*argv[]){ NCBncb; //NCB结构体,用于设置执行的NetBIOS命令和参数UCHARuRetCode; //执行Netbios()函数的返回值memset(&ncb,0,sizeof(ncb)); //初始化ncb结构体=NCBRESET; //设置执行NCBRESET=0; //设置LANA编号//调用Netbios()函数,执行NCBRESET命令uRetCode=Netbios(&ncb);//输出执行NCBRESET命令的结果printf("TheNCBRESETreturncodeis:0x%x\n",uRetCode);memset(&ncb,0,sizeof(ncb)); //初始化ncb=NCBASTAT; //执行NCBASTAT命令=0; //设置LANA编号//设置执行NCBASTAT命令的参数,将获取到的网络适配器数据保存到Adapter结构体中memcpy(&,"*",16);=(UCHAR*)&Adapter;=sizeof(Adapter);//调用Netbios()函数,执行NCBASTAT命令uRetCode=Netbios(&ncb);printf("TheNCBASTATreturncodeis:0x%x\n",uRetCode);3._tmain()函数if(uRetCode==0){//输出MAC地址printf("TheEthernetNumberis:%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]);}system("pause");return0;}程序的运行过程执行NCBRESET命令,清空本地的名字表和会话表。执行NCBASTAT命令获取网络适配器信息。依次打印数组[]中的元素值,即输出MAC地址。SUP-4.3在程序中实现NBTSTAT命令的功能SUP-4.3.1本实例的工作原理SUP-4.3.2定义的结构体SUP-4.3.3为获取NetBIOS信息而定义的函数SUP-4.3.4实现NBTSTAT命令功能的主函数SUP-4.3.1本实例的工作原理SUP-4.3.2定义的结构体1.names结构体2.workstationNameThreadStruct结构体1.names结构体names结构体用于接收目标计算机发送回来的名字信息,代码如下:

structnames{ unsignedcharnb_name[16]; unsignedshortname_flags;};参数nb_name表示接收到的名字,name_flags用于标识名字的含义。2.workstationNameThreadStruct结构体workstationNameThreadStruct结构体用于保存获取NetBIOS信息的套接字和IP地址列表,代码如下:

structworkstationNameThreadStruct{ SOCKETs; std::map<unsignedlong,CDevice*>*ips;};

参数s指定发送和接收NetBIOS数据包的套接字,参数ips指定获取NetBIOS信息的IP地址列表。SUP-4.3.3为获取NetBIOS信息而定义的函数为了获取远程计算机的NetBIOS信息,在程序中需要向指定的IP地址发送NetBIOS请求包,然后创建一个线程来接收返回的NetBIOS回应包,最后将回应包中的信息解析成需要的数据。本节介绍实现这些功能的3个函数。1.GetHostInfo()函数2.NetBiosRecvThreadProc()函数3.GetEthernetAdapter()函数1.GetHostInfo()函数voidGetHostInfo(std::map<unsignedlong,CDevice*>&ips,inttimeout){SOCKETsock; //通信套接字structsockaddr_inorigen; //本地地址WSADATAwsaData; //WindowsSockets环境变量

//初始化WindowsSockets环境if(WSAStartup(MAKEWORD(2,1),&wsaData)!=0)return;//创建TCP/IP套接字if((sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==INVALID_SOCKET)return;//设置超时时间if(setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout))==SOCKET_ERROR){//释放资源closesocket(sock);WSACleanup();return;}……1.GetHostInfo()函数 //将套接字绑定到本地地址和端口 memset(&origen,0,sizeof(origen)); =AF_INET; =htonl(INADDR_ANY); =htons(0); if(bind(sock,(structsockaddr*)&origen,sizeof(origen))<0) { //释放资源 closesocket(sock); WSACleanup(); return; }

//为创建接收线程准备数据 workstationNameThreadStructunionStruct; =&ips; =sock;1.GetHostInfo()函数 //启动线程等待接收NetBIOS回应包 DWORDpid; HANDLEthreadHandle=CreateThread(NULL,0,NetBiosRecvThreadProc,(void*)&unionStruct,0,&pid);

//依次向ips中的每个IP地址的端口发送NetBIOS请求包(保存在input字符数组中) std::map<unsignedlong,CDevice*>::iteratoritr; for(itr=ips.begin();itr!=ips.end();itr++) { charinput[]="\x80\x94\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x20\x43\x4b\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x00\x00\x21\x00\x01"; structsockaddr_indest; //发送NetBios请求信息 memset(&dest,0,sizeof(dest)); =itr->first; =AF_INET; =htons(137); sendto(sock,input,sizeof(input)-1,0,(structsockaddr*)&dest,sizeof(dest)); }1.GetHostInfo()函数 //等待接收线程NetBiosRecvThreadProc结束 DWORDret=WaitForSingleObject(threadHandle,timeout*4); //如果超时,则结束接收线程NetBiosRecvThreadProc if(ret==WAIT_TIMEOUT) Terminat

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论