2023年全國(guó)碩士研究生考試考研英語一試題真題(含答案詳解+作文范文)_第1頁
已閱讀1頁,還剩67頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、<p><b>  摘 要</b></p><p>  網(wǎng)絡(luò)聊天室,其實(shí)質(zhì)就是基于Internet的一種網(wǎng)絡(luò)聊天軟件。它可以在網(wǎng)絡(luò)環(huán)境下進(jìn)行實(shí)時(shí)的一對(duì)多或多對(duì)多的匿名交談。網(wǎng)絡(luò)聊天室軟件的制作方法有很多種,比如用MFC 和Java等語言設(shè)計(jì)的就有很多,本次課程設(shè)計(jì)主要是利用MFC所提供的各種控件尤其是WinSock控件,基于C/S模式,設(shè)計(jì)了一個(gè)網(wǎng)絡(luò)聊天室,圓滿地實(shí)現(xiàn)在網(wǎng)絡(luò)上實(shí)時(shí)

2、聊天及多種人性化的輔助功能。</p><p>  關(guān)鍵詞:WinSock;C/S ;Visual C++ 6.0;聊天室</p><p><b>  目錄</b></p><p><b> ?。?查找資料4</b></p><p>  1.1 網(wǎng)絡(luò)聊天程序的開發(fā)背景4</p>&l

3、t;p>  1.2 網(wǎng)絡(luò)聊天程序的設(shè)計(jì)目標(biāo)4</p><p><b> ?。?相關(guān)知識(shí)5</b></p><p>  2.1 Winsock介紹5</p><p>  2.2 MFC 的CAsyncsocket類和CSocket類6</p><p>  2.3 利用CSocket進(jìn)行有連接的通信..

4、................................8</p><p>  2.4 方案比較與選擇...............................................9</p><p>  3.詳細(xì)設(shè)計(jì)........................................................14</p><p

5、>  3.1聊天程序現(xiàn)....................................................15</p><p> ?。?程序流程圖62</p><p>  4.1 建立連接的流程圖62</p><p>  4.2 客戶關(guān)閉或者注銷時(shí)的程序流程圖63</p><p> ?。?程序運(yùn)行結(jié)果64&l

6、t;/p><p>  5.1 客戶端64</p><p><b>  5.2服務(wù)端64</b></p><p> ?。?、討論及進(jìn)一步研究建議...........................................65</p><p>  7、課程設(shè)計(jì)心得...........................

7、.......................66</p><p> ?。?、參考文獻(xiàn).......................................................67</p><p><b>  1.查找資料 </b></p><p>  當(dāng)前是數(shù)字信息時(shí)代,網(wǎng)絡(luò)時(shí)代,獲得信息的渠道做種多樣。而最為快速的當(dāng)然就是

8、網(wǎng)絡(luò)了。所以在課程設(shè)計(jì)動(dòng)員之后,我們就馬不停蹄的通過互聯(lián)網(wǎng)收縮有關(guān)網(wǎng)絡(luò)編程和MFC編程的有關(guān)資料。找到大量資料之后,我們還有根據(jù)課程設(shè)計(jì)的要求進(jìn)行篩選資料,最后選定方案和確定實(shí)現(xiàn)方法。這也是我們第一階段的工作。 </p><p>  1.1 網(wǎng)絡(luò)聊天程序的開發(fā)背景 </p><p>  近年來,互連網(wǎng)發(fā)展日新月異,網(wǎng)絡(luò)使空間的距離不再成為人們溝通的障礙,世界各個(gè)角落的人們可以通過Inter

9、net收發(fā)郵件、實(shí)時(shí)聊天、獲取最新的資訊。所以網(wǎng)絡(luò)聊天的程序早已被前人所實(shí)現(xiàn),而且實(shí)現(xiàn)的方法多種多樣。因此,本次課程設(shè)計(jì),我們主要借鑒前人創(chuàng)立的方法和編程經(jīng)驗(yàn)來制作一個(gè)C/S聊天室程序,通過制作該程序達(dá)到的學(xué)習(xí)網(wǎng)絡(luò)socket編程和使用MFC編程的相關(guān)知識(shí)。 </p><p>  1.2 網(wǎng)絡(luò)聊天程序的設(shè)計(jì)目標(biāo) </p><p>  本課題是設(shè)計(jì)一個(gè)網(wǎng)絡(luò)聊天的程序,包括服務(wù)器端和客戶端,主

10、要功能為: 客戶端部分:</p><p> ?。?、輸入服務(wù)器端IP地址和端口號(hào)進(jìn)行連接</p><p>  2、發(fā)送消息給服務(wù)器端并顯示服務(wù)器端回傳的消息</p><p>  3、在客戶端增加歷史聊天記錄和當(dāng)天聊天記錄 </p><p>  4、可以設(shè)置個(gè)性昵稱、增添快捷表情、更換個(gè)性圖像和背景設(shè)計(jì)</p><p>&

11、lt;b>  服務(wù)器端部分:</b></p><p>  立服務(wù)器端與客戶端的連接請(qǐng)求</p><p> ?。病⒔邮账杏脩舭l(fā)送的消息</p><p>  3、向所有在線用戶群發(fā)消息</p><p> ?。础⒃诳蛻舳嗽黾託v史聊天記錄和當(dāng)天聊天記錄 </p><p> ?。?、可以設(shè)置個(gè)性昵稱、增添快捷表

