




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
計(jì)算機(jī)軟件與應(yīng)用NetBIOSSUP-4NetBIOS網(wǎng)絡(luò)編程技術(shù)課程描述NetBIOS(NETworkBasicInput/OutputSystem,網(wǎng)絡(luò)基本輸入/輸出系統(tǒng))定義了一種軟件接口以及在應(yīng)用程序和連接介質(zhì)之間提供通信接口的標(biāo)準(zhǔn)方法。它可以提供名字服務(wù)、會話服務(wù)和數(shù)據(jù)庫服務(wù),基于NetBIOS的比較典型的應(yīng)用是獲取遠(yuǎn)程計(jì)算機(jī)的Mac地址、名稱和所在工作組等信息。本章將對NetBIOS網(wǎng)絡(luò)編程技術(shù)進(jìn)行介紹。本章知識點(diǎn)SUP-4.1NetBIOS協(xié)議及應(yīng)用SUP-4.2NetBIOS開發(fā)接口SUP-4.3在程序中實(shí)現(xiàn)NBTSTAT命令的功能SUP-4.1NetBIOS協(xié)議及應(yīng)用SUP-4.1.1NetBIOS協(xié)議SUP-4.1.2使用NBTSTAT命令SUP-4.1.1NetBIOS協(xié)議NetBIOS協(xié)議最初由IBM開發(fā),微軟公司在此基礎(chǔ)上對該協(xié)議進(jìn)行了完善,并在Windows上提供了對NetBIOS協(xié)議的支持。網(wǎng)絡(luò)鄰居功能就是基于NetBIOS協(xié)議的。在Windows中安裝TCP/IP協(xié)議的同時就會安裝NetBIOS協(xié)議。下面介紹一下在Windows2003中啟用和配置NetBIOS協(xié)議的方法。
配置NetBIOS右鍵單擊桌面上的網(wǎng)絡(luò)鄰居圖標(biāo),在彈出菜單中選擇“屬性”,打開“網(wǎng)絡(luò)連接”窗口。右鍵單擊“本地連接”圖標(biāo),在彈出菜單中選擇“屬性”,打開“本地連接屬性”對話框。
配置NetBIOS選中“Internet協(xié)議(TCP/IP)”項(xiàng),單擊“屬性”按鈕,打開“Internet協(xié)議(TCP/IP)”屬性對話框。單擊“高級”按鈕,打開“高級TCP/IP設(shè)置”對話框。單擊“WINS”選項(xiàng)卡,可以對NetBIOS協(xié)議進(jìn)行設(shè)置。1.LANA編號LANA(LANAdapter,LAN適配器)編號是NetBIOS進(jìn)行網(wǎng)絡(luò)編程的關(guān)鍵,它對應(yīng)于網(wǎng)卡及傳輸協(xié)議的唯一組合。例如,假定某個工作站安裝了兩塊網(wǎng)卡,以及兩種具有NetBIOS能力的傳輸協(xié)議(例如TCP/IP和NetBEUI),那么將共有下面4個LANA編號:表示“TCP/IP—網(wǎng)卡1”對。表示“NetBEUI—網(wǎng)卡1”對。表示“TCP/IP—網(wǎng)卡2”對。表示“NetBEUI—網(wǎng)卡2”對。2.名字服務(wù)NetBIOS協(xié)議支持建立名字服務(wù)器,負(fù)責(zé)查找目標(biāo)主機(jī)對應(yīng)的IP地址,并賦予一個NetBIOS名稱。名字服務(wù)提供的主要功能如下:添加名字,即注冊一個NetBIOS名字。添加組名,即注冊一個NetBIOS組名。刪除名字,即取消一個NetBIOS名字和組名的注冊。查詢名字,即在網(wǎng)絡(luò)中搜索NetBIOS名字。3.會話服務(wù)會話服務(wù)提供的主要功能如下:調(diào)用,即打開一個到遠(yuǎn)程N(yùn)etBIOS名字的會話。偵聽,即偵聽其他程序的連接請求。掛起,即關(guān)閉一個會話。發(fā)送,即向會話對端的計(jì)算機(jī)發(fā)送一個數(shù)據(jù)包,并等待對方確認(rèn)。無確認(rèn)發(fā)送,即向會話對端的計(jì)算機(jī)發(fā)送一個數(shù)據(jù)包,但不需要對方確認(rèn)。接收,即等待從會話對端發(fā)送的數(shù)據(jù)包到達(dá)。4.?dāng)?shù)據(jù)報服務(wù)數(shù)據(jù)報服務(wù)提供的主要功能如下:發(fā)送數(shù)據(jù)報,即向遠(yuǎn)程N(yùn)etBIOS名字發(fā)送一個數(shù)據(jù)報。發(fā)送廣播數(shù)據(jù)報,即向網(wǎng)絡(luò)中所有NetBIOS名字發(fā)送數(shù)據(jù)報。接收數(shù)據(jù)報,即等待從發(fā)送數(shù)據(jù)報操作中到達(dá)的數(shù)據(jù)。接收廣播數(shù)據(jù)報,即等待從發(fā)送廣播數(shù)據(jù)報操作中到達(dá)的數(shù)據(jù)。在Windows中,如果安裝了NetBIOS協(xié)議,則系統(tǒng)將自動開放下列端口:137端口,主要作用是在局域網(wǎng)中提供計(jì)算機(jī)的名稱或IP地址查詢服務(wù)。138端口,主要作用是提供NetBIOS環(huán)境下的計(jì)算機(jī)名瀏覽功能。139端口,主要作用是提供文件和打印機(jī)共享的功能。SUP-4.1.2使用NBTSTAT命令在Windows命令窗口中執(zhí)行NBTSTAT命令,可以獲取指定遠(yuǎn)程計(jì)算機(jī)的基本信息,包括Mac地址、計(jì)算機(jī)名和所屬工作組等。NBTSTAT命令的格式如下:
NBTSTAT[[-aRemoteName][-AIPaddress][-c][-n][-r][-R][-RR][-s][-S][interval]]NBTSTAT參數(shù)的具體說明參
數(shù)說
明-aRemoteName列出指定名稱的遠(yuǎn)程機(jī)器的名稱表,RemoteName表示指定的遠(yuǎn)程主機(jī)計(jì)算機(jī)名-AIPaddress列出指定
IP地址的遠(yuǎn)程機(jī)器的名稱表,IPaddress表示用點(diǎn)分法表示的IP地址-c列出遠(yuǎn)程計(jì)算機(jī)名稱及其IP地址的
NBT緩存-n列出本地的NetBIOS名稱-r列出通過廣播和經(jīng)由WINS解析的名稱-R清除和重新加載遠(yuǎn)程緩存名稱表-RR將名稱釋放包發(fā)送到WINS,然后啟動刷新-s列出將目標(biāo)IP地址轉(zhuǎn)換成計(jì)算機(jī)NetBIOS名稱的會話表-S列出具有目標(biāo)IP地址的會話表interval重新顯示選定的統(tǒng)計(jì)、每次顯示之間暫停的間隔秒數(shù)。按Ctrl+C停止重新顯示統(tǒng)計(jì)實(shí)例NBTSTAT-aLEE-THINKPADSUP-4.2NetBIOS開發(fā)接口SUP-4.2.1NetBIOS操作SUP-4.2.2NCB結(jié)構(gòu)體SUP-4.2.3其他常用NetBIOS結(jié)構(gòu)體SUP-4.2.4Netbios()函數(shù)SUP-4.2.5獲取LANA上的所有NetBIOS名字SUP-4.2.6獲取網(wǎng)絡(luò)適配器上的MAC地址SUP-4.2.1NetBIOS操作協(xié)議驅(qū)動程序?qū)ν夤糔etBIOS接口,并將NetBIOS命令映射到協(xié)議驅(qū)動程序的內(nèi)部命令。NetBIOS模擬器接收NetBIOS命令,將它們轉(zhuǎn)換成TDI(TransportDriverInterface,傳輸驅(qū)動程序接口)調(diào)用,然后使用TDI接口將它們轉(zhuǎn)發(fā)到傳輸驅(qū)動程序。在Windows2003、WindowsXP、Windows2000和WindowsNT操作系統(tǒng)中,NetBIOS操作的流程如下:SUP-4.2.2NCB結(jié)構(gòu)體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非標(biāo)準(zhǔn)NetBIOS3.0命令NCBADDGRNAME向本地名字表中添加一個組名,組名在網(wǎng)絡(luò)中必須是唯一的NCBADDNAME向本地名字表中添加一個唯一的名字NCBASTAT獲取本地或遠(yuǎn)程網(wǎng)絡(luò)適配器的狀態(tài)。如果指定了此編碼,則成員變量_buffer指向填充了ADAPTER_STATUS結(jié)構(gòu)體和NAME_BUFFER結(jié)構(gòu)體數(shù)組的緩沖區(qū)NCBCALL打開與其他名字之間的會話NCBCANCEL取消之前掛起的命令NCBCHAINSEND向指定的會話伙伴發(fā)送兩個數(shù)據(jù)緩沖區(qū)的內(nèi)容NCBCHAINSENDNA向指定的會話伙伴發(fā)送兩個數(shù)據(jù)緩沖區(qū)的內(nèi)容,并且不等待對方確認(rèn)NCBDELNAME從本地名字表中刪除一個名字NCBDGRECV獲取來自任意名字的數(shù)據(jù)包NCBDGRECVBC獲取來自任意名字的廣播數(shù)據(jù)包NCBDGSEND向指定名字發(fā)送數(shù)據(jù)包NCBDGSENDBC向局域網(wǎng)中的所有計(jì)算機(jī)發(fā)送廣播數(shù)據(jù)包NCBENUM用于枚舉LANA編號。如果指定此編碼,則成員變量ncb_buffer指定填充了LANA_ENUM結(jié)構(gòu)體的緩沖區(qū)。NCBENUM不是標(biāo)準(zhǔn)的NetBIOS3.0命令NCBFINDNAME決定指定名字在網(wǎng)絡(luò)中的位置。如果指定此編碼,則成員變量_buffer指定填充了FIND_NAME_HEADER結(jié)構(gòu)體和FIND_NAME_BUFFER結(jié)構(gòu)體的緩沖區(qū)NCBHANGUP關(guān)閉指定的會話NCBLANSTALERT只對WindowsServer2003、WindowsXP、Windows2000和WindowsNT等操作系統(tǒng)有效,提示用戶持續(xù)時間在1分鐘以上的局域網(wǎng)故障NCBLISTEN允許一個會話可以被其他名字打開NCBRECV從指定的會話伙伴獲取數(shù)據(jù)NCBRECVANY從指定名字對應(yīng)的會話中獲取數(shù)據(jù)NCBRESET復(fù)位局域網(wǎng)網(wǎng)絡(luò)適配器NCBSEND向指定的會話伙伴發(fā)送數(shù)據(jù)NCBSENDNA向指定的會話伙伴發(fā)送數(shù)據(jù),并且不等待對方確認(rèn)NCBSSTAT獲取會話的狀態(tài)。如果指定了此參數(shù),則成員變量_buffer指向填充了SESSION_HEADER和SESSION_BUFFER結(jié)構(gòu)體的緩沖區(qū)NCBTRACE激活或取消NCB跟蹤。此命令目前不被支持NCBUNLINK斷開一個網(wǎng)絡(luò)適配器的連接。此命令只為與之前版本的NetBIOS兼容而提供,但在Windows中無效2.ncb_retcode返回編碼可選值說
明NRC_GOODRET操作成功NRC_BUFLEN提供了無效的緩沖區(qū)長度NRC_ILLCMD提供了無效的命令NRC_CMDTMO命令超時NRC_INCOMP消息不完整,應(yīng)用程序正在執(zhí)行其他命令NRC_BADDR緩沖區(qū)地址無效NRC_SNUMOUT會話編號越界NRC_NORES沒有有效的資源NRC_SCLOSED會話已被關(guān)閉NRC_CMDCAN命令被取消NRC_DUPNAME在本地名字表中存在相同的名字NRC_NAMTFUL名字表已滿NRC_ACTSES命令已執(zhí)行完成,指定名字擁有活動的會話,并且不再注冊NRC_LOCTFUL本地會話表已滿NRC_REMTFUL遠(yuǎn)端會話表已滿,打開會話的請求被拒絕NRC_ILLNN指定了無效的名稱編號NRC_NOCALL系統(tǒng)沒有發(fā)現(xiàn)調(diào)用的名字NRC_NOWILD成員變量ncb_name中不允許通配符NRC_INUSE名字已經(jīng)在遠(yuǎn)程適配器上使用NRC_NAMERR名字已被刪除NRC_SABORT會話非正常結(jié)束NRC_NAMCONF檢測到名字沖突NRC_IFBUSY接口忙NRC_TOOMANY命令太多,應(yīng)用程序?qū)⒃谏院笾卦嚸頝RC_BRIDGE成員變量ncb_lana_num沒有指定有效的網(wǎng)絡(luò)編號NRC_CANOCCR執(zhí)行取消操作后,命令已經(jīng)結(jié)束NRC_CANCELNCBCANCEL命令無效,命令并未取消NRC_DUPENV名字已經(jīng)被另一個本地進(jìn)程占用NRC_ENVNOTDEF環(huán)境沒有被定義,因此必須執(zhí)行一個重置命令NRC_OSRESNOTAV操作系統(tǒng)資源被耗光,該命令稍候會重試NRC_MAXAPPS應(yīng)用程序數(shù)量超過規(guī)定的最大值NRC_NOSAPS沒有對NetBIOS有效的服務(wù)訪問點(diǎn)(SAP,ServiceAccesPoints)NRC_NORESOURCES請求的資源無效NRC_INVADDRESSNCB地址無效NRC_INVDDIDNCBDDID無效NRC_LOCKFAIL嘗試鎖定用戶區(qū)域失敗NRC_OPENERR當(dāng)設(shè)備驅(qū)動器執(zhí)行打開操作時發(fā)生錯誤。錯誤編碼并不在NetBIOS3.0中定義NRC_SYSTEM發(fā)生系統(tǒng)錯誤NRC_PENDING異步操作并未結(jié)束NCB結(jié)構(gòu)體其他成員變量3.ncb_lsn表示本地會話編號。在指定環(huán)境中此編號唯一標(biāo)識一個會話。調(diào)用Netbios()函數(shù)成功執(zhí)行了NCBCALL命令后返回此編號。4.ncb_num指定本地網(wǎng)絡(luò)名字編號。調(diào)用Netbios()函數(shù)成功執(zhí)行了NCBADDNAME或者NCBADDGRNAME命令后返回此編號。此編號在所有數(shù)據(jù)包命令和NCBRECVANY命令中使用。5.ncb_buffer指向消息緩沖區(qū)??梢允褂帽碇械拿钤L問消息緩沖區(qū)。命
令說
明NCBSEND發(fā)送消息NCBRECV接收消息NCBSSTAT接收請求狀態(tài)信息NCB結(jié)構(gòu)體其他成員變量6.ncb_length指定消息緩沖區(qū)的大小,單位為字節(jié)。對于接收命令,此成員變量由Netbios()函數(shù)設(shè)置,表示接收到的字節(jié)數(shù)。如果緩沖區(qū)長度不正確,則Netbios()函數(shù)返回NRC_BUFLEN錯誤編碼。指定遠(yuǎn)端應(yīng)用程序的名字。8.ncb_name指定應(yīng)用程序可以識別的名字。9.ncb_rto指定會話執(zhí)行接收操作的超時時間。將此成員變量指定為0,表示在執(zhí)行NCBCALL和NCBLISTEN命令時沒有超時。超時會影響隨后執(zhí)行的NCBRECV命令。10.ncb_sto指定會話執(zhí)行發(fā)送操作的超時時間。將此成員變量指定為0,表示在執(zhí)行NCBCALL和NCBLISTEN命令時沒有超時。超時會影響隨后執(zhí)行的NCBSEND和NCBCHAINSEND命令。11.ncb_post指定異步命令完成后需調(diào)用的例程地址。12.ncb_lana_num指定LANA編號。13.ncb_cmd_cplt指定命令完成標(biāo)識。14.ncb_reserve保留字段,必須為0。15.ncb_event指定事件對象的句柄。當(dāng)執(zhí)行異步命令時,事件對象被設(shè)置為未受信狀態(tài);當(dāng)異步命令完成后,事件對象被設(shè)置為受信狀態(tài),這樣就可以執(zhí)行對應(yīng)的事件處理程序了。SUP-4.2.3其他常用NetBIOS結(jié)構(gòu)體1.LANA_ENUM結(jié)構(gòu)體2.ADAPTER_STATUS結(jié)構(gòu)體3.NAME_BUFFER結(jié)構(gòu)體4.ASTAT結(jié)構(gòu)體1.LANA_ENUM結(jié)構(gòu)體LANA_ENUM結(jié)構(gòu)體中包含當(dāng)前邏輯網(wǎng)絡(luò)適配器的數(shù)量。當(dāng)一個物理網(wǎng)絡(luò)適配器綁定到一個網(wǎng)絡(luò)協(xié)議時,就對應(yīng)一個邏輯網(wǎng)絡(luò)適配器。執(zhí)行NCB命令NCBENUM可以向LANA_ENUM結(jié)構(gòu)體中填充邏輯網(wǎng)絡(luò)適配器的個數(shù)和邏輯網(wǎng)絡(luò)適配器編號,此時NCB結(jié)構(gòu)體中的ncb_buffer成員變量指向LANA_ENUM結(jié)構(gòu)體。LANA_ENUM結(jié)構(gòu)體的定義代碼如下:
typedefstruct_LANA_ENUM{UCHARlength;UCHARlana[MAX_LANA];}LANA_ENUM,*PLANA_ENUM;
參數(shù)說明如下:length,系統(tǒng)中包含的邏輯網(wǎng)絡(luò)適配器數(shù)量。lana[MAX_LANA],系統(tǒng)中包含的邏輯網(wǎng)絡(luò)適配器編號數(shù)組。2.ADAPTER_STATUS結(jié)構(gòu)體ADAPTER_STATUS結(jié)構(gòu)體中包含網(wǎng)絡(luò)適配器的信息。NCB結(jié)構(gòu)體的ncb_buffer成員變量指定該結(jié)構(gòu)體。通常,ADAPTER_STATUS結(jié)構(gòu)體的后面跟著很多NAME_BUFFER結(jié)構(gòu)體。ADPATER_STATUS結(jié)構(gòu)體的定義代碼如下:
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結(jié)構(gòu)體參數(shù)說明adapter_address,指定網(wǎng)絡(luò)適配器的地址。rev_major,指定發(fā)布軟件的主版本號。例如,如果發(fā)布版本號為,則rev_major的值為3。reserved0,保留字段,始終為0。adapter_type,指定網(wǎng)絡(luò)適配器的類型。如果是令牌環(huán)適配器,則該值為0xFF;如果是以太網(wǎng)適配器,則該值為0xFE。rev_minor,指定發(fā)布軟件的副版本號。例如,如果發(fā)布版本號為,則rev_minor的值為0。duration,指定報告的時間周期,單位為分鐘。frmr_recv,指定接收到的FRMR(幀拒絕)幀數(shù)量。frmr_xmit,指定傳送的FRMR幀數(shù)量。iframe_recv_err,指定接收到的錯誤幀數(shù)量。xmit_aborts,指定終止傳輸?shù)陌鼣?shù)量。xmit_success,指定成功傳輸?shù)陌鼣?shù)量。recv_success,指定成功接收的包數(shù)量。iframe_xmit_err,指定傳輸?shù)腻e誤幀數(shù)量。recv_buff_unavail,指定緩沖區(qū)無法為遠(yuǎn)程計(jì)算機(jī)提供服務(wù)的次數(shù)。t1_timeouts,指定DLC(DataLinkControl,數(shù)據(jù)鏈路控制)T1計(jì)時器超時的次數(shù)。ti_timeouts,指定ti非活動計(jì)時器超時的次數(shù)。t1計(jì)時器用于檢測斷開的連接。reserved1,保留字段,始終為0。free_ncbs,指定當(dāng)前空閑的網(wǎng)絡(luò)控制塊的數(shù)量。max_dgram_size,指定數(shù)據(jù)包的最大大小,該值至少為512字節(jié)。pendingsess,指定掛起會話的數(shù)量。max_cfg_sess,指定配置的最大掛起會話數(shù)量。max_sess_pkt_size,指定會話數(shù)據(jù)包的最大大小。name_count,指定本地名字表中名字的數(shù)量。3.NAME_BUFFER結(jié)構(gòu)體結(jié)構(gòu)體NAME_BUFFER中包含本地網(wǎng)絡(luò)名字信息。當(dāng)應(yīng)用程序執(zhí)行NCBASTAT命令時,可以獲取ADAPTER_STATUS結(jié)構(gòu)體及其后面的NAME_BUFFER結(jié)構(gòu)體。NAME_BUFFER結(jié)構(gòu)體。typedefstruct_NAME_BUFFER{UCHARname[NCBNAMSZ];UCHARname_num;UCHARname_flags;}NAME_BUFFER,*PNAME_BUFFER;參數(shù)說明如下:name,指定本地網(wǎng)絡(luò)名字,該值對應(yīng)NCB結(jié)構(gòu)體的ncb_name字段。name_num,指定本地網(wǎng)絡(luò)名字的數(shù)量,該值對應(yīng)NCB結(jié)構(gòu)體的ncb_num字段。name_flags,指定名字表?xiàng)l目的當(dāng)前狀態(tài)。4.ASTAT結(jié)構(gòu)體ASTAT結(jié)構(gòu)體用于描述網(wǎng)絡(luò)適配器的狀態(tài)和名字信息,定義代碼如下:
typedefstruct{ADAPTER_STATUSadapt;NAME_BUFFERNameBuff[30];}ASTAT;參數(shù)adapt表示網(wǎng)絡(luò)適配器的狀態(tài)信息,參數(shù)NameBuff表示網(wǎng)絡(luò)適配器中保存的本地網(wǎng)絡(luò)名字信息。SUP-4.2.4Netbios()函數(shù)Netbios()函數(shù)用于解釋和執(zhí)行指定的網(wǎng)絡(luò)控制塊(NCB),語法如下:
UCHAR
Netbios(__inPCNBpcnb);
參數(shù)pcnb是指定NCB結(jié)構(gòu)體的指針,用于描述網(wǎng)絡(luò)控制塊。如果執(zhí)行同步請求命令,則函數(shù)的返回值為NCB結(jié)構(gòu)體的編碼。該值也保存在NCB結(jié)構(gòu)體的ncb_retcode字段中。
異步請求的返回值有以下兩種情況:(1)如果Netbios()返回時異步命令已經(jīng)完成,則返回值為NCB結(jié)構(gòu)體的編碼,這與同步請求的返回值相同。(2)如果Netbios()返回時異步命令尚未完成,則返回值為0。如果pncb參數(shù)中指定的地址無效,則返回NRC_BADNCB。如果NCB結(jié)構(gòu)體中ncb_length字段指定的緩沖區(qū)長度不正確,或者緩沖區(qū)不允許執(zhí)行寫操作,則返回NRC_BUFLEN。SUP-4.2.5獲取LANA上的所有NetBIOS名字【例】編寫程序,向本地名字表中添加一個名字UNIQUENAME,然后列出指定LANA0中定義的所有NetBIOS名字。第1個名字是本地計(jì)算機(jī)名,第2個名字是本地計(jì)算機(jī)所屬的工作組名,最后一個名字是新添加的NetBIOS名字。下面對本實(shí)例中的代碼進(jìn)行介紹。
1.引用的頭文件和庫文件#include""#include<>#include<>#include<>#include<Nb30.h>#pragmacomment(lib,"netapi32.lib")
其中是定義NetBIOS結(jié)構(gòu)體和函數(shù)的頭文件,而則是NetBIOS編程所需要的靜態(tài)庫文件。2.常量和宏定義#defineLANANUM0 //本實(shí)例中操作的LANA編號//本實(shí)例中添加的名字,注意不能與本地計(jì)算機(jī)重名#defineLOCALNAME"UNIQUENAME“#defineNBCheck(x)if(NRC_GOODRET!=){\printf("Line%d:Got0x%xfromNetBios()\n",\__LINE__,);\}在使用宏NBCheck時,使用ncb結(jié)構(gòu)體為參數(shù)。ncb結(jié)構(gòu)體的ncb_retcode參數(shù)表示調(diào)用Netbios()函數(shù)的返回值。如果返回值不等于NRC_GOODRET,則表示函數(shù)調(diào)用失敗,需要輸出發(fā)生錯誤的行號和函數(shù)返回值,以便用戶定位問題。3.NBReset()函數(shù)BOOLNBReset(intnLana,intnSessions,intnNames){NCBncb;//初始化ncb結(jié)構(gòu)體memset(&ncb,0,sizeof(ncb)); //清空ncb結(jié)構(gòu)體=NCBRESET; //執(zhí)行NCBRESET命令=0; //分配新的lana_num資源=nLana; //設(shè)置lana_num資源ncb.ncb_callname[0]=nSessions;//設(shè)置最大會話數(shù)ncb.ncb_callname[2]=nNames; //設(shè)置最大名字?jǐn)?shù)Netbios(&ncb); //執(zhí)行NCBRESET命令NBCheck(ncb); //如果執(zhí)行結(jié)果不正確,則輸出//如果成功返回TRUE,否則返回FALSEreturn(NRC_GOODRET==);}4.NBAddName()函數(shù)BOOLNBAddName(intnLana,LPCSTRszName){NCBncb;memset(&ncb,0,sizeof(ncb)); //清空ncb結(jié)構(gòu)體=NCBADDNAME; //執(zhí)行NCBDDNAME命令=nLana; //設(shè)置lana_num//將szName賦值到中MakeNetbiosName((char*),szName);Netbios(&ncb); //執(zhí)行NCBRESET命令NBCheck(ncb);//如果執(zhí)行結(jié)果不正確,則輸出 //如果成功返回TRUE,否則返回FALSEreturn(NRC_GOODRET==);}MakenetbiosName()函數(shù)//將szSrc中的名字賦值到achDest中,名字的長度為NCBNAMESZ//如果不足,則使用空格補(bǔ)齊voidMakeNetbiosName(char*achDest,LPCSTRszSrc){intcchSrc;
cchSrc=lstrlen(szSrc);if(cchSrc>NCBNAMSZ)cchSrc=NCBNAMSZ;
memset(achDest,'',NCBNAMSZ);memcpy(achDest,szSrc,cchSrc);}
5.NBAdapterStatus()函數(shù)//獲取指定LANA的網(wǎng)絡(luò)適配器信息//nLana,LANA編號//pBuffer,獲取到的網(wǎng)絡(luò)適配器緩沖區(qū)//cbBuffer,緩沖區(qū)長度//szName,主機(jī)名字BOOLNBAdapterStatus(intnLana,PVOIDpBuffer,intcbBuffer,LPCSTRszName){NCBncb; memset(&ncb,0,sizeof(ncb)); //清空ncb結(jié)構(gòu)體=NCBASTAT;//設(shè)置執(zhí)行NCBASTAT命令=nLana;//設(shè)置LANA編號//將獲取到的數(shù)據(jù)保存到參數(shù)pBuffer中=(PUCHAR)pBuffer;=cbBuffer;//設(shè)置緩沖區(qū)長度//設(shè)置參數(shù)MakeNetbiosName((char*),szName);Netbios(&ncb); //執(zhí)行NetBIOS命令NBCheck(ncb); //如果執(zhí)行不成功,則輸出返回值//如果成功返回TRUE,否則返回FALSEreturn(NRC_GOODRET==);}6.NBListNames()函數(shù)BOOLNBListNames(intnLana,LPCSTRszName){intcbBuffer; //獲取數(shù)據(jù)的緩沖區(qū)ADAPTER_STATUS*pStatus; //保存網(wǎng)絡(luò)適配器的信息NAME_BUFFER*pNames; //保存本地名字信息HANDLEhHeap; //當(dāng)前調(diào)用進(jìn)程的堆句柄
//當(dāng)前調(diào)用進(jìn)程的堆句柄hHeap=GetProcessHeap();//分配可能的最大緩沖區(qū)空間cbBuffer=sizeof(ADAPTER_STATUS)+255*sizeof(NAME_BUFFER); //為pStatus分配空間pStatus=(ADAPTER_STATUS*)HeapAlloc(hHeap,0,cbBuffer);if(NULL==pStatus)returnFALSE;//獲取本地網(wǎng)絡(luò)適配器信息,結(jié)果保存到pStatus中if(!NBAdapterStatus(nLana,(PVOID)pStatus,cbBuffer,szName)){HeapFree(hHeap,0,pStatus);returnFALSE;}//列出跟在ADAPTER_STATUS結(jié)構(gòu)體后面的名字信息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()函數(shù)程序的運(yùn)行過程如下:獲取當(dāng)前進(jìn)程的堆句柄,然后在堆上分配可能的最大緩沖區(qū)空間,即一個ADAPTER_STATUS結(jié)構(gòu)體占用的空間加上255個NAME_BUFFER結(jié)構(gòu)體占用的空間。在執(zhí)行NCBASTAT命令時,可以返回一個ADAPTER_STATUS結(jié)構(gòu)體和一組(最多255個)NAME_BUFFER結(jié)構(gòu)體。調(diào)用NBAdapterStatus()函數(shù),獲取本地網(wǎng)絡(luò)適配器信息,結(jié)果保存到pStatus結(jié)構(gòu)體中。在pStatus結(jié)構(gòu)體后面緊跟著的是一組NAME_BUFFER結(jié)構(gòu)體,將pName指針指向第1個NAME_BUFFER結(jié)構(gòu)體。pStatus->name_count中保存著pStatus后面NAME_BUFFER結(jié)構(gòu)體的數(shù)量。使用for語句遍歷這些結(jié)構(gòu)體,輸出NAME_BUFFER結(jié)構(gòu)體中的名字信息。釋放分配的堆空間。SUP-4._tmain()函數(shù)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獲取網(wǎng)絡(luò)適配器上的MAC地址【例】編寫程序,獲取網(wǎng)絡(luò)適配器上的MAC地址。1.引用的頭文件和庫文件#include""#include<>#include<>#include<Nb30.h>#pragmacomment(lib,"netapi32.lib")2.結(jié)構(gòu)體ASTAT結(jié)構(gòu)體ASTAT用于定義網(wǎng)絡(luò)適配器狀態(tài)和名字表信息,代碼如下:
typedefstruct_ASTAT_{ADAPTER_STATUSadapt;NAME_BUFFERNameBuff[30];}ASTAT,*PASTAT;ASTATAdapter;
ASTAT結(jié)構(gòu)體變量Adapter用于保存執(zhí)行NCBASTAT命令獲取到的網(wǎng)絡(luò)適配器狀態(tài)和名字表信息。3._tmain()函數(shù)int_tmain(intargc,_TCHAR*argv[]){ NCBncb; //NCB結(jié)構(gòu)體,用于設(shè)置執(zhí)行的NetBIOS命令和參數(shù)UCHARuRetCode; //執(zhí)行Netbios()函數(shù)的返回值memset(&ncb,0,sizeof(ncb)); //初始化ncb結(jié)構(gòu)體=NCBRESET; //設(shè)置執(zhí)行NCBRESET=0; //設(shè)置LANA編號//調(diào)用Netbios()函數(shù),執(zhí)行NCBRESET命令uRetCode=Netbios(&ncb);//輸出執(zhí)行NCBRESET命令的結(jié)果printf("TheNCBRESETreturncodeis:0x%x\n",uRetCode);memset(&ncb,0,sizeof(ncb)); //初始化ncb=NCBASTAT; //執(zhí)行NCBASTAT命令=0; //設(shè)置LANA編號//設(shè)置執(zhí)行NCBASTAT命令的參數(shù),將獲取到的網(wǎng)絡(luò)適配器數(shù)據(jù)保存到Adapter結(jié)構(gòu)體中memcpy(&,"*",16);=(UCHAR*)&Adapter;=sizeof(Adapter);//調(diào)用Netbios()函數(shù),執(zhí)行NCBASTAT命令uRetCode=Netbios(&ncb);printf("TheNCBASTATreturncodeis:0x%x\n",uRetCode);3._tmain()函數(shù)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;}程序的運(yùn)行過程執(zhí)行NCBRESET命令,清空本地的名字表和會話表。執(zhí)行NCBASTAT命令獲取網(wǎng)絡(luò)適配器信息。依次打印數(shù)組[]中的元素值,即輸出MAC地址。SUP-4.3在程序中實(shí)現(xiàn)NBTSTAT命令的功能SUP-4.3.1本實(shí)例的工作原理SUP-4.3.2定義的結(jié)構(gòu)體SUP-4.3.3為獲取NetBIOS信息而定義的函數(shù)SUP-4.3.4實(shí)現(xiàn)NBTSTAT命令功能的主函數(shù)SUP-4.3.1本實(shí)例的工作原理SUP-4.3.2定義的結(jié)構(gòu)體1.names結(jié)構(gòu)體2.workstationNameThreadStruct結(jié)構(gòu)體1.names結(jié)構(gòu)體names結(jié)構(gòu)體用于接收目標(biāo)計(jì)算機(jī)發(fā)送回來的名字信息,代碼如下:
structnames{ unsignedcharnb_name[16]; unsignedshortname_flags;};參數(shù)nb_name表示接收到的名字,name_flags用于標(biāo)識名字的含義。2.workstationNameThreadStruct結(jié)構(gòu)體workstationNameThreadStruct結(jié)構(gòu)體用于保存獲取NetBIOS信息的套接字和IP地址列表,代碼如下:
structworkstationNameThreadStruct{ SOCKETs; std::map<unsignedlong,CDevice*>*ips;};
參數(shù)s指定發(fā)送和接收NetBIOS數(shù)據(jù)包的套接字,參數(shù)ips指定獲取NetBIOS信息的IP地址列表。SUP-4.3.3為獲取NetBIOS信息而定義的函數(shù)為了獲取遠(yuǎn)程計(jì)算機(jī)的NetBIOS信息,在程序中需要向指定的IP地址發(fā)送NetBIOS請求包,然后創(chuàng)建一個線程來接收返回的NetBIOS回應(yīng)包,最后將回應(yīng)包中的信息解析成需要的數(shù)據(jù)。本節(jié)介紹實(shí)現(xiàn)這些功能的3個函數(shù)。1.GetHostInfo()函數(shù)2.NetBiosRecvThreadProc()函數(shù)3.GetEthernetAdapter()函數(shù)1.GetHostInfo()函數(shù)voidGetHostInfo(std::map<unsignedlong,CDevice*>&ips,inttimeout){SOCKETsock; //通信套接字structsockaddr_inorigen; //本地地址WSADATAwsaData; //WindowsSockets環(huán)境變量
//初始化WindowsSockets環(huán)境if(WSAStartup(MAKEWORD(2,1),&wsaData)!=0)return;//創(chuàng)建TCP/IP套接字if((sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==INVALID_SOCKET)return;//設(shè)置超時時間if(setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout))==SOCKET_ERROR){//釋放資源closesocket(sock);WSACleanup();return;}……1.GetHostInfo()函數(shù) //將套接字綁定到本地地址和端口 memset(&origen,0,sizeof(origen)); =AF_INET; =htonl(INADDR_ANY); =htons(0); if(bind(sock,(structsockaddr*)&origen,sizeof(origen))<0) { //釋放資源 closesocket(sock); WSACleanup(); return; }
//為創(chuàng)建接收線程準(zhǔn)備數(shù)據(jù) workstationNameThreadStructunionStruct; =&ips; =sock;1.GetHostInfo()函數(shù) //啟動線程等待接收NetBIOS回應(yīng)包 DWORDpid; HANDLEthreadHandle=CreateThread(NULL,0,NetBiosRecvThreadProc,(void*)&unionStruct,0,&pid);
//依次向ips中的每個IP地址的端口發(fā)送NetBIOS請求包(保存在input字符數(shù)組中) 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; //發(fā)送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()函數(shù) //等待接收線程N(yùn)etBiosRecvThreadProc結(jié)束 DWORDret=WaitForSingleObject(threadHandle,timeout*4); //如果超時,則結(jié)束接收線程N(yùn)etBiosRecvThreadProc if(ret==WAIT_TIMEOUT) Terminat
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 藥店鋪貨合同協(xié)議書
- 代發(fā)合同協(xié)議書模板圖片
- 2025辦公室裝修設(shè)計(jì)合同范本,辦公室裝修設(shè)計(jì)合同樣本
- 富士康合同解除協(xié)議書
- 2025有關(guān)設(shè)備采購合同范本
- 測試內(nèi)存泄漏常見方法試題及答案
- 高頻交易系統(tǒng)中的嵌入式應(yīng)用試題及答案
- 軟考網(wǎng)絡(luò)工程師專業(yè)試題及答案分析
- 房產(chǎn)合同免責(zé)協(xié)議書范本
- 信息系統(tǒng)監(jiān)理師信息安全問題試題及答案
- (完整word版)電梯管理證復(fù)審申請表
- 材料科學(xué)基礎(chǔ)基礎(chǔ)知識點(diǎn)總結(jié)
- 醫(yī)學(xué)倫理審查申請表1
- 數(shù)控銑工圖紙(60份)(共60頁)
- 香樟栽植施工方案
- 惠州市出租車駕駛員從業(yè)資格區(qū)域科目考試題庫(含答案)
- 加工設(shè)備工時單價表
- 高脂血癥藥物治療ppt課件
- 高層建筑等電位聯(lián)結(jié)安裝技術(shù)分析探討
- 模型預(yù)測控制(課堂PPT)
- OQC出貨檢驗(yàn)規(guī)范及方法
評論
0/150
提交評論