版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第4章MFC套接字編程楊明紫金學院計算機系數(shù)據(jù)結(jié)構(gòu)2/3/2023內(nèi)容MFC編程框架CAsyncSocket類編程CSocket類編程MFC編程MFC概述MFC類庫是C++類庫,構(gòu)成了MFC編程框架。這些類分別封裝了Win32應(yīng)用程序編程接口、應(yīng)用程序的概念、OLE特性、以及ODBC和DAO數(shù)據(jù)訪問的功能。MFC類具有繼承關(guān)系,有虛擬函數(shù)和動態(tài)約束,并提供了MFC的開發(fā)模板。MFC框架從總體上定義了應(yīng)用程序的輪廓,并提供了用戶接口的標準實現(xiàn)方法,程序員只須通過預定義的接口把具體應(yīng)用程序特有的東西填入這個輪廓,就能建立Windows下的應(yīng)用程序。典型的MFC應(yīng)用程序的構(gòu)成MFC對象間的交互作用關(guān)系MFC消息處理消息映射就是讓程序員指定用來處理某個消息的某個MFC類使用MFC提供的ClassWizard類向?qū)?,可以在處理消息的類中添加處理消息的成員函數(shù),方便地實現(xiàn)消息映射。在此基礎(chǔ)上,程序員可將自己的代碼添加到這些消息處理函數(shù)中,實現(xiàn)所希望的消息處理。如果派生類要覆蓋基類的消息處理函數(shù),就用ClassWizard在派生類中添加一個消息映射條目,用同樣的原型定義一個函數(shù),然后實現(xiàn)該函數(shù)。MFC的消息與映射處理Windows消息以前綴“WM_”打頭的消息,Windows消息直接被送給MFC的窗口過程處理,窗口過程再調(diào)用對應(yīng)的消息處理函數(shù)??刂仆ㄖ?,是控制子窗口送給父窗口的通知消息。窗口過程調(diào)用對應(yīng)的消息處理函數(shù)。命令消息,這是來自菜單、工具條按鈕、加速鍵等用戶接口對象的WM_COMMAND通知消息,屬于應(yīng)用程序自己定義的消息。MFC消息映射的實現(xiàn)方法程序員可以使用MFC的類向?qū)lassWizard來實現(xiàn)消息映射。類向?qū)г谠创a中添加一些消息映射的內(nèi)容,并聲明和實現(xiàn)消息處理函數(shù)。MFC類的構(gòu)成8基于CCmdTarget和CWnd派生的MFC類9MFC編程框架10MFCWinSock類的編程MFCWinSock類為簡化套接字網(wǎng)絡(luò)編程,更方便地利用Windows的消息驅(qū)動機制,微軟的基礎(chǔ)類庫MFC,提供了兩個套接字類,在不同的層次上對WindowsSocketAPI函數(shù)進行了封裝,提供了兩種編程模式。CAsyncSocket類和CSocket類CAsyncSocket類特點在很低的層次上對WindowsSocketsAPI進行了封裝它的成員函數(shù)和WindowsSocketsAPI的函數(shù)調(diào)用直接對應(yīng)。一個CAsyncSocket對象代表了一個Windows套接字。它是網(wǎng)絡(luò)通信的端點。除了把套接字封裝成C++的面向?qū)ο蟮男问焦┏绦騿T使用以外,這個類唯一所增加的抽象就是將那些與套接字相關(guān)的Windows消息變?yōu)镃AsyncSocket類的回調(diào)函數(shù)。CSocket類特點從CAsyncSocket類派生,是對WindowsSocketsAPI的高級封裝。CSocket類繼承了CAsyncSocket類的許多成員函數(shù),用法一致。CSocket類的高級表現(xiàn)在三個方面:(1)CSocket結(jié)合archive類來使用套接字。(2)CSocket管理了通信的許多方面,如字節(jié)順序問題和字符串轉(zhuǎn)換問題。(3)CSocket類為Windows消息的后臺處理提供了阻塞的工作模式。CAsyncSocket類的定義14CAsyncSocket類的定義15六種套接字相關(guān)的事件與通知消息當事件發(fā)生時,套接字對象會收到相應(yīng)的通知消息,并自動執(zhí)行套接字對象響應(yīng)的事件處理函數(shù)。FD_READ事件通知:通知有數(shù)據(jù)可讀。FD_WRITE事件通知:通知可以寫數(shù)據(jù)。FD_ACCEPT事件通知:通知監(jiān)聽套接字有連接請求可以接受。FD_CONNECT事件通知:通知請求連接的套接字,連接的要求已被處理。FD_CLOSE事件通知:通知套接字已關(guān)閉。FD_OOB事件通知:通知將有帶外數(shù)據(jù)到達。CAsyncSocket類的定義17套接字類的通知函數(shù)CAsyncSocket類這六個網(wǎng)絡(luò)事件對應(yīng)的事件處理函數(shù)virtualvoidOnReceive(intnErrorCode);對應(yīng)FD_READ事件virtualvoidOnSend(intnErrorCode);對應(yīng)FD_WRITE事件virtualvoidOnAccept(intnErrorCode);對應(yīng)FD_ACCEPT事件virtualvoidOnConnect(intnErrorCode);對應(yīng)FD_CONNECT事件virtualvoidOnClose(intnErrorCode);對應(yīng)FD_CLOSE事件virtualvoidOnOutOfBandData(intnErrorCode);對應(yīng)FD_OOB事件重載套接字對象的回調(diào)函數(shù) MFC框架自動調(diào)用通知函數(shù),使得你可以在套接字被通知的時候來優(yōu)化套接字的行為。創(chuàng)建CasyncSocket類對象定義異步套接字對象變量如:CAsyncSocketaa; aa.Create(。。。。。。);如:CAsyncSocket*Pa; Pa->Create(。。。。。。);
創(chuàng)建CasyncSocket類對象創(chuàng)建異步套接字對象的底層套接字句柄格式:BOOLCreate(UINTnSocketPort=0, IntnSocketType=SOCK_STREAM, LongIevent=FD_READ|FD_WRITE|FD_OOB| FD_ACCEPT|FD_CONNECT|FD_CLOSE, LPCTSTRlpszSocketAddress=NULL);例:CAsyncSocket*pSocket=newCAsyncSocket;intnPort=27;pSocket->Create(nPort,SOCK_STREAM);客戶端套接字對象請求連接客戶端套接字對象請求連接到服務(wù)器端套接字對象在服務(wù)器端套接字對象已經(jīng)進入監(jiān)聽狀態(tài)之后,客戶應(yīng)用程序可以調(diào)用CAsyncSocket類的Connect()成員函數(shù),向服務(wù)器發(fā)出一個連接請求,格式一:BOOLConnect(LPCTSTRlpszHostAddress,UINTnHostPort);格式二:BOOLConnect(constSOCKADDR*lpSockAddr,intnSockAddrLen);當調(diào)用結(jié)束返回時,都會發(fā)生FD_CONNECT事件接受連接請求服務(wù)器接受客戶機的連接請求服務(wù)器應(yīng)用程序必須首先創(chuàng)建一個監(jiān)聽套接字對象,專門用來監(jiān)聽來自客戶機的連接請求。調(diào)用監(jiān)聽套接字對象的Listen成員函數(shù),BOOLListen(intnConnectionBacklog=5);當Listen函數(shù)確認并接納了一個來自客戶端的連接請求后,會觸發(fā)FD_ACCEPT事件創(chuàng)建一個新的連接套接字,這個套接字專門用來與客戶端連接,并進行數(shù)據(jù)的傳輸。調(diào)用監(jiān)聽套接字對象的Accept成員函數(shù),調(diào)用格式為:virtualBOOLAccept(CAsyncSocket&rConnectedSocket,SOCKADDR*lpSockAddr=NULL,int*lpSockAddrLen=NULL);發(fā)送與接收流式數(shù)據(jù)用Send成員函數(shù)發(fā)送數(shù)據(jù)格式:virtualintSend(constvoid*lpBuf,intnBufLen,intnFlags=0);對于一個CAsyncSocket套接字對象,當它的發(fā)送緩沖區(qū)騰空時,會激發(fā)FD_WRITE事件。用Receive成員函數(shù)接收數(shù)據(jù)格式:VirtualintReceive(Void*lpBuf,IntnBufLen,IntnFlags=0);對于一個CAsyncSocket套接字對象,當有數(shù)據(jù)到達它的接收隊列時,會激發(fā)FD_READ事件,套接字會得到已經(jīng)有數(shù)據(jù)到達的通知,MFC框架會自動調(diào)用這個套接字對象的OnReceive事件處理函數(shù)。在應(yīng)用程序?qū)?shù)據(jù)取走之前,套接字接收的數(shù)據(jù)將一直保留在套接字的緩沖區(qū)中。CAsyncSocket類編程步驟24步驟服務(wù)器客戶機1//創(chuàng)建服務(wù)器偵聽套接字對象CAsyncSocketsockListen;//創(chuàng)建客戶機套接字對象CAsyncSocketsockClient;2//創(chuàng)建SOCKET句柄,綁定到指定端口sockListen.Create(nPort);//創(chuàng)建SOCKET句柄,自動選擇本地可用端口sockClient.Create();3//啟動監(jiān)聽,時刻準備接受客戶連接請求sockListen.Listen();
4
//請求連接到服務(wù)器sockClient.Connect(strAddr,nPort);5//創(chuàng)建一個新的服務(wù)器套接字對象CAsyncSocketsockServer;//接受新連接sockListen.Accept(sockServer);
6//接收數(shù)據(jù)sockServer.Receive(pBuf,nLen);或//發(fā)送數(shù)據(jù)sockServer.Send(pBuf,nLen);或兩者//發(fā)送數(shù)據(jù)sockClient.Send(pBuf,nLen);或/接收數(shù)據(jù)sockClient.Receive(pBuf,nLen);或兩者7//禁用服務(wù)器套接字某些操作sockServer.ShutDown();//禁用客戶機套接字某些操作sockClient.ShutDown();8//關(guān)閉服務(wù)器套接字sockServer.Close();//關(guān)閉客戶機套接字sockClient.Close();9//關(guān)閉服務(wù)器偵聽套接字sockListen.Close();
CAsyncSocket類的應(yīng)用實例實現(xiàn)目標應(yīng)用實例是一個簡單的聊天室程序,采用客戶/服務(wù)器模式,分為客戶端程序和服務(wù)器端程序。由于服務(wù)器只能支持一個客戶,實際是一個點對點通信的程序??蛻舳顺绦蚝头?wù)器程序通過網(wǎng)絡(luò)交換聊天的字符串內(nèi)容,并在窗口的列表框中顯示。創(chuàng)建客戶端應(yīng)用程序使用MFCAppWizard創(chuàng)建客戶端應(yīng)用程序框架使用MFCAppWizard設(shè)置創(chuàng)建的骨架工程的有關(guān)信息為對話框界面添加控件對象設(shè)計對話框通過resourceView設(shè)計并構(gòu)建對話框修改對話框中的控件屬性對話框設(shè)置控件類型控件IDCaption靜態(tài)文本statictextIDC_STATIC_SERVNAME服務(wù)器名稱靜態(tài)文本statictextIDC_STATIC_SERVPORT服務(wù)器端口靜態(tài)文本statictextIDC_STATIC_MSG消
息靜態(tài)文本statictextIDC_STATIC_SENT發(fā)送的消息靜態(tài)文本statictextIDC_STATIC_RECEIVED接收的消息編輯框editboxIDC_EDIT_SERVNAME
編輯框editboxIDC_EDIT_SERVPORT
編輯框editboxIDC_EDIT_MSG
命令按鈕buttonIDC_BUTTON_CONNECT連接命令按鈕buttonIDC_BUTTON_CLOSE斷開命令按鈕buttonIDOK發(fā)送列表框listboxIDC_LIST_SENT
列表框listboxIDC_LIST_RECEIVED
為對話框中的控件對象定義相應(yīng)的成員變量對話框中的控件對象對應(yīng)的成員變量
控件IDControlIDs變量名稱MemberVariableName變量類別Category變量類型VariableTypeIDC_BUTTON_CONNECTm_btnConnectControlCButtonIDC_EDIT_SERVNAMEm_strServNameValueCStringIDC_EDIT_SERVPORTm_strServPortValueintIDC_EDIT_MSGm_strMsgValueCStringIDC_LIST_SENTm_listSentControlCListBoxIDC_LIST_RECEIVEDm_listRecetvedControlCListBox
創(chuàng)建從CAsyncSocket類繼承的派生類為了能夠捕獲并響應(yīng)socket事件,應(yīng)創(chuàng)建用戶自己的套接字類。從CAsyncSocket類派生,將套接字事件傳遞給對話框,以便執(zhí)行用戶自己的事件處理函數(shù)。為套接字類添加響應(yīng)消息的事件處理成員函數(shù)為套接字類添加一般的成員函數(shù)和成員變量對這個套接字類,添加一個私有的成員變量,是一個對話框類的指針。private:CTalkcDlg*m_pDlg;為套接字類添加一般的成員變量為套接字類添加成員函數(shù)再添加一個成員函數(shù):voidSetParent(CTalkcDlg*pDlg);客戶端程序的類與消息驅(qū)動客戶端程序主要代碼說明1.應(yīng)用程序類CTalkcApp對應(yīng)的文件應(yīng)用程序類CTalkcApp,對應(yīng)的文件是talkc.h和talkc.cpp;talkc.h定義了CTalkcApp類,talkc.cpp是該類的實現(xiàn)代碼,完全由VC++自動創(chuàng)建,用戶不必作任何改動。
2.派生的套接字類CMySocket對應(yīng)的文件CMySocket類對應(yīng)MySocket.h頭文件和MySocket.CPP文件3.對話框類CTalkcDlg對應(yīng)的文件對話框類CTalkcDlg,對應(yīng)的文件是talkcDlg.h和talkcDlg.cpp。4.其他文件對于VC++為talkc工程創(chuàng)建的其他文件,如stdafx.h和stdafx.cpp,以及Resource.h和talkc.rc都不需要作任何處理。創(chuàng)建服務(wù)器端程序1.使用MFCAppWizard創(chuàng)建服務(wù)器端應(yīng)用程序框架2.為對話框界面添加控件對象3.為對話框中的控件對象定義相應(yīng)的成員變量4.創(chuàng)建從CAsyncSocket類繼承的派生類5.為對話框類添加控件對象事件的響應(yīng)函數(shù)6.為CTalksDlg對話框類添加其它成員函數(shù)和成員變量7.手工添加的代碼8.添加事件函數(shù)和成員函數(shù)的代碼9.進行測試。
服務(wù)器端程序的流程和消息驅(qū)動創(chuàng)建服務(wù)器1.使用MFC應(yīng)用程序向?qū)?chuàng)建服務(wù)器程序框架43創(chuàng)建服務(wù)器2.為服務(wù)器對話框添加控件,構(gòu)建程序主界面44創(chuàng)建服務(wù)器3.為對話框中的控件對象定義相應(yīng)的成員變量4.創(chuàng)建從CAsyncSocket類派生的子類CServerSocket,處理與客戶機的通信5.為對話框類CServerDlg中的三個按鈕控件添加單擊事件處理函數(shù)6.為CServerDlg類添加與套接字關(guān)聯(lián)的成員變量和成員函數(shù)7.手工添加部分代碼8.添加事件函數(shù)和成員函數(shù)業(yè)務(wù)邏輯代碼45服務(wù)器代碼分析同客戶機一樣,應(yīng)用程序Server.h和Server.cpp對應(yīng)CServerApp類的定義和實現(xiàn),完全由VC++2010的MFC向?qū)ё詣觿?chuàng)建,是整個項目的入口文件,編程者不需做任何改動。Resource.h、stdafx.h、stdafx.cpp、targetver.h等由系統(tǒng)自動生成,不需改動。教材重點給出ServerSocket.h、ServerSocket.cpp、ServerDlg.h和ServerDlg.cpp這四個文件的編碼清單。46服務(wù)器代碼分析服務(wù)器運行初始界面47客戶機服務(wù)器聯(lián)合測試客戶機與服務(wù)器交流界面截圖48CSOCKET類編程模型CSocket類的高級特性CSocket結(jié)合archive類來使用套接字。CSocket管理了通信的許多方面,如字節(jié)順序問題和字符串轉(zhuǎn)換問題。CSocket類為Windows消息的后臺處理提供了阻塞的工作模式CSOCKET類編程模型CArchive、CSocketFile和CSocket協(xié)同工作模型50創(chuàng)建CSocket對象創(chuàng)建步驟(1)調(diào)用CSocket類的構(gòu)造函數(shù),創(chuàng)建一個空的CSocket對象。(2)調(diào)用此CSocket對象的Create()成員函數(shù),創(chuàng)建對象的底層套接字。調(diào)用格式是:BOOLCreate(UINTnSocketPort=端口號,
IntnSocketPort=SOCK_STREAM|SOCK_DGRAM, LPCTSTRlpszSocketAddress=套接字所用網(wǎng)絡(luò)地址);如果打算使用CArchive對象和套接字一起進行數(shù)據(jù)傳輸工作,必須使用流式套接字。建立連接相同的方法CSocket類使用基類CAsyncSocket的同名成員函數(shù)Connect()、Listen()、Accept()來建立服務(wù)器和客戶機套接字之間的連接,使用方法相同。不同的是CSocket類的Connect()和Accept()支持阻塞調(diào)用。比如:在調(diào)用Connect()函數(shù)時會發(fā)生阻塞,直到成功地建立了連接或有錯誤發(fā)生才返回,在多線程的應(yīng)用程序中,一個線程發(fā)生阻塞,其他的線程仍能處理Windows事件。CSocket對象從不調(diào)用OnConnect()事件處理函數(shù)發(fā)送和接收數(shù)據(jù)對于數(shù)據(jù)報套接字直接使用CSocket類的SendTo()、ReceiveFrom()成員函數(shù)來發(fā)送和接收數(shù)據(jù)。對于流式套接字首先在服務(wù)器和客戶機之間建立連接,然后使用CSocket類的Send()、Receive()成員函數(shù)來發(fā)送和接收數(shù)據(jù),它們的調(diào)用方式與CAsyncSocket類相同。
不同的是CSocket類的這些函數(shù)工作在阻塞的模式。比如,一旦調(diào)用了Send()函數(shù),在所有的數(shù)據(jù)發(fā)送之前,程序或線程將處于阻塞的狀態(tài)。一般將CSocket類與CArchive類和CSocketFile類結(jié)合,來發(fā)送和接收數(shù)據(jù),這將使編程更為簡單。CSocket對象從不調(diào)用OnSend()事件處理函數(shù)。CSocket類的使用CSocket類與CArchive類和CSocketFile類使用CSocket類的最大優(yōu)點在于,應(yīng)用程序可以在連接的兩端通過CArchive對象來進行數(shù)據(jù)傳輸。具體做法創(chuàng)建CSocket類對象創(chuàng)建一個基于CSocketFile類的文件對象,并把它的指針傳給上面的已創(chuàng)建的CSocket對象。分別創(chuàng)建用于輸入和輸出的CArchive對象,并將它們與這個CSocketFile文件對象連接。利用CArchive對象來發(fā)送和接收數(shù)據(jù)。CSOCKET類編程模型55步驟服務(wù)器客戶端1//創(chuàng)建服務(wù)器偵聽套接字對象CSocketsockListen;//創(chuàng)建客戶機套接字對象CSocketsockClient;2//創(chuàng)建SOCKET句柄,綁定指定端口sockListen.Create(nPort);//創(chuàng)建SOCKET句柄,自動選擇本地可用端口sockClient.Create();3//啟動服務(wù)器端偵聽,時刻準備接受連接sockListen.Listen();
4
//向服務(wù)器發(fā)起連接請求sockClient.Connect(strAddr,nPort);5//創(chuàng)建一個新的服務(wù)器套接字對象CSocketsockServer;//接受客戶機連接sockListen.Accept(sockServer);
6//創(chuàng)建一個與套接字關(guān)聯(lián)的文件對象CSocketFilefile(&sockServer);//創(chuàng)建一個與套接字關(guān)聯(lián)的文件對象CSocketFilefile(&sockClient);7//在服務(wù)器創(chuàng)建與套接字文件對象關(guān)聯(lián)的歸檔對象,用于輸入或輸出CArchivearIn(&file,CArchive::load);-或-CArchivearOut(&file,CArchive::store);-或兩者-//在客戶機創(chuàng)建與套接字文件對象關(guān)聯(lián)的歸檔對象,用于輸入或輸出CArchivearIn(&file,CArchive::load);-或-CArchivearOut(&file,CArchive::store);-或兩者-8//使用歸檔對象傳輸數(shù)據(jù)arIn>>dwValu
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《雙半橋直流諧振變換器控制策略研究》
- 《外源Ca2+對鹽脅迫下珠美海棠幼苗耐鹽特性的影響》
- 《一種植物和三種高等真菌的化學成分及其生物活性研究》
- 2024冷卻塔用泵采購合同
- 《門德爾松《d小調(diào)莊嚴變奏曲》Op.54的音樂分析與演奏詮釋》
- 牛津譯林八年級下Unit3知識梳理學案
- 專題08電化學-原卷版
- 2024年海東客運資格證題庫
- 2024年山東客運從業(yè)資格考試
- 人教部編版六年級語文上冊第20課《青山不老》精美課件
- 餐飲行業(yè)初期投資預算分析
- 遼寧省重點高中沈陽市郊聯(lián)體2023-2024學年高三上學期期中生物試題(解析版)
- 剪映:手機短視頻制作-配套課件
- 西氣東輸二線25標段山嶺隧道內(nèi)管道安裝技術(shù)
- 防校園欺凌-課件(共28張PPT)
- 第6章 智能網(wǎng)聯(lián)汽車測評技術(shù)
- 單向板結(jié)構(gòu)設(shè)計
- 普通高等學校學生轉(zhuǎn)學申請表
- 房租、水、電費(專用)收據(jù)Excel模板
- 習近平總書記關(guān)于教育的重要論述研究學習通章節(jié)答案期末考試題庫2023年
評論
0/150
提交評論