12、情、更換個(gè)性圖像和背景設(shè)計(jì)</p><p>  通過這次課程設(shè)計(jì),可以比較深入的了解和掌握WINSOCK控件基本屬性、方法和事件,熟悉VC++的開發(fā)環(huán)境。理解網(wǎng)絡(luò)聊天通信的概念,輸控制協(xié)議(TCP)進(jìn)行數(shù)據(jù)交流,初步掌握網(wǎng)絡(luò)聊天通信程序的設(shè)計(jì)方法,以及WINDOWS編程的一些方法。并能鞏固和擴(kuò)展之前學(xué)過的知識(shí),進(jìn)行項(xiàng)目的設(shè)計(jì)開發(fā)訓(xùn)練,更好的適應(yīng)社會(huì)的需求。 </p><p><b&g

13、t;  2.相關(guān)知識(shí)</b></p><p>  2.1 Winsock介紹</p><p>  Windows Sockets規(guī)范以U.C. Berkeley大學(xué)BSD UNIX中流行的Socket接口為范例定義了一套Micosoft Windows下網(wǎng)絡(luò)編程接口。它不僅包含了人們所熟悉的Berkeley Socket風(fēng)格的庫函數(shù);也包含了一組針對(duì)Windows的擴(kuò)展庫函數(shù)

14、,以使程序員能充分地利用Windows消息驅(qū)動(dòng)機(jī)制進(jìn)行編程。    Windows Sockets規(guī)范本意在于提供給應(yīng)用程序開發(fā)者一套簡(jiǎn)單的API,并讓各家網(wǎng)絡(luò)軟件供應(yīng)商共同遵守。此外,在一個(gè)特定版本W(wǎng)indows的基礎(chǔ)上,Windows Sockets也定義了一個(gè)二進(jìn)制接口(ABI),以此來保證應(yīng)用Windows Sockets API的應(yīng)用程序能夠在任何網(wǎng)絡(luò)軟件供應(yīng)商的符合Windows Sockets協(xié)議的實(shí)

15、現(xiàn)上工作。因此這份規(guī)范定義了應(yīng)用程序開發(fā)者能夠使用,并且網(wǎng)絡(luò)軟件供應(yīng)商能夠?qū)崿F(xiàn)的一套庫函數(shù)調(diào)用和相關(guān)語義。    遵守這套Windows Sockets規(guī)范的網(wǎng)絡(luò)軟件,我們稱之為Windows Sockets兼容的,而Windows Sockets兼容實(shí)現(xiàn)的提供者,我們稱之為Windows Soc</p><p>  2.2 MFC 的CAsyncsocket類和CSocket類</

16、p><p>  構(gòu)造一個(gè) CAsyncSocket 對(duì)象并使用該對(duì)象創(chuàng)建基礎(chǔ) SOCKET 句柄。 </p><p> ?、偬捉幼值膭?chuàng)建:遵循兩階段構(gòu)造的 MFC 模式。 </p><p><b>  例如: </b></p><p>  CAsyncSocket sock;sock.Create( ); // Use th

17、e default parameters </p><p><b>  - 或 - </b></p><p>  CAsyncSocket* pSocket = new CAsyncSocket;int nPort = 27;</p><p>  pSocket-> Create( nPort, SOCK_DGRAM ); </p&

18、gt;<p>  上面的第一個(gè)構(gòu)造函數(shù)在堆棧上創(chuàng)建一個(gè) CAsyncSocket 對(duì)象,第二個(gè)構(gòu)造函數(shù)在堆上創(chuàng)建 CAsyncSocket 。上面的第一個(gè) Create 調(diào)用使用默認(rèn)參數(shù)創(chuàng)建流式套接字,第二個(gè) Create 調(diào)用創(chuàng)建具有指定端口和地址的數(shù)據(jù)文報(bào)套接字。(任一個(gè) Create 版本都可以和任一種構(gòu)造方法一起使用。) </p><p>  Create 的參數(shù)有: </p>

19、<p>  “端口”:短整型。 </p><p>  對(duì)于服務(wù)器套接字,必須指定端口。對(duì)于客戶端套接字,通常接受此參數(shù)的默認(rèn)值,該值允許 Windows Sockets 選擇端口。 </p><p>  套接字類型: SOCK_STREAM (默認(rèn)值)或 SOCK_DGRAM 。 </p><p>  套接字“地址”,如“ftp1.scau.edu.cn

20、”或“128.56.22.8”。 該地址為網(wǎng)絡(luò)上的網(wǎng)際協(xié)議 (IP) 地址。很可能要始終依賴此參數(shù)的默認(rèn)值。 </p><p> ?、谌绻捉幼质强蛻舳?,則使用 CAsyncSocket::Connect 將此套接字對(duì)象連接到服務(wù)器套接字。 如果套接字是服務(wù)器,則將套接字設(shè)置為開始偵聽(使用 CAsyncSocket::Listen)來自客戶端的連接嘗試。接收到連接請(qǐng)求時(shí),用 CAsyncSocket::Acce

21、pt 接受該請(qǐng)求。 </p><p>  ③接受連接后,可以執(zhí)行驗(yàn)證密碼等任務(wù)。</p><p>  注意 Accept 成員函數(shù)采用對(duì)新的空 CSocket 對(duì)象的引用作為它的參數(shù)。在調(diào)用 Accept 之前,必須構(gòu)造該對(duì)象。如果此套接字對(duì)象超出范圍,則連接關(guān)閉。不要對(duì)這個(gè)新套接字對(duì)象調(diào)用 Create 。 </p><p> ?、芡ㄟ^調(diào)用 CAsyncSocke

