第3章基于NetBIOS的網(wǎng)絡(luò)編程課件_第1頁
第3章基于NetBIOS的網(wǎng)絡(luò)編程課件_第2頁
第3章基于NetBIOS的網(wǎng)絡(luò)編程課件_第3頁
第3章基于NetBIOS的網(wǎng)絡(luò)編程課件_第4頁
第3章基于NetBIOS的網(wǎng)絡(luò)編程課件_第5頁
已閱讀5頁,還剩65頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

Windows網(wǎng)絡(luò)編程技術(shù)

第3章基于NetBIOS的網(wǎng)絡(luò)編程授課老師:胡鳴數(shù)學(xué)與計(jì)算機(jī)學(xué)院計(jì)算機(jī)系Windows網(wǎng)絡(luò)編程技術(shù)

第3章基于NetBIOS的網(wǎng)絡(luò)編1本章提綱3.1基于NetBIOS網(wǎng)絡(luò)編程的基礎(chǔ)3.1.1網(wǎng)絡(luò)應(yīng)用實(shí)例和來源3.1.2NetBIOS提供的接口與服務(wù)3.1.3網(wǎng)絡(luò)控制塊NCB的應(yīng)用3.2數(shù)據(jù)報(bào)通信編程3.2.1數(shù)據(jù)報(bào)通信應(yīng)用模型3.2.2實(shí)例中的廣播式數(shù)據(jù)報(bào)通信算法與實(shí)現(xiàn)3.2.3實(shí)例中的定向型數(shù)據(jù)報(bào)通信的算法與實(shí)現(xiàn)3.3會(huì)話通信編程3.3.1會(huì)話通信應(yīng)用模型3.3.2實(shí)例中會(huì)話服務(wù)器的算法與實(shí)現(xiàn)3.3.3實(shí)例中會(huì)話客戶算法與實(shí)現(xiàn)本章提綱3.1基于NetBIOS網(wǎng)絡(luò)編程的基礎(chǔ)23.1.1網(wǎng)絡(luò)應(yīng)用實(shí)例和來源VC++實(shí)現(xiàn)的控制臺(tái)程序,位于“第3章代碼”中,其源程序代碼由cnetbios.h和CnetbiosChat.cpp兩部分組成兩個(gè)界面:初始界面和功能操作界面程序使用命令提示符$,界面上可以提供用戶操作的命令有五種:Lookup(了解本地命名和適配器信息)、session(會(huì)話建立與通信)、sendtoname(發(fā)送單播和組播數(shù)據(jù)包)、sendtoall(發(fā)送廣播通信)、exit(退出)鍵入非命令字符串,則提示3.1.1網(wǎng)絡(luò)應(yīng)用實(shí)例和來源VC++實(shí)現(xiàn)的控制臺(tái)程序,位于“3初始界面初始界面4功能操作界面功能操作界面5LookupLookup6session會(huì)話服務(wù)器session會(huì)話服務(wù)器7會(huì)話客戶會(huì)話客戶8sendtonamesendtoname9sendtoallsendtoall103.1.2NetBIOS提供的接口與服務(wù)網(wǎng)絡(luò)基本輸入/輸出系統(tǒng)NetBIOS(NetworkBasicInput/OutputSystem)在支持三個(gè)傳輸協(xié)議(NetBEUI、TCP/IP和IPX/SPX)的基礎(chǔ)上提供了標(biāo)準(zhǔn)接口;應(yīng)用程序通過引用網(wǎng)絡(luò)控制塊NCB(NetworkControlBlock)作為參數(shù)調(diào)用函數(shù):UCHARNetbios(PNCBpNCB);NetBIOS支持的服務(wù):網(wǎng)絡(luò)名字注冊和驗(yàn)證、會(huì)話服務(wù)、無連接的數(shù)據(jù)報(bào)服務(wù)、協(xié)議和適配器的監(jiān)視與管理、支持三種軟件調(diào)用Netbios函數(shù):同步、異步和回調(diào)3.1.2NetBIOS提供的接口與服務(wù)網(wǎng)絡(luò)基本輸入/輸出系11NBF——NetBIOSFrames,NetBEUI(NetBIOSExtendedUserInterface)協(xié)議,IBM和Microsoft為小型局域網(wǎng)建立的不可路由協(xié)議,不適合廣域網(wǎng)。針對TCP/IP也稱NBT(NetBIOSoverTCP/IP)IPX(InternetworkPacketExchange)/SPXSequencesPacketExchange(順序包交換)NovellNetWare操作系統(tǒng)使用的網(wǎng)絡(luò)層協(xié)議,路由協(xié)議沒有IP豐富,設(shè)置簡單。但I(xiàn)PX協(xié)議在以太網(wǎng)上運(yùn)行時(shí)必須指定封裝形式。TDI(TransportDriverInterface)傳輸驅(qū)動(dòng)接口NBF——NetBIOSFrames,NetBEUI(Ne12函數(shù)Netbios(PNCBpNCB)#defineNetbiosInt5c((unsignedchar)0x5C)#defineNetbiosInt2AFunctionCode((unsignedchar)0x2A)voidNetbios(structNCB*NcbPtrNear){UnionREGSInRegs,OutRegs;structNCBfar*NcbPtrFar=(structNCB*far)NcbPtrNear;segread(&SegRegs);SegRegs.es=FP_SEG(NcbPtrFar);SegRegs.x.bx=FP_OFF(NcbPtrFar);Int86x(NetbiosInt5c,&InRegs,&OutRegs,&SegRegs);}函數(shù)Netbios(PNCBpNCB)#defineNe13網(wǎng)絡(luò)名字注冊和驗(yàn)證名字解析系統(tǒng)有LMHOSTS文件和WINS(WindowsInternetNameService)服務(wù)器兩個(gè)選項(xiàng)類型有唯一名,組名,永久節(jié)點(diǎn)名(網(wǎng)卡地址),符號(hào)名。為每個(gè)LANA編號(hào)維護(hù)一個(gè)命名表,名字(最多16個(gè)字節(jié))與一個(gè)字節(jié)的命名編號(hào)(1-254)對應(yīng)LANA編號(hào)描述網(wǎng)卡和傳輸協(xié)議(3個(gè)),例如兩個(gè)網(wǎng)卡以及三種協(xié)議0(TCP/IP,網(wǎng)卡1)、1(NetBEUI,網(wǎng)卡1)、2(IPX/SPX,網(wǎng)卡1)、3(TCP/IP,網(wǎng)卡2)、4(NetBEUI,網(wǎng)卡2)、5(IPX/SPX,網(wǎng)卡2)網(wǎng)絡(luò)名字注冊和驗(yàn)證名字解析系統(tǒng)有LMHOSTS文件和WIN14會(huì)話服務(wù)呼叫功能用于建立一條與被呼叫的應(yīng)用進(jìn)程之間的會(huì)話連接一旦連接建立,就某個(gè)LANA編號(hào)有了一條虛電路用NetBIOS本地會(huì)話號(hào)(1-254,0和255作為系統(tǒng)保留值)來識(shí)別。會(huì)話數(shù)據(jù)發(fā)送和接收都是基于所建立的虛電路,因此除了指定收發(fā)緩沖區(qū)的指針和緩沖區(qū)的長度外,還需要指定的本地會(huì)話號(hào)和LANA編號(hào)。通信結(jié)束釋放已有連接,同時(shí)釋放進(jìn)程占用的內(nèi)存單元,即本地會(huì)話號(hào)對應(yīng)的表。會(huì)話服務(wù)呼叫功能用于建立一條與被呼叫的應(yīng)用進(jìn)程之間的會(huì)話連接15無連接的數(shù)據(jù)報(bào)服務(wù)NetBIOS提供單播、組播和廣播三種數(shù)據(jù)報(bào)傳送功能NetBIOS單播和組播信息發(fā)送都是基于名字,因此單播與組播的區(qū)分取決于接收方的名字是唯一名還是組名,而發(fā)送進(jìn)程則需要指定本地名字編號(hào)和LANA編號(hào)。接收進(jìn)程要區(qū)分單播和組播,名字編號(hào)是關(guān)鍵,如果不區(qū)分,則用通用名字號(hào)(0xff),否則唯一名編號(hào)接收為單播,組名編號(hào)接收為組播。廣播的接收和發(fā)送采用單獨(dú)的命令,不過還是以應(yīng)用進(jìn)程注冊名和LANA編號(hào)為基礎(chǔ)。無連接的數(shù)據(jù)報(bào)服務(wù)NetBIOS提供單播、組播和廣播三種數(shù)據(jù)16同步、異步和回調(diào)同步調(diào)用是一種阻塞的單向調(diào)用方式,調(diào)用方必須一直等待Netbios函數(shù)完成功能返回;異步調(diào)用是一種非阻塞的單向調(diào)用方式,Netbios函數(shù)調(diào)用后立即返回,調(diào)用雙方可以各自繼續(xù)完成自己工作,NetBIOS接口提供事件觸發(fā)以便通知調(diào)用方被調(diào)用方已經(jīng)Netbios函數(shù)完成工作;回調(diào)是一種非阻塞的雙向調(diào)用方法,調(diào)用方設(shè)置Netbios函數(shù)完成工作后的程序地址,以便被調(diào)用方完成工作后執(zhí)行預(yù)先設(shè)置的那個(gè)程序。同步、異步和回調(diào)同步調(diào)用是一種阻塞的單向調(diào)用方式,調(diào)用方必須17回調(diào)函數(shù)示例typedefint(__stdcall*PFunc)(int,int);

int

__stdcall

Max(inta,intb)

{return

a>b?a:b;

}

int__stdcallTest(PFuncfunc,inta,

intb)

{

return

func(a,

b);

}

void

main()

{

cout<<Test(Max,1,30)<<endl;

}

回調(diào)函數(shù)示例typedefint(__stdcall183.1.3網(wǎng)絡(luò)控制塊NCB的應(yīng)用用#include<nb30.h>和#pragmacomment(lib,“netapi32.lib”)(或通過項(xiàng)目菜單)加入頭文件和庫文件所有NetBIOS網(wǎng)絡(luò)功能實(shí)現(xiàn)的關(guān)鍵就是Netbios函數(shù)的調(diào)用,而不同功能實(shí)現(xiàn)的關(guān)鍵是該函數(shù)引用參數(shù)NCB結(jié)構(gòu)各個(gè)域的取值不同同樣的函數(shù)Netbios,同樣的參數(shù)NCB結(jié)構(gòu)指針,要實(shí)現(xiàn)不同的功能,就必須對NCB結(jié)構(gòu)成員初始化。通過對NCB結(jié)構(gòu)成員ncb_command賦值來完成等待(同步)和非等待(回調(diào)和異步)兩種調(diào)用方式中選擇3.1.3網(wǎng)絡(luò)控制塊NCB的應(yīng)用用#include<nb319參數(shù)NCB結(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)(struct_NCB*);UCHARncb_lana_num;UCHARncb_cmd_cplt;UCHARncb_reserve[10];HANDLEncb_event;}NCB,*PNCB參數(shù)NCB結(jié)構(gòu)Typedefstruct_NCB{UC20NCB結(jié)構(gòu)成員初始化舉例UCHARRestNCB(UCHARjiangxue_lana){ NCBjiangxue_ncb; memset(&jiangxue_ncb,0,sizeof(NCB)); jiangxue_ncb.ncb_command=NCBRESET; jiangxue_ncb.ncb_callname[0]=MAXSESSIONS; jiangxue_ncb.ncb_callname[2]=MAXNAMES; jiangxue_ncb.ncb_lana_num=jiangxue_lana; Netbios(&jiangxue_ncb); NBCheck(jiangxue_ncb) return(jiangxue_ncb.ncb_cmd_cplt);}NCB結(jié)構(gòu)成員初始化舉例UCHARRestNCB(UCHA21非等待調(diào)用選擇非等待調(diào)用賦值時(shí)增加|ASYNCH(表示將該字節(jié)的最高位置1),而等待調(diào)用不需要;例如,pncb->ncb_command=NCBDGSEND|ASYNCH表示數(shù)據(jù)報(bào)發(fā)送命令采用非等待調(diào)用方式;異步方式通過NCB結(jié)構(gòu)成員ncb_event指定事件的句柄,讓Netbios函數(shù)完成命令后觸發(fā)一個(gè)事件;回調(diào)方式是將處理程序的地址(回調(diào)函數(shù))通過NCB結(jié)構(gòu)成員ncb_post,讓Netbios函數(shù)命令完成后喚醒該程序;一般回調(diào)函數(shù)定義如下:voidCALLBACK回調(diào)函數(shù)名(PNCB);其中回調(diào)函數(shù)的參數(shù)指向的NCB就是命令執(zhí)行完成后的NCB結(jié)構(gòu)。非等待調(diào)用選擇非等待調(diào)用賦值時(shí)增加|ASYNCH(表示將該字223.2.1數(shù)據(jù)報(bào)通信應(yīng)用模型定向型數(shù)據(jù)報(bào)通信模型3.2.1數(shù)據(jù)報(bào)通信應(yīng)用模型定向型數(shù)據(jù)報(bào)通信模型23廣播式數(shù)據(jù)報(bào)通信模型廣播式數(shù)據(jù)報(bào)通信模型243.2.2實(shí)例中的廣播式數(shù)據(jù)報(bào)通信算法與實(shí)現(xiàn)不論是廣播式數(shù)據(jù)報(bào)通信還是定向型數(shù)據(jù)報(bào),都要獲取可用適配器網(wǎng)絡(luò)編號(hào)并完成通信的初始化。接下來是唯一名LocalName和組名GroupName的注冊,注冊成功后返回相應(yīng)唯一名字號(hào)NameNum和組名字號(hào)GroupNameNum。創(chuàng)建線程DGRecvBCTread用于實(shí)現(xiàn)廣播數(shù)據(jù)報(bào)接收過程。定義了PdataGram結(jié)構(gòu)指針,其結(jié)構(gòu)的成員flag定義了Online,Offline,Listen和Message四種消息類型。3.2.2實(shí)例中的廣播式數(shù)據(jù)報(bào)通信算法與實(shí)現(xiàn)不論是廣播式數(shù)據(jù)25鍵入命令sendtoall后調(diào)用DGsendBCCMD(Elana[0],NameNum)函數(shù)發(fā)送廣播消息。提示進(jìn)程用戶“pleaseinputmessagetobroadcast:”,鍵入發(fā)送的消息,設(shè)置消息標(biāo)志flag為Message,然后調(diào)用函數(shù)DatagramSendBC(lana,NameNum,(char*)pdata,len)發(fā)送鍵入的消息內(nèi)容,其中l(wèi)ana為LANA編號(hào),NameNum為本地名字號(hào)。在退出命令exit的處理中,終止接收線程DGRecvBCTread。然后發(fā)送廣播消息,告訴其他在線應(yīng)用進(jìn)程,本應(yīng)用進(jìn)程下線,并關(guān)閉線程對象,然后調(diào)用函數(shù)DeleteName(注冊的名字,Elana[0])刪除注冊的組名和唯一名。鍵入命令sendtoall后調(diào)用DGsendBCCMD(El263.2.3實(shí)例中的定向型數(shù)據(jù)報(bào)通信的算法與實(shí)現(xiàn)初始化與名字注冊同上一小節(jié)創(chuàng)建接收線程GDGRecvTread和SDGRecvTread接收組播和單播消息第二個(gè)參數(shù)不同,前者為注冊的組名綁定的名字號(hào)GroupNameNum,后者為注冊名綁定的名字號(hào)。前者收到信息后,屏幕提示“Multicastingsender‘sname:組播發(fā)送進(jìn)程注冊名”和“thecontentofmessage:收到的消息內(nèi)容”。在用戶操作命令提示($)下,鍵入命令“sendtoname”回車后,程序提示應(yīng)用進(jìn)程的用戶鍵入接收應(yīng)用進(jìn)程注冊的唯一名或組名3.2.3實(shí)例中的定向型數(shù)據(jù)報(bào)通信的算法與實(shí)現(xiàn)初始化與名字注27屏幕提示“pleaseinputmessagetosendtothename接收進(jìn)程注冊的唯一名或組名:”發(fā)送進(jìn)程的用戶鍵入要發(fā)送的消息回車后,該函數(shù)調(diào)用SDGSend函數(shù)發(fā)送該消息內(nèi)容。SDGSend函數(shù)在cnetbios.h中有定義,并且有5個(gè)參數(shù):可用的LANA編號(hào)lana,接收進(jìn)程注冊的唯一名或組名DestName,發(fā)送進(jìn)程注冊名綁定的名字號(hào)NameNum,要發(fā)送消息緩沖區(qū)的指針(char*)pdata和發(fā)送緩沖區(qū)的長度len。屏幕提示“pleaseinputmessagetos283.3.1會(huì)話通信應(yīng)用模型會(huì)話通信模型3.3.1會(huì)話通信應(yīng)用模型會(huì)話通信模型293.3.2實(shí)例中會(huì)話服務(wù)器的算法與實(shí)現(xiàn)初始化與名字注冊同上一節(jié);鍵入session操作命令后,提示用戶信息“Enterthecharacter*(tolistenasaserver)ortheserver‘sname(toconnectasaclient):”,如果鍵入“*”字符,則該應(yīng)用進(jìn)程作為服務(wù)器該進(jìn)程設(shè)置消息標(biāo)志pdata->flag為Listen,并用函數(shù)DatagramSendBC(Elana[0],NameNum,(char*)pdata,len)發(fā)送廣播消息,通知其他在線進(jìn)程,本進(jìn)程作為服務(wù)器。在while循環(huán)體中,首先服務(wù)器進(jìn)程調(diào)用NetbiosListen(Elana[0],pncb,LocalName)函數(shù)被動(dòng)監(jiān)聽任何客戶進(jìn)程的連接請求。3.3.2實(shí)例中會(huì)話服務(wù)器的算法與實(shí)現(xiàn)初始化與名字注冊同上一30接收一個(gè)客戶進(jìn)程的連接請求后,調(diào)用函數(shù)ServerSession(pncb)處理連接請求,將連接客戶進(jìn)程的注冊名送入DestName中,然后創(chuàng)建會(huì)話數(shù)據(jù)接收線程SessionReceiveThread,同時(shí)指定該線程的調(diào)用參數(shù)(PVOID)pncb。屏幕顯示“本地服務(wù)器進(jìn)程注冊名hasacceptedtheconnectionto遠(yuǎn)端客戶進(jìn)程注冊名!”,然后休息片刻,發(fā)送數(shù)據(jù)“WelcometoServer!”給客戶進(jìn)程,屏幕提示用戶“Whenyousendamessagetotheotherparty,themessage"exit"meansstoppingtosend!”,告訴用戶當(dāng)鍵入消息“exit”時(shí),停止發(fā)送。然后進(jìn)入發(fā)送循環(huán)。接收一個(gè)客戶進(jìn)程的連接請求后,調(diào)用函數(shù)ServerSessi31在for(;;)循環(huán)體中,提示服務(wù)器進(jìn)程用戶“pleaseinputmessagetosendto客戶進(jìn)程注冊名:”鍵入的消息。如果用戶鍵入“exit”,則服務(wù)器進(jìn)程終止會(huì)話數(shù)據(jù)接收線程SessionReceiveThread,關(guān)閉線程句柄對象,斷開連接,然后退出循環(huán);如果不是,則調(diào)用函數(shù)SessionSend(Elana[0],SessionNum,sbuffer,sizeof(sbuffer))發(fā)送數(shù)據(jù),發(fā)送結(jié)束后,并判斷返回retcode,如果不是成功結(jié)束,表示對方已經(jīng)關(guān)閉連接,退出循環(huán)。當(dāng)連接請求處理完畢后,服務(wù)器進(jìn)程提示用戶“Ifyouneedlistentothenext,pleasetypetheletter"y":”,如果用戶鍵入“y”則服務(wù)器進(jìn)程進(jìn)入下一輪循環(huán),否則退出循環(huán),回到用戶操作命令提示狀態(tài)$等待用戶鍵入下一條命令。在for(;;)循環(huán)體中,提示服務(wù)器進(jìn)程用戶“please323.3.3實(shí)例中會(huì)話客戶算法與實(shí)現(xiàn)初始化與名字注冊同上一節(jié);消息“Theserver服務(wù)器進(jìn)程注冊名iswaitingforaclienttoconnect!”顯示告訴用戶有服務(wù)器進(jìn)程等待連接。操作命令提示符$下鍵入操作命令session回車后,用戶進(jìn)程提示信息“Enterthecharacter*(tolistenasaserver)ortheserver‘sname(toconnectasaclient):”,用戶鍵入服務(wù)器注冊名如果連接請求成功,則轉(zhuǎn)入客戶連接處理函數(shù)ClientSession(pncb),否則屏幕提示用戶“Theserver服務(wù)器注冊名isn'tlistening!”表示連接服務(wù)器進(jìn)程失敗。3.3.3實(shí)例中會(huì)話客戶算法與實(shí)現(xiàn)初始化與名字注冊同上一節(jié);33像服務(wù)器處理連接函數(shù)ServerSession一樣創(chuàng)建會(huì)話數(shù)據(jù)接收線程SessionReceiveThread,同時(shí)指定該線程的調(diào)用參數(shù)(PVOID)pncb。屏幕顯示“本地客戶進(jìn)程注冊名hasconnectedtotheserver遠(yuǎn)端服務(wù)器進(jìn)程注冊名!”然后屏幕提示用戶“Whenyousendamessagetotheotherparty,themessage”exit“meansstoppingtosend!”,告訴用戶當(dāng)鍵入消息“exit”時(shí),停止發(fā)送。然后進(jìn)入發(fā)送循環(huán)。在for(;;)循環(huán)體中,收到服務(wù)器進(jìn)程發(fā)來的消息“WelcometoServer!”,并在屏幕上顯示,并提示客戶進(jìn)程用戶“pleaseinputmessagetosendto服務(wù)器進(jìn)程注冊名:”用戶進(jìn)入消息存放在緩沖區(qū)cbuffer內(nèi)。像服務(wù)器處理連接函數(shù)ServerSession一樣創(chuàng)建會(huì)話數(shù)34如果用戶鍵入“exit”,則客戶進(jìn)程終止會(huì)話數(shù)據(jù)接收線程SessionReceiveThread,關(guān)閉線程句柄對象,斷開連接,然后退出循環(huán);如果不是鍵入“exit”,則調(diào)用函數(shù)SessionSend(Elana[0],SessionNum,sbuffer,sizeof(sbuffer))發(fā)送緩沖區(qū)sbuffer的數(shù)據(jù),發(fā)送結(jié)束后,并判斷返回retcode,如果不是成功結(jié)束,則表示對方已經(jīng)關(guān)閉連接,則退出循環(huán)。發(fā)送成功結(jié)束后,提示客戶進(jìn)程用戶“pleaseinputmessagetosendto服務(wù)器進(jìn)程注冊名:”進(jìn)入下一輪循環(huán),以便用戶鍵入消息。如果用戶鍵入“exit”,則客戶進(jìn)程終止會(huì)話數(shù)據(jù)接收線程Se35Windows網(wǎng)絡(luò)編程技術(shù)

第3章基于NetBIOS的網(wǎng)絡(luò)編程授課老師:胡鳴數(shù)學(xué)與計(jì)算機(jī)學(xué)院計(jì)算機(jī)系Windows網(wǎng)絡(luò)編程技術(shù)

第3章基于NetBIOS的網(wǎng)絡(luò)編36本章提綱3.1基于NetBIOS網(wǎng)絡(luò)編程的基礎(chǔ)3.1.1網(wǎng)絡(luò)應(yīng)用實(shí)例和來源3.1.2NetBIOS提供的接口與服務(wù)3.1.3網(wǎng)絡(luò)控制塊NCB的應(yīng)用3.2數(shù)據(jù)報(bào)通信編程3.2.1數(shù)據(jù)報(bào)通信應(yīng)用模型3.2.2實(shí)例中的廣播式數(shù)據(jù)報(bào)通信算法與實(shí)現(xiàn)3.2.3實(shí)例中的定向型數(shù)據(jù)報(bào)通信的算法與實(shí)現(xiàn)3.3會(huì)話通信編程3.3.1會(huì)話通信應(yīng)用模型3.3.2實(shí)例中會(huì)話服務(wù)器的算法與實(shí)現(xiàn)3.3.3實(shí)例中會(huì)話客戶算法與實(shí)現(xiàn)本章提綱3.1基于NetBIOS網(wǎng)絡(luò)編程的基礎(chǔ)373.1.1網(wǎng)絡(luò)應(yīng)用實(shí)例和來源VC++實(shí)現(xiàn)的控制臺(tái)程序,位于“第3章代碼”中,其源程序代碼由cnetbios.h和CnetbiosChat.cpp兩部分組成兩個(gè)界面:初始界面和功能操作界面程序使用命令提示符$,界面上可以提供用戶操作的命令有五種:Lookup(了解本地命名和適配器信息)、session(會(huì)話建立與通信)、sendtoname(發(fā)送單播和組播數(shù)據(jù)包)、sendtoall(發(fā)送廣播通信)、exit(退出)鍵入非命令字符串,則提示3.1.1網(wǎng)絡(luò)應(yīng)用實(shí)例和來源VC++實(shí)現(xiàn)的控制臺(tái)程序,位于“38初始界面初始界面39功能操作界面功能操作界面40LookupLookup41session會(huì)話服務(wù)器session會(huì)話服務(wù)器42會(huì)話客戶會(huì)話客戶43sendtonamesendtoname44sendtoallsendtoall453.1.2NetBIOS提供的接口與服務(wù)網(wǎng)絡(luò)基本輸入/輸出系統(tǒng)NetBIOS(NetworkBasicInput/OutputSystem)在支持三個(gè)傳輸協(xié)議(NetBEUI、TCP/IP和IPX/SPX)的基礎(chǔ)上提供了標(biāo)準(zhǔn)接口;應(yīng)用程序通過引用網(wǎng)絡(luò)控制塊NCB(NetworkControlBlock)作為參數(shù)調(diào)用函數(shù):UCHARNetbios(PNCBpNCB);NetBIOS支持的服務(wù):網(wǎng)絡(luò)名字注冊和驗(yàn)證、會(huì)話服務(wù)、無連接的數(shù)據(jù)報(bào)服務(wù)、協(xié)議和適配器的監(jiān)視與管理、支持三種軟件調(diào)用Netbios函數(shù):同步、異步和回調(diào)3.1.2NetBIOS提供的接口與服務(wù)網(wǎng)絡(luò)基本輸入/輸出系46NBF——NetBIOSFrames,NetBEUI(NetBIOSExtendedUserInterface)協(xié)議,IBM和Microsoft為小型局域網(wǎng)建立的不可路由協(xié)議,不適合廣域網(wǎng)。針對TCP/IP也稱NBT(NetBIOSoverTCP/IP)IPX(InternetworkPacketExchange)/SPXSequencesPacketExchange(順序包交換)NovellNetWare操作系統(tǒng)使用的網(wǎng)絡(luò)層協(xié)議,路由協(xié)議沒有IP豐富,設(shè)置簡單。但I(xiàn)PX協(xié)議在以太網(wǎng)上運(yùn)行時(shí)必須指定封裝形式。TDI(TransportDriverInterface)傳輸驅(qū)動(dòng)接口NBF——NetBIOSFrames,NetBEUI(Ne47函數(shù)Netbios(PNCBpNCB)#defineNetbiosInt5c((unsignedchar)0x5C)#defineNetbiosInt2AFunctionCode((unsignedchar)0x2A)voidNetbios(structNCB*NcbPtrNear){UnionREGSInRegs,OutRegs;structNCBfar*NcbPtrFar=(structNCB*far)NcbPtrNear;segread(&SegRegs);SegRegs.es=FP_SEG(NcbPtrFar);SegRegs.x.bx=FP_OFF(NcbPtrFar);Int86x(NetbiosInt5c,&InRegs,&OutRegs,&SegRegs);}函數(shù)Netbios(PNCBpNCB)#defineNe48網(wǎng)絡(luò)名字注冊和驗(yàn)證名字解析系統(tǒng)有LMHOSTS文件和WINS(WindowsInternetNameService)服務(wù)器兩個(gè)選項(xiàng)類型有唯一名,組名,永久節(jié)點(diǎn)名(網(wǎng)卡地址),符號(hào)名。為每個(gè)LANA編號(hào)維護(hù)一個(gè)命名表,名字(最多16個(gè)字節(jié))與一個(gè)字節(jié)的命名編號(hào)(1-254)對應(yīng)LANA編號(hào)描述網(wǎng)卡和傳輸協(xié)議(3個(gè)),例如兩個(gè)網(wǎng)卡以及三種協(xié)議0(TCP/IP,網(wǎng)卡1)、1(NetBEUI,網(wǎng)卡1)、2(IPX/SPX,網(wǎng)卡1)、3(TCP/IP,網(wǎng)卡2)、4(NetBEUI,網(wǎng)卡2)、5(IPX/SPX,網(wǎng)卡2)網(wǎng)絡(luò)名字注冊和驗(yàn)證名字解析系統(tǒng)有LMHOSTS文件和WIN49會(huì)話服務(wù)呼叫功能用于建立一條與被呼叫的應(yīng)用進(jìn)程之間的會(huì)話連接一旦連接建立,就某個(gè)LANA編號(hào)有了一條虛電路用NetBIOS本地會(huì)話號(hào)(1-254,0和255作為系統(tǒng)保留值)來識(shí)別。會(huì)話數(shù)據(jù)發(fā)送和接收都是基于所建立的虛電路,因此除了指定收發(fā)緩沖區(qū)的指針和緩沖區(qū)的長度外,還需要指定的本地會(huì)話號(hào)和LANA編號(hào)。通信結(jié)束釋放已有連接,同時(shí)釋放進(jìn)程占用的內(nèi)存單元,即本地會(huì)話號(hào)對應(yīng)的表。會(huì)話服務(wù)呼叫功能用于建立一條與被呼叫的應(yīng)用進(jìn)程之間的會(huì)話連接50無連接的數(shù)據(jù)報(bào)服務(wù)NetBIOS提供單播、組播和廣播三種數(shù)據(jù)報(bào)傳送功能NetBIOS單播和組播信息發(fā)送都是基于名字,因此單播與組播的區(qū)分取決于接收方的名字是唯一名還是組名,而發(fā)送進(jìn)程則需要指定本地名字編號(hào)和LANA編號(hào)。接收進(jìn)程要區(qū)分單播和組播,名字編號(hào)是關(guān)鍵,如果不區(qū)分,則用通用名字號(hào)(0xff),否則唯一名編號(hào)接收為單播,組名編號(hào)接收為組播。廣播的接收和發(fā)送采用單獨(dú)的命令,不過還是以應(yīng)用進(jìn)程注冊名和LANA編號(hào)為基礎(chǔ)。無連接的數(shù)據(jù)報(bào)服務(wù)NetBIOS提供單播、組播和廣播三種數(shù)據(jù)51同步、異步和回調(diào)同步調(diào)用是一種阻塞的單向調(diào)用方式,調(diào)用方必須一直等待Netbios函數(shù)完成功能返回;異步調(diào)用是一種非阻塞的單向調(diào)用方式,Netbios函數(shù)調(diào)用后立即返回,調(diào)用雙方可以各自繼續(xù)完成自己工作,NetBIOS接口提供事件觸發(fā)以便通知調(diào)用方被調(diào)用方已經(jīng)Netbios函數(shù)完成工作;回調(diào)是一種非阻塞的雙向調(diào)用方法,調(diào)用方設(shè)置Netbios函數(shù)完成工作后的程序地址,以便被調(diào)用方完成工作后執(zhí)行預(yù)先設(shè)置的那個(gè)程序。同步、異步和回調(diào)同步調(diào)用是一種阻塞的單向調(diào)用方式,調(diào)用方必須52回調(diào)函數(shù)示例typedefint(__stdcall*PFunc)(int,int);

int

__stdcall

Max(inta,intb)

{return

a>b?a:b;

}

int__stdcallTest(PFuncfunc,inta,

intb)

{

return

func(a,

b);

}

void

main()

{

cout<<Test(Max,1,30)<<endl;

}

回調(diào)函數(shù)示例typedefint(__stdcall533.1.3網(wǎng)絡(luò)控制塊NCB的應(yīng)用用#include<nb30.h>和#pragmacomment(lib,“netapi32.lib”)(或通過項(xiàng)目菜單)加入頭文件和庫文件所有NetBIOS網(wǎng)絡(luò)功能實(shí)現(xiàn)的關(guān)鍵就是Netbios函數(shù)的調(diào)用,而不同功能實(shí)現(xiàn)的關(guān)鍵是該函數(shù)引用參數(shù)NCB結(jié)構(gòu)各個(gè)域的取值不同同樣的函數(shù)Netbios,同樣的參數(shù)NCB結(jié)構(gòu)指針,要實(shí)現(xiàn)不同的功能,就必須對NCB結(jié)構(gòu)成員初始化。通過對NCB結(jié)構(gòu)成員ncb_command賦值來完成等待(同步)和非等待(回調(diào)和異步)兩種調(diào)用方式中選擇3.1.3網(wǎng)絡(luò)控制塊NCB的應(yīng)用用#include<nb354參數(shù)NCB結(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)(struct_NCB*);UCHARncb_lana_num;UCHARncb_cmd_cplt;UCHARncb_reserve[10];HANDLEncb_event;}NCB,*PNCB參數(shù)NCB結(jié)構(gòu)Typedefstruct_NCB{UC55NCB結(jié)構(gòu)成員初始化舉例UCHARRestNCB(UCHARjiangxue_lana){ NCBjiangxue_ncb; memset(&jiangxue_ncb,0,sizeof(NCB)); jiangxue_ncb.ncb_command=NCBRESET; jiangxue_ncb.ncb_callname[0]=MAXSESSIONS; jiangxue_ncb.ncb_callname[2]=MAXNAMES; jiangxue_ncb.ncb_lana_num=jiangxue_lana; Netbios(&jiangxue_ncb); NBCheck(jiangxue_ncb) return(jiangxue_ncb.ncb_cmd_cplt);}NCB結(jié)構(gòu)成員初始化舉例UCHARRestNCB(UCHA56非等待調(diào)用選擇非等待調(diào)用賦值時(shí)增加|ASYNCH(表示將該字節(jié)的最高位置1),而等待調(diào)用不需要;例如,pncb->ncb_command=NCBDGSEND|ASYNCH表示數(shù)據(jù)報(bào)發(fā)送命令采用非等待調(diào)用方式;異步方式通過NCB結(jié)構(gòu)成員ncb_event指定事件的句柄,讓Netbios函數(shù)完成命令后觸發(fā)一個(gè)事件;回調(diào)方式是將處理程序的地址(回調(diào)函數(shù))通過NCB結(jié)構(gòu)成員ncb_post,讓Netbios函數(shù)命令完成后喚醒該程序;一般回調(diào)函數(shù)定義如下:voidCALLBACK回調(diào)函數(shù)名(PNCB);其中回調(diào)函數(shù)的參數(shù)指向的NCB就是命令執(zhí)行完成后的NCB結(jié)構(gòu)。非等待調(diào)用選擇非等待調(diào)用賦值時(shí)增加|ASYNCH(表示將該字573.2.1數(shù)據(jù)報(bào)通信應(yīng)用模型定向型數(shù)據(jù)報(bào)通信模型3.2.1數(shù)據(jù)報(bào)通信應(yīng)用模型定向型數(shù)據(jù)報(bào)通信模型58廣播式數(shù)據(jù)報(bào)通信模型廣播式數(shù)據(jù)報(bào)通信模型593.2.2實(shí)例中的廣播式數(shù)據(jù)報(bào)通信算法與實(shí)現(xiàn)不論是廣播式數(shù)據(jù)報(bào)通信還是定向型數(shù)據(jù)報(bào),都要獲取可用適配器網(wǎng)絡(luò)編號(hào)并完成通信的初始化。接下來是唯一名LocalName和組名GroupName的注冊,注冊成功后返回相應(yīng)唯一名字號(hào)NameNum和組名字號(hào)GroupNameNum。創(chuàng)建線程DGRecvBCTread用于實(shí)現(xiàn)廣播數(shù)據(jù)報(bào)接收過程。定義了PdataGram結(jié)構(gòu)指針,其結(jié)構(gòu)的成員flag定義了Online,Offline,Listen和Message四種消息類型。3.2.2實(shí)例中的廣播式數(shù)據(jù)報(bào)通信算法與實(shí)現(xiàn)不論是廣播式數(shù)據(jù)60鍵入命令sendtoall后調(diào)用DGsendBCCMD(Elana[0],NameNum)函數(shù)發(fā)送廣播消息。提示進(jìn)程用戶“pleaseinputmessagetobroadcast:”,鍵入發(fā)送的消息,設(shè)置消息標(biāo)志flag為Message,然后調(diào)用函數(shù)DatagramSendBC(lana,NameNum,(char*)pdata,len)發(fā)送鍵入的消息內(nèi)容,其中l(wèi)ana為LANA編號(hào),NameNum為本地名字號(hào)。在退出命令exit的處理中,終止接收線程DGRecvBCTread。然后發(fā)送廣播消息,告訴其他在線應(yīng)用進(jìn)程,本應(yīng)用進(jìn)程下線,并關(guān)閉線程對象,然后調(diào)用函數(shù)DeleteName(注冊的名字,Elana[0])刪除注冊的組名和唯一名。鍵入命令sendtoall后調(diào)用DGsendBCCMD(El613.2.3實(shí)例中的定向型數(shù)據(jù)報(bào)通信的算法與實(shí)現(xiàn)初始化與名字注冊同上一小節(jié)創(chuàng)建接收線程GDGRecvTread和SDGRecvTread接收組播和單播消息第二個(gè)參數(shù)不同,前者為注冊的組名綁定的名字號(hào)GroupNameNum,后者為注冊名綁定的名字號(hào)。前者收到信息后,屏幕提示“Multicastingsender‘sname:組播發(fā)送進(jìn)程注冊名”和“thecontentofmessage:收到的消息內(nèi)容”。在用戶操作命令提示($)下,鍵入命令“sendtoname”回車后,程序提示應(yīng)用進(jìn)程的用戶鍵入接收應(yīng)用進(jìn)程注冊的唯一名或組名3.2.3實(shí)例中的定向型數(shù)據(jù)報(bào)通信的算法與實(shí)現(xiàn)初始化與名字注62屏幕提示“pleaseinputmessagetosendtothename接收進(jìn)程注冊的唯一名或組名:”發(fā)送進(jìn)程的用戶鍵入要發(fā)送的消息回車后,該函數(shù)調(diào)用SDGSend函數(shù)發(fā)送該消息內(nèi)容。SDGSend函數(shù)在cnetbios.h中有定義,并且有5個(gè)參數(shù):可用的LANA編號(hào)lana,接收進(jìn)程注冊的唯一名或組名DestName,發(fā)送進(jìn)程注冊名綁定的名字號(hào)NameNum,要發(fā)送消息緩沖區(qū)的指針(char*)pdata和發(fā)送緩沖區(qū)的長度len。屏幕提示“pleaseinputmessagetos633.3.1會(huì)話通信應(yīng)用模型會(huì)話通信模型3.3.1會(huì)話通信應(yīng)用模型會(huì)話通信模型643.3.2實(shí)例中會(huì)話服務(wù)器的算法與實(shí)現(xiàn)初始化與名字注冊同上一節(jié);鍵入session操作命令后,提示用戶信息“Enterthecharacter*(tolistenasaserver)ortheserver‘sname(toconnectasaclient):”,如果鍵入“*”字符,則該應(yīng)用進(jìn)程作為服務(wù)器該進(jìn)程設(shè)置消息標(biāo)志pdata->flag為Listen,并用函數(shù)DatagramSendBC(Elana[0],NameNum,(char*)pdata,len)發(fā)送廣播消息,通知其他在線進(jìn)程,本進(jìn)程作為服務(wù)器。在while循環(huán)體中,首先服務(wù)器進(jìn)程調(diào)用NetbiosListen(Elana[0],pncb,LocalName)函數(shù)被動(dòng)監(jiān)聽任何客戶進(jìn)程的連接請求。3.3.2實(shí)例中會(huì)話服務(wù)器的算法與實(shí)現(xiàn)初始化與名字注冊同上一65接收一個(gè)客戶進(jìn)程的連接請求后,調(diào)用函數(shù)ServerSession(pncb)處理連接請求,將連接客戶進(jìn)程的注冊名送入DestName中,然后創(chuàng)建會(huì)話數(shù)據(jù)接收線程SessionReceiveThread,同時(shí)指定該線程的調(diào)用參數(shù)(PVOID)pncb。屏幕顯示“本地服務(wù)器進(jìn)程注冊名hasacceptedtheconnectionto遠(yuǎn)端客戶進(jìn)程注冊名!”,然后休息片刻,發(fā)送數(shù)據(jù)“WelcometoServer!”

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論