22、t 對(duì)象的封裝 Windows Sockets API 函數(shù)的成員函數(shù),與其他套接字進(jìn)行通信。 </p><p> ?、萑绻诙褩I蟿?chuàng)建了套接字對(duì)象,當(dāng)包含函數(shù)超出范圍時(shí)將調(diào)用此對(duì)象的析構(gòu)函數(shù)。如果使用 new 運(yùn)算符在堆上創(chuàng)建了套接字對(duì)象,則您必須負(fù)責(zé)使用 delete 運(yùn)算符銷毀此對(duì)象。 析構(gòu)函數(shù)在銷毀對(duì)象之前調(diào)用對(duì)象的 Close 成員函數(shù)。</p><p>  2.3 利用CSo

23、cket進(jìn)行有連接的通信</p><p>  微軟的MFC把復(fù)雜的WinSock API函數(shù)封裝到類里,這使得編寫網(wǎng)絡(luò)應(yīng)用程序更容易。CAsyncSocket類逐個(gè)封裝了WinSock API,為高級(jí)網(wǎng)絡(luò)程序員 提供了更加有力而靈活的方法。這個(gè)類基于程序員了解網(wǎng)絡(luò)通訊的假設(shè),目的是為了在MFC中使用WinSock,程序員有責(zé)任處理諸如阻塞、字節(jié)順序和在Unicode與MBCS 間轉(zhuǎn)換字符的任務(wù)。</p>

24、;<p>  為了給程序員提供更方便的接口以自動(dòng)處理這些任務(wù),MFC給出 了CSocket類,這個(gè)類是由CAsyncSocket類繼承下來的,它提供了比CAsyncSocket更高層的WinSock API接口。CSocket類和CSocketFile類可以與CArchive類一起合作來管理發(fā)送和接收的數(shù)據(jù),這使管理數(shù)據(jù)收發(fā)更加便利。CSocket對(duì)象提供阻塞模式,這對(duì)于CArchive的同步操作是至關(guān)重要的。阻塞函數(shù)(如

25、Receive()、Send()、ReceiveFrom()、SendTo() 和Accept())直到操作完成后才返回控制權(quán)。</p><p>  因此如果需要低層控制和高效率,就使用CasyncSock類;如果需要方便,則可使用CSocket類。</p><p>  由于我們對(duì)網(wǎng)絡(luò)底層的了解比較淺薄,所以這次課程設(shè)計(jì)我們選擇了采用CSocket類來編程實(shí)現(xiàn)。下面主要針對(duì)這種方法進(jìn)行講述

26、。</p><p>  使用CSocket對(duì)象涉及CArchive和CSocketFile 類對(duì)象。以下介紹的針對(duì)字節(jié)流型(即基于TCP/IP協(xié)議)套接字的操作步驟中,只有第3和第4步對(duì)于客戶端和服務(wù)端操作是不同的,其他步驟都相同。 </p><p> ?、贅?gòu)造一個(gè)CSocket對(duì)象。   ② 使用這個(gè)對(duì)象的Create()成員函數(shù)產(chǎn)生一個(gè)socket對(duì)象。在客戶端程序中,除非需要數(shù)據(jù)

27、報(bào)套接字,Create()函數(shù)一般情況下應(yīng)該使用默認(rèn)參數(shù)。而對(duì)于服務(wù)端程序,必須在調(diào)用Create時(shí)指定一個(gè)端口。需要注意的是,CArchive類對(duì)象不能與數(shù)據(jù)報(bào)(UDP)套接字一起工作,因此對(duì)于數(shù)據(jù)報(bào)套接字,CAsyncSocket和CSocket 的使用方法是一樣的。  ?、?如果是客戶端套接字,則調(diào)用CAsyncSocket ∷Connect()函數(shù)與服務(wù)端套接字連接;如果是服務(wù)端套接字,則調(diào)用CAsyncSocket∷List

28、en()開始監(jiān)聽來自客戶端的連接請(qǐng)求,收到連接請(qǐng)求后,調(diào)用CAsyncSocket∷Accept()函數(shù)接受請(qǐng)求,建立連接。請(qǐng)注意Accept()成員函數(shù)需要一個(gè)新的并且為空的CSocket對(duì)象作為它的參數(shù)。  ?、?重載CSocket類的部分函數(shù)??蛻舳诵枰剌dOnReceive(int i) 和 OnClose(int i);服務(wù)器端需要重載OnAccept(int i) 、OnClose(int i) 和 OnR</p&g

29、t;<p>  2.4 方案比較與選擇 </p><p><b>  系統(tǒng)分析與設(shè)計(jì)</b></p><p>  1、系統(tǒng)構(gòu)架方式如下圖所示:</p><p>  設(shè)計(jì)出一個(gè)完整的網(wǎng)絡(luò)聊天程序,使之實(shí)現(xiàn)以上基本要求。</p><p>  服務(wù)端需要完成的三件事</p><p>

30、;  在特定端口等待連接請(qǐng)求,并需要維護(hù)一個(gè)客戶連接表,已記錄所有成功連接。</p><p>  及時(shí)接受消息,然后轉(zhuǎn)發(fā)到客戶連接。</p><p>  監(jiān)控連接狀態(tài),客戶離開或故障時(shí)從列表中刪除相應(yīng)表項(xiàng),并及時(shí)更新連接表。</p><p>  客戶端需要完成的三件事</p><p>  建立與維護(hù)服務(wù)器的連接,并隨時(shí)監(jiān)測(cè)連接狀態(tài)。</

31、p><p>  把用戶輸入的信息及時(shí)發(fā)送到服務(wù)端,同時(shí)準(zhǔn)備好接受,并顯示信息。</p><p>  在用戶退出時(shí)關(guān)閉連接。</p><p><b>  程序方案比較:</b></p><p>  方案一:基于TCP的socket編程</p><p>  TCP(Transmission Control

32、 Protocol,傳輸控制協(xié)議)是基于連接的協(xié)議,也就是說,在正式收發(fā)數(shù)據(jù)前,必須和對(duì)方建立可靠的連接。</p><p>  服務(wù)器端程序流程如下:</p><p>  創(chuàng)建套接字(socket);</p><p>  將套接字綁定到一個(gè)本地地址和端口上(bind);</p><p>  將套接字設(shè)為監(jiān)聽模式,準(zhǔn)備接受客戶請(qǐng)求(listen

33、);</p><p>  等待客戶請(qǐng)求到來;當(dāng)請(qǐng)求到來后,接受連接請(qǐng)求,返回一個(gè)新的對(duì)應(yīng)于此次連接的套接字(accept);</p><p>  用返回的套接字和客戶端進(jìn)行通信(send/recv);</p><p>  返回,等待另一客戶請(qǐng)求;</p><p><b>  關(guān)閉套接字;</b></p>&

34、lt;p>  客戶端程序流程如下:</p><p>  創(chuàng)建套接字(socket);</p><p>  向服務(wù)器發(fā)出連接請(qǐng)求(connect);</p><p>  和服務(wù)器端進(jìn)行通信(send/recv);</p><p><b>  關(guān)閉套接字。</b></p><p>  在服務(wù)器端

35、,當(dāng)調(diào)用accept函數(shù)時(shí),程序就會(huì)等待,等待客戶調(diào)用connect函數(shù)發(fā)出連接請(qǐng)求,然后服務(wù)器端接受該請(qǐng)求,于是雙方就建立了連接。之后,服務(wù)器端和客戶端就可以利用send和recv函數(shù)進(jìn)行通信了。因?yàn)榉?wù)器需要接受客戶端的請(qǐng)求,所以必須告訴本地主機(jī)它打算在哪個(gè)IP地址和哪個(gè)端口上等待客戶要求,因此必須調(diào)用bind函數(shù)來實(shí)現(xiàn)這一功能。而對(duì)客戶端來說,當(dāng)它發(fā)起連接請(qǐng)求,服務(wù)器端接受請(qǐng)求后,在服務(wù)端就保存了改客戶端的IP地址和端口的信息。這

36、樣,對(duì)服務(wù)器端來說,一旦建立連接之后,實(shí)際上它已經(jīng)保存了客戶端的IP地址和端口號(hào)的信息,就可以利用所返回的套接字調(diào)用send/recv函數(shù)與客戶端進(jìn)行通信。</p><p><b>  程序流程圖如下:</b></p><p>  方案二:基于UDP(面向無連接)的socket程序</p><p>  UDP(User Data Protoco

37、l,用戶數(shù)據(jù)報(bào)協(xié)議)是與TCP相對(duì)應(yīng)的協(xié)議。它是面向非連接的協(xié)議,它不與對(duì)方建立連接,而是直接就把數(shù)據(jù)包發(fā)送過去。UDP適用于一次只傳送少量數(shù)據(jù)、對(duì)可靠性要求不高的應(yīng)用環(huán)境</p><p>  服務(wù)器端也叫接收端,對(duì)于基于UDP(面向無連接)的套接字編程來說,它的服務(wù)器端和客戶端這種概念不是很強(qiáng)化,我們也可以把服務(wù)器端,即先啟動(dòng)的一端稱為接收端,發(fā)送數(shù)據(jù)的一端稱為發(fā)送端,也稱為客戶端。</p>&l

38、t;p>  服務(wù)端程序編寫流程如下:</p><p>  創(chuàng)建套接字(socket);</p><p>  將套接字綁定到一個(gè)本地地址和端口上(bind);</p><p>  等待接受數(shù)據(jù)(recvfrom);</p><p><b>  關(guān)閉套接字。</b></p><p>  雖然面向

39、無連接的socket編程無須建立連接,但是為了完成這次通信,對(duì)于接受端來說,它必須先啟動(dòng)以接受客戶端發(fā)送的數(shù)據(jù),因此接收端必須告訴主機(jī)它是在哪個(gè)地址和端口上等待數(shù)據(jù)的到來,接收端(服務(wù)器端)必須調(diào)用bind函數(shù)將套接字綁定到一個(gè)本地地址和端口上。</p><p>  客戶端程序編寫流程如下:</p><p>  創(chuàng)建套接字(socket);</p><p>  向服

40、務(wù)器發(fā)送數(shù)據(jù)(sengto);</p><p><b>  關(guān)閉套接字。</b></p><p>  在UDP的套接字編程時(shí),利用的是sendto和recvfrom這兩個(gè)函數(shù)實(shí)現(xiàn)數(shù)據(jù)的發(fā)送和接收,而基于TCP的套接字編程時(shí),發(fā)送數(shù)據(jù)是調(diào)用send函數(shù),接受數(shù)據(jù)調(diào)用recv函數(shù)。</p><p><b>  程序流程圖如下:</b

41、></p><p><b>  方案比較結(jié)果</b></p><p>  TCP與UDP最基本的區(qū)別在于基于連接與無連接,相比之下,第一種方案對(duì)系統(tǒng)的要求以及數(shù)據(jù)量都比較大,但是保證數(shù)據(jù)的正確性與數(shù)據(jù)順序,在傳輸大量數(shù)據(jù)的時(shí)候具有更高的可靠性。至于第二種方案的優(yōu)點(diǎn)在于傳輸?shù)乃俣瓤欤绦蚪Y(jié)構(gòu)精簡(jiǎn)。</p><p>  總的來說,我認(rèn)為TCP

42、協(xié)議更能滿足目前各行業(yè)對(duì)遠(yuǎn)程數(shù)據(jù)傳輸?shù)囊?,它提供更穩(wěn)定更便利的傳輸通道,滿足了對(duì)安全性的要求以及遠(yuǎn)程數(shù)據(jù)傳輸?shù)囊蟆?lt;/p><p>  所以我們小組選擇方案一。</p><p><b>  3.詳細(xì)設(shè)計(jì)</b></p><p>  我們利用MFC提供的CSocket類來編程實(shí)現(xiàn)一個(gè)網(wǎng)絡(luò)聊天室。那么就需要一個(gè)聊天的服務(wù)器(即是服務(wù)端),它可以

43、和很多客戶端進(jìn)行通信,從而把來自不同的客戶的聊天信息轉(zhuǎn)交到所有其他的客戶端。當(dāng)然也需要用戶界面(客戶端)。這樣就形成了一個(gè)采用Client/Server結(jié)構(gòu)的并可以多人同時(shí)在線的聊天室。同時(shí),服務(wù)器端應(yīng)該有一定的管理功能,如手動(dòng)/自動(dòng)響應(yīng)申請(qǐng)、設(shè)置服務(wù)器名稱和服務(wù)器端口、在線名單統(tǒng)計(jì)、單獨(dú)斷開某人連接以及保持聊天記錄等功能。對(duì)于客戶端,因?yàn)槭敲嫦蛴脩?,所以外觀和功能都應(yīng)有更高的要求。實(shí)現(xiàn)諸如:手動(dòng)輸入IP 和用戶名、頭像切換、心情書寫、

44、表情輸入、軟件皮膚切換、注銷登錄、保存聊天記錄以及伸縮界面等功能。下面詳細(xì)介紹各項(xiàng)功能是如何實(shí)現(xiàn)的。</p><p>  3.1聊天程序的實(shí)現(xiàn)</p><p>  (1)首先啟動(dòng)Visual C++ 6.0,利用MFC AppWizard[EXE]建立一個(gè)新的MFC工程,工程名為chat,在MFC AppWizard Step1的時(shí)候選擇Dialog based 即基于對(duì)話框,在Step4

45、時(shí)勾選Windows Sockets選項(xiàng)(如圖表 02),其他默認(rèn)值下一步。</p><p><b>  圖表 01</b></p><p><b>  圖表 02</b></p><p> ?。?)客戶端的界面如圖圖表 03所示。其中包含文檔編輯框、按鍵控件、靜態(tài)文本控件組成。左半邊由上自下分別是:頭像、昵稱、當(dāng)

46、天聊天信息顯示、12個(gè)表情按鈕、消息輸入框和發(fā)送按鈕。右半邊有歷史記錄顯示框、歷史記錄顯示按鈕。</p><p>  圖表 03軟件界面</p><p><b>  圖表 04</b></p><p>  聊天程序總共有6個(gè)類。其中,CChatApp和CAboutDlg由AppWizard實(shí)現(xiàn);另外,CServerSocket和CClien

47、tSocket分別負(fù)責(zé)服務(wù)端和客戶端的網(wǎng)絡(luò)通信功能;CChatDlg為程序的主控類,主界面、通信方式及程序邏輯均由該類實(shí)現(xiàn),它繼承自CDialog類;CMessgage是對(duì)消息的封裝。</p><p>  CClientSocket</p><p>  通過相應(yīng)的OnReceive消息來接收數(shù)據(jù),響應(yīng)OnClose消息來斷開對(duì)話的處理,實(shí)現(xiàn)以CArchive對(duì)數(shù)據(jù)進(jìn)行的串行化。</p

48、><p><b>  類定義代碼如下:</b></p><p>  #include"Messg.h" //命令目標(biāo)</p><p>  class CChatDlg;</p><p>  class CClientSocket:public CSocket</p><p>&l

49、t;b>  {</b></p><p><b>  public:</b></p><p>  CArchive *m_aSessionIn;</p><p>  CArchive *m_aSessionOut;</p><p>  CSocketFile *m_sfSocketFile;</p&

50、gt;<p>  CChatDlg *m_dlg;</p><p>  bool m_bInit; //是否進(jìn)行了初始化</p><p>  bool m_bClose; //連接是否關(guān)閉</p><p><b>  public:</b></p><p>  void Init(CChatDlg *d

51、lg);</p><p>  BOOL SendMessage(CMessg *msg);</p><p>  void CloseSocket();</p><p><b>  public:</b></p><p>  static int GetLocalHostName(CString &sHostNam

52、e); //獲得本地計(jì)算機(jī)名稱</p><p>  static int GetIpAddress(const CString &sHostName,</p><p>  CString &sIpAddress); //獲得本地IP</p><p>  static int GetIpAddress(const CString &sHos

53、tName,BYTE &f0,</p><p>  BYTE &f1,BYTE &f2,BYTE &f3); //獲得本地IP</p><p>  static CString ErrorReason(int tag);</p><p><b>  public:</b></p><p>

54、;  virtual void OnReceive(int nErrorCode);</p><p>  virtual void OnClose(int nErrorCode);</p><p><b>  public:</b></p><p>  CClientSocket();</p><p>  virtual

55、 ~CClientSocket();</p><p>  protected:</p><p><b>  };</b></p><p>  CClientSocket.CPP中的代碼:</p><p>  #include "stdafx.h"</p><p>  #incl

56、ude "chat.h"</p><p>  #include "ClientSocket.h"</p><p>  #include"ChatDlg.h"</p><p>  // CClientSocket</p><p>  CClientSocket::CClientSock

57、et()</p><p><b>  {</b></p><p>  m_aSessionIn=NULL;</p><p>  m_aSessionOut=NULL;</p><p>  m_sfSocketFile=NULL;</p><p>  m_bInit=false;</p>

58、<p>  m_bClose=false;</p><p><b>  }</b></p><p>  CClientSocket::~CClientSocket()</p><p><b>  {</b></p><p>  if(m_aSessionIn)</p>&

59、lt;p>  delete m_aSessionIn;</p><p>  if(m_aSessionOut)</p><p>  delete m_aSessionOut;</p><p>  if(m_sfSocketFile)</p><p>  delete m_sfSocketFile;</p><p>

60、;<b>  }</b></p><p>  //ClientSocket成員函數(shù)</p><p>  void CClientSocket::OnReceive(int nErrorCode)</p><p><b>  {</b></p><p>  CSocket::OnReceive(nEr

61、rorCode); //OnReceive()函數(shù)的實(shí)現(xiàn)</p><p><b>  do</b></p><p><b>  {</b></p><p>  CMessg temp;</p><p>  temp.Serialize(*m_aSessionIn);</p>&l

62、t;p>  m_dlg->m_sMsgList+=temp.m_strText+"\r\n";</p><p>  m_dlg->m_tmpMsgList=temp.m_strText+"\r\n";</p><p>  m_dlg->SetDlgItemText(IDC_SHOWTEXT,m_dlg->m_sMsgLi

63、st);</p><p><b>  FILE* fp;</b></p><p>  fp = fopen("chatnote.txt","a+");</p><p>  fputs(m_dlg->m_tmpMsgList,fp);</p><p>  fclose(fp)

64、;</p><p>  m_dlg->SetDlgItemText(IDC_SHOWTEXT,m_dlg->m_sMsgList);</p><p>  int linenum=((CEdit*)</p><p>  (m_dlg->GetDlgItem(IDC_SHOWTEXT)))->GetLineCount();</p>

65、<p><b>  ((CEdit*)</b></p><p>  (m_dlg->GetDlgItem(IDC_SHOWTEXT)))->LineScroll(linenum);</p><p>  if(!m_dlg->m_bClient)</p><p>  { </p>

66、<p>  for(POSITION pos=m_dlg->m_connectionList.GetHeadPosition();</p><p>  pos!=NULL;)</p><p><b>  {</b></p><p>  CClientSocket *t=(CClientSocket*)</p>&l

67、t;p>  m_dlg->m_connectionList.GetNext(pos);</p><p>  if(t->m_hSocket!=this->m_hSocket)</p><p><b>  {</b></p><p>  t->SendMessage(&temp);</p>&l

68、t;p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  while(!m_aSessionIn->IsBufferEmpty()

69、);</p><p><b>  }</b></p><p>  void CClientSocket::Init(CChatDlg *dlg)</p><p><b>  {</b></p><p>  m_sfSocketFile=new CSocketFile(this);</p>

70、<p>  m_aSessionIn=new CArchive(m_sfSocketFile,CArchive::load);</p><p>  m_aSessionOut=new CArchive(m_sfSocketFile,CArchive::store);</p><p>  m_bClose=false;</p><p>  this-&g

71、t;m_dlg=dlg;</p><p><b>  }</b></p><p><b>  /*</b></p><p>  *SendMessage()函數(shù)的實(shí)現(xiàn)</p><p><b>  *主要功能:</b></p><p><b> 

72、 *將信息串行化</b></p><p><b>  */</b></p><p>  BOOL CClientSocket::SendMessage(CMessg *msg)</p><p><b>  {</b></p><p>  if(m_aSessionOut!=NULL)&l

73、t;/p><p><b>  {</b></p><p>  msg->Serialize(*m_aSessionOut);</p><p>  m_aSessionOut->Flush();</p><p>  return TRUE;</p><p><b>  }</

74、b></p><p><b>  else</b></p><p><b>  {</b></p><p>  m_bClose=true; //對(duì)方關(guān)閉了連接</p><p>  CloseSocket();</p><p>  m_dlg->CloseSes

75、sionSocket();</p><p>  return FALSE;</p><p><b>  }</b></p><p><b>  }</b></p><p><b>  /*</b></p><p>  *CloseSocket()函數(shù)的實(shí)

76、現(xiàn)</p><p><b>  *主要功能:</b></p><p><b>  *關(guān)閉套接字的連接</b></p><p><b>  */</b></p><p>  void CClientSocket::CloseSocket()</p><p>

77、;<b>  {</b></p><p>  if(m_aSessionIn)</p><p><b>  {</b></p><p>  delete m_aSessionIn;</p><p>  m_aSessionIn=NULL;</p><p><b> 

78、 }</b></p><p>  if(m_aSessionOut)</p><p><b>  {</b></p><p>  delete m_aSessionOut;</p><p>  m_aSessionOut=NULL;</p><p><b>  }</b

79、></p><p>  if(m_sfSocketFile)</p><p><b>  {</b></p><p>  delete m_sfSocketFile;</p><p>  m_sfSocketFile=NULL;</p><p><b>  }</b>&

80、lt;/p><p><b>  Close();</b></p><p>  m_bInit=false;</p><p>  m_bClose=true;</p><p><b>  }</b></p><p><b>  /*</b></p>

81、<p>  *OnClose()函數(shù)的實(shí)現(xiàn)</p><p><b>  *主要功能:</b></p><p><b>  *關(guān)閉套接字的連接</b></p><p><b>  */</b></p><p>  void CClientSocket::OnClos

82、e(int nErrorCode)</p><p><b>  {</b></p><p>  m_bClose=true;</p><p>  CloseSocket();</p><p>  m_dlg->CloseSessionSocket();</p><p>  CSocket::

83、OnClose(nErrorCode);</p><p><b>  }</b></p><p><b>  /*</b></p><p>  *GetLocalHostName()函數(shù)的實(shí)現(xiàn)</p><p><b>  *主要功能:</b></p><p&

84、gt;  *獲得本地計(jì)算機(jī)的名稱</p><p><b>  */</b></p><p>  int CClientSocket::GetLocalHostName(CString &sHostName)</p><p><b>  {</b></p><p>  char szHostN

85、ame[256];</p><p>  int nRetCode;</p><p>  nRetCode=gethostname(szHostName,sizeof(szHostName));</p><p>  if(nRetCode!=0)</p><p>  { //產(chǎn)生錯(cuò)誤</p><p>  sHost

86、Name=_T("沒有取得");</p><p>  return GetLastError();</p><p><b>  }</b></p><p>  sHostName=szHostName;</p><p><b>  return 0;</b></p>

87、<p><b>  }</b></p><p><b>  /*</b></p><p>  *GetIpAddress()函數(shù)的實(shí)現(xiàn)</p><p><b>  *主要功能:</b></p><p><b>  *取得本地IP地址</b>&l

88、t;/p><p><b>  */</b></p><p>  int CClientSocket::GetIpAddress(const CString &sHostName,CString &sIpAddress)</p><p><b>  //獲得本地IP</b></p><p>

89、;<b>  {</b></p><p>  struct hostent FAR *lpHostEnt=gethostbyname(sHostName);</p><p>  if(lpHostEnt==NULL)</p><p>  { //產(chǎn)生錯(cuò)誤</p><p>  sIpAddress=_T("

90、");</p><p>  return GetLastError();</p><p><b>  }</b></p><p>  LPSTR lpAddr=lpHostEnt->h_addr_list[0];</p><p>  if(lpAddr)</p><p><b

91、>  {</b></p><p>  struct in_addr inAddr;</p><p>  memmove(&inAddr,lpAddr,4);</p><p>  sIpAddress=inet_ntoa(inAddr); //轉(zhuǎn)換為標(biāo)準(zhǔn)格式</p><p>  if(sIpAddress.IsEm

92、pty())</p><p>  sIpAddress=_T("沒有取得");</p><p><b>  }</b></p><p><b>  return 0;</b></p><p><b>  }</b></p><p>&

93、lt;b>  /*</b></p><p>  * GetIpAddress ()函數(shù)的實(shí)現(xiàn)</p><p><b>  *主要功能:</b></p><p><b>  *獲得本地IP地址</b></p><p><b>  */</b></p>

94、<p>  int CClientSocket::GetIpAddress(const CString &sHostName,BYTE &f0,</p><p>  BYTE &f1,BYTE &f2,BYTE &f3)//獲得IP地址</p><p><b>  {</b></p><p>

95、;  struct hostent FAR *lpHostEnt=gethostbyname(sHostName);</p><p>  if(lpHostEnt==NULL)</p><p>  { //產(chǎn)生錯(cuò)誤</p><p>  f0=f1=f2=f3=0;</p><p>  return GetLastError();</

96、p><p><b>  }</b></p><p>  LPSTR lpAddr=lpHostEnt->h_addr_list[0]; //獲取IP</p><p>  if(lpAddr)</p><p><b>  {</b></p><p>  struct in

97、_addr inAddr;</p><p>  memmove(&inAddr,lpAddr,4);</p><p>  f0=inAddr.S_un.S_un_b.s_b1; </p><p>  f1=inAddr.S_un.S_un_b.s_b2;</p><p>  f2=inAddr.S_un.S_un_b.s_b3;&

98、lt;/p><p>  f3=inAddr.S_un.S_un_b.s_b4;</p><p><b>  }</b></p><p><b>  return 0;</b></p><p><b>  }</b></p><p>  CString CCl

99、ientSocket::ErrorReason(int tag) //錯(cuò)誤信息的宏定義</p><p><b>  {</b></p><p>  CString result;</p><p>  switch(tag)</p><p><b>  {</b></p><p

100、>  case WSANOTINITIALISED:</p><p>  result="A successful AfxSocketInit must occur before using this API.";</p><p><b>  break;</b></p><p>  case WSAENETDOWN:

101、</p><p>  result="The network subsystem failed";</p><p><b>  break;</b></p><p>  case WSAEADDRINUSE:</p><p>  result="The specified address i

102、s already in use";</p><p><b>  break;</b></p><p>  case WSAEINPROGRESS:</p><p>  result="A blocking Windows Socket call is in progress";</p><p&

103、gt;<b>  break;</b></p><p>  case WSAEADDRNOTAVAIL:</p><p>  result="The specified address is not available from the local machine";</p><p><b>  break;<

104、;/b></p><p>  case WSAEAFNOSUPPORT:</p><p>  result="Address in the specified family cannot be used with this socket";</p><p><b>  break;</b></p><

105、;p>  case WSAECONNREFUSED:</p><p>  result="The attempt to connect eas rejected";</p><p><b>  break;</b></p><p>  case WSAEDESTADDRREQ:</p><p>

106、  result="A destination address is requireed";</p><p><b>  break;</b></p><p>  case WSAEFAULT:</p><p>  result="The nSockAddrLen arguement is incorrect&qu

107、ot;;</p><p><b>  break;</b></p><p>  case WSAEINVAL:</p><p>  result="Invalid host address";</p><p><b>  break;</b></p><p&g

108、t;  case WSAEISCONN:</p><p>  result="The socket is already connected";</p><p><b>  break;</b></p><p>  case WSAEMFILE:</p><p>  result="No m

109、ore file descriptions are available";</p><p><b>  break;</b></p><p>  case WSAENETUNREACH:</p><p>  result="The network cannot be reached from this host at thi

110、s time";</p><p><b>  break;</b></p><p>  case WSAENOBUFS:</p><p>  result="No buffer space is available.The socket cannot be connected";</p><p&

111、gt;<b>  break;</b></p><p>  case WSAENOTSOCK:</p><p>  result="The descriptor is not a socket";</p><p><b>  break;</b></p><p>  case W

112、SAETIMEDOUT:</p><p>  result="Attempt to connect timed out without establishing a connection";</p><p><b>  break;</b></p><p>  case WSAEWOULDBLOCK:</p>

113、<p>  result="The socket is marked as nonblocking and the connnection cannot be completed immediately";</p><p><b>  break;</b></p><p><b>  default:</b><

114、/p><p>  result="unknown error";</p><p><b>  }</b></p><p>  return result;</p><p><b>  }</b></p><p>  CServerSocket</p>

115、;<p>  CServerSocket主要功能是實(shí)現(xiàn)OnAccept()消息,負(fù)責(zé)監(jiān)聽服務(wù)窗口,是一個(gè)服務(wù)socket。</p><p>  CServerSocket.h的代碼如下:</p><p>  // CServerSocket command target</p><p>  class CChatDlg;</p><

116、p>  class CServerSocket: public CSocket</p><p><b>  {</b></p><p><b>  public:</b></p><p>  CServerSocket();</p><p>  virtual ~CServerSocket()

117、;</p><p>  CChatDlg *m_dlg;</p><p>  UINT m_uPort;</p><p>  BOOL Init(UINT port,CChatDlg *dlg);</p><p><b>  public:</b></p><p>  virtual void O

118、nAccept(int nErrorCode); //用于響應(yīng)OnAccept消息的函數(shù)</p><p><b>  };</b></p><p>  CServerSocket.CPP的代碼如下:</p><p>  #include "stdafx.h"</p><p>  #include &

119、quot;chat.h"</p><p>  #include "ServerSocket.h"</p><p>  #include "ChatDlg.h"</p><p>  // CServerSocket</p><p>  CServerSocket::CServerSocket()

120、</p><p><b>  {</b></p><p><b>  }</b></p><p>  CServerSocket::~CServerSocket()</p><p><b>  {</b></p><p><b>  }<

121、/b></p><p>  //CServerSocket成員函數(shù)</p><p>  BOOL CServerSocket::Init(UINT port,CChatDlg *dlg)</p><p><b>  {</b></p><p>  m_uPort=port;</p><p>

122、  m_dlg=dlg;</p><p>  if(Create(m_uPort)==FALSE)</p><p><b>  {</b></p><p>  AfxMessageBox(_T("Server Socket Create Error"));</p><p>  return FALSE

123、;</p><p><b>  }</b></p><p>  if(this->Listen()==FALSE)</p><p><b>  {</b></p><p>  AfxMessageBox("Server Listen Error");</p>

124、<p>  return FALSE;</p><p><b>  }</b></p><p>  m_dlg->SetDlgItemText(IDC_SHOWTEXT,"Serverr Has Been Set OK!");</p><p>  return TRUE;</p><p&g

125、t;<b>  }</b></p><p>  void CServerSocket::OnAccept(int nErrorCode)</p><p><b>  {</b></p><p>  m_dlg->ProcessPendingAccept();</p><p>  CSocket

126、::OnAccept(nErrorCode);</p><p><b>  }</b></p><p><b>  CMessg</b></p><p>  CMessg類主要作用是實(shí)現(xiàn)信息的串行化,方便信息的傳輸。</p><p>  CMessg.h代碼如下:</p><p&

127、gt;  #pragma once</p><p>  class CMessg:public CObject //命令目標(biāo)</p><p><b>  {</b></p><p>  protected:</p><p>  DECLARE_DYNCREATE(CMessg)</p><p>

128、;<b>  public:</b></p><p><b>  CMessg();</b></p><p><b>  public:</b></p><p>  CString m_strText;</p><p><b>  public:</b>&

129、lt;/p><p>  void Init();</p><p><b>  public:</b></p><p>  virtual ~CMessg();</p><p>  virtual void Serialize(CArchive &ar); //實(shí)行串行化</p><p>  

130、#if def_DEBUG</p><p>  virtual void AssertValid() const;</p><p>  virtual void Dump(CDumpContext &dc) const;</p><p><b>  #endif</b></p><p><b>  };

131、</b></p><p>  CMessg.CPP代碼如下:</p><p>  #include "stdafx.h"</p><p>  #include "chat.h"</p><p>  #include "Messg.h"</p><p&g

溫馨提示

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

評(píng)論

0/150

提交評(píng)論