版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、<p> 本科畢業(yè)設計(論文)</p><p><b> ?。ǘ?屆)</b></p><p> 基于VC的簡單即時通信軟件開發(fā)</p><p> 所在學院 </p><p> 專業(yè)班級 電子信息工程 </p
2、><p> 學生姓名 學號 </p><p> 指導教師 職稱 </p><p> 完成日期 年 月 </p><p><b> 摘 要</b></p><p>
3、 本文開頭講述了通訊軟件的來源,研究意義,繼而展開對即時通訊軟件的討論。</p><p> 第一章主要講述了即時通訊軟件的現(xiàn)狀,研究意義。</p><p> 第二章深入地講述了如何開發(fā)一款簡單的即時通訊軟件,內(nèi)容包括了:功能描述,主要是指該即時通訊軟件的基本功能,如文本的發(fā)送和接收;結構描述,是指構成一個簡單通訊系統(tǒng)所必須的幾個模塊——服務器,客戶端,internet;通訊協(xié)議、報文
4、,其中講述了在這個系統(tǒng)中所用到的幾個命令,如登陸、登出命令。以及各種細節(jié)的描述,如結構設計,宏的設計,外觀設計,和各模塊功能的設計。這幾部分的描述,是這個軟件的框架。</p><p> 最后部分是相關重要內(nèi)容的代碼設計。這一部分是通過參考各種文獻和報刊雜志等,然后匯總,分析,組合,修改而成的。主要涉及的有CClient類的實現(xiàn),Server類的實現(xiàn)。</p><p> 關鍵詞:即時通訊
5、軟件、vc++、chat類、server設計。</p><p> The Design of Simple Instant Messaging Software Based on VC</p><p><b> Abstract</b></p><p> Beginning of this article,I describes the
6、source of communication software , the study of significance.Then expand the discussion of instant messaging software. Chapter1 mainly describes about the status of instant messaging software and significance.
7、Chapter2 describes in-depth about how to develop a simple instant messaging software. Topics include: functional description, Mainly refers to the basic functions of instant messaging software, such as sending and receiv
8、ing text; the sch</p><p> It’s an important part of the code related to the design. This section is by reference to a variety of documents and newspapers and magazines, then summary, analysis, portfolio, c
9、hanges made. Mainly related to implementation of the class are CClient,server class implementation. Keywords: IM, vc + +, chat class, server design.</p><p><b> 目錄</b></p><p><b
10、> 摘要I</b></p><p> AbstractII</p><p><b> 1 緒論1</b></p><p> 1.1課題的來源1</p><p> 1.2課題的意義1</p><p> 1.3即時通訊國內(nèi)外發(fā)展現(xiàn)狀2</p>&
11、lt;p> 1.4課題研究的主要內(nèi)容2</p><p> 2 功能描述和系統(tǒng)結構3</p><p> 2.1即時通訊系統(tǒng)的主要功能3</p><p> 2.2即時通訊系統(tǒng)的結構4</p><p> 3 通訊協(xié)議和報文格式5</p><p> 4 結構、類型和宏8</p>&l
12、t;p> 5 Chat的UI設計10</p><p> 6 Chat主要的類及其關系11</p><p> 6.1 ClientDlg的類11</p><p> 6.2 Server的類14</p><p> 7 Chat的實現(xiàn)16</p><p> 7.1 Client的實現(xiàn)代碼16&l
13、t;/p><p> 7.2 Server的實現(xiàn)代碼35</p><p><b> 結論50</b></p><p><b> 參考文獻51</b></p><p><b> 致謝52</b></p><p><b> 1 緒論&l
14、t;/b></p><p><b> 1.1課題的來源</b></p><p> InstantMessaging或即時通訊或實時傳訊的縮寫是IM,這是一種可以讓使用者在網(wǎng)絡上可以建立某種私人聊天室(chatroom)的實時通訊的服務。目前在互聯(lián)網(wǎng)上很受歡迎的即時通訊軟件包括QQ、百度HI、新浪UC、MSN Messenger等等。</p>&
15、lt;p> 基于局域網(wǎng)的即時通信工具,實際上是在互聯(lián)網(wǎng)即時通信工具中的一個小規(guī)模版本。是為了實現(xiàn)快捷通訊而出現(xiàn)的。如今一般采用UDP或者 TCP協(xié)議體系來實現(xiàn) 。</p><p> 1970年代早期,一種更早的即時通訊形式是柏拉圖系統(tǒng)(PLATO system)。之後在1980年代,UNIX/Linux的交談即時訊息被廣泛的使用在工程師與學術界,1990年代即時通訊更跨越了網(wǎng)際網(wǎng)路交流的界限。1996年
16、11月,ICQ是首個廣泛被非UNIX/Linux使用者用於網(wǎng)際網(wǎng)路的即時通訊軟體,并開始廣泛擴散。在ICQ的之後,同時在許多地方都有了一定數(shù)量的即時通訊方式發(fā)展,且各式的即時通訊程式具有獨立的協(xié)定,且無法彼此互通。這引導使用者同時執(zhí)行兩個以上的即時通訊軟體,或者他們可以使用支援多協(xié)定的終端軟體,如Gaim、Trillian或Jabber。</p><p><b> 1.2課題的意義</b>
17、</p><p> 即時聊天工具是一種可以讓使用者在網(wǎng)絡上實時通訊的工具,大部分的即時通訊工具提供了狀態(tài)信息的特性,如顯示聯(lián)絡人名單,聯(lián)絡人是否在線及能否與聯(lián)絡人交談等。</p><p> 在本文中我們將討論一種基于MFC Socket的局域網(wǎng)通信工具的設計與實現(xiàn)方法?;贛FC Socket的局域網(wǎng)通信軟件可以為局域網(wǎng)提供一種良好、安全、快速的通信機制,在局域網(wǎng)內(nèi)部通信、教學、討論等
18、應用中都具有一定的實用價值,它同時很好地詮釋了MFC Socket通信的原理?;赟ocket的局域網(wǎng)通信軟件應用范圍廣闊,不但可以處理傳統(tǒng)的通信需求,而且也能擴展以適應新型的網(wǎng)絡應用,如網(wǎng)絡教育,數(shù)據(jù)影音傳輸?shù)?,擁有廣泛的應用前景。</p><p> 如今許許多多的企業(yè)非??释梢杂幸豢畎踩?,純凈的,適用于商業(yè)使用的聊天系統(tǒng)。所以在聊天軟件如此豐富的環(huán)境下,即時通訊軟件的研究是很有意義的。</p>
19、;<p> 1.3即時通訊國內(nèi)外發(fā)展現(xiàn)狀</p><p> 開發(fā)到現(xiàn)在,技術已經(jīng)比較成熟,有了比如較早的ICQ、MSN Messenger、YAHOO通等國外開發(fā)的產(chǎn)品,還有國產(chǎn)的QQ、新浪UC、LAVA-LAVA等聊天軟件,這些工具統(tǒng)統(tǒng)都能實現(xiàn)廣域網(wǎng)上的即時通信,盡管都是即時通信,實現(xiàn)了即時聊天,以及文件傳輸?shù)鹊闹饕δ?,但是也各有特色,比如ICQ具有巨大客戶群,MSN具有個性化表情,YAHO
20、O通有易操作性等,當然QQ也具有一個相當方便的屏幕截圖功能,另外就是,所有上述軟件都已實現(xiàn)了網(wǎng)絡即時的視頻,語音聊天功能[1]。</p><p> 這些軟件,在使用方面各有特色,在實現(xiàn)方面也各有所長,但由于這些產(chǎn)品正在商業(yè)運營的階段,其實現(xiàn)方式是屬于商業(yè)機密的,具體細節(jié)我不可能得知到,但是它在大的方面無非就是各種利用各種平臺上的網(wǎng)絡通信接口等,建構基于下層TCP/IP,或者UDP/IP協(xié)議的軟件產(chǎn)品而已。在局域
21、網(wǎng)內(nèi),這些功能的實現(xiàn)相比廣域網(wǎng)來說更加簡單,因為局域網(wǎng)的網(wǎng)絡結構本身就比廣域網(wǎng)要簡單,但是可以借此來理解網(wǎng)絡協(xié)議,以及網(wǎng)絡通信工具的實現(xiàn)原理。</p><p> 1.4課題研究的主要內(nèi)容</p><p> 這個課題的要求是開發(fā)基于vc++的局域網(wǎng)簡單即時通訊軟件。所以第一個主要內(nèi)容就是開發(fā)平臺—vc++6.0。我們通常所說的Visual C++實際是一個完善的、非常強大的C++程序開發(fā)
22、環(huán)境,它的全名是 Microsoft Developer Studio。二者之間的細小差別其實并不重要,通常這兩個術語可以互換。但如果我們不圍繞Developer Studio來進行學習,就不能有效地使用Visual C++。其中包含:C++編譯器、調試器、應用程序框架生成器、項目管理器、設計和實現(xiàn)菜單等資源的編輯器等等內(nèi)容[2]。</p><p> 為了完成該軟件的編程的需要,第二個研究內(nèi)容是開發(fā)語言--Wi
23、n32,和MFC。所謂的Win32開發(fā),就是在C語言的層面上直接使用Win32 API(Application Programming Interface:系統(tǒng)開放出來,給程序員使用的接口。)來開發(fā)Windows應用程序或者系統(tǒng)程序。MFC是在1992年隨微軟的Microsoft C/C++ 7.0編譯器發(fā)布的,是建立在Windows API之上的C++類庫(C++ Class Library),意圖是使Windows程序設計過程更有效
24、率,更符合面向對象的精神。現(xiàn)在MFC已經(jīng)成為了Windows環(huán)境上標準的C++ API[3]。</p><p> 最后深入到軟件的功能:(1) 單人、多人之間的文本對話,這是任何一款通訊軟件所必須的功能。 </p><p> 方便高效的自動應答系統(tǒng),反應一個服務器的效率。</p><p> 可在任何形式局域網(wǎng)中
25、使用,一個軟件的開發(fā)后需要的是普及。</p><p> 操作簡捷、界面清新,直接影響使用著的情緒。</p><p> 2 功能描述和系統(tǒng)結構</p><p> 該程序的名稱為Chat Project,簡稱Chat。Chat的開發(fā)的平臺是winxp home edition、visiual studio 6.0。</p><p> 2.
26、1即時通訊系統(tǒng)的主要功能</p><p> 網(wǎng)路通信的經(jīng)典模式應該是客戶機/服務器模式,這程序也是采用這個模式。它包括了客戶端軟件和服務器軟件二個部分,在這里,對應于開發(fā)中建立的名為sever和client兩個工程。如下是各部分的功能介紹。</p><p><b> 客戶端:</b></p><p> 自由登錄(login)、登出(log
27、out)指定的chat服務器。</p><p> 以服務器上的在線人員的變動信息(用戶上線,下線)來修改本機保存的在線人員名單。</p><p> 用戶之間進行及時通信(發(fā)送、接受文本信息)。</p><p><b> 服務器:</b></p><p> ?。?) 啟動和終止服務。</p><
28、p> ?。?) 接受并驗證客戶端連接。</p><p> ?。?) 動態(tài)管理在線用戶名單。</p><p> ?。?) 為新登錄用戶提供本服務器在線人員名單。</p><p> ?。?) 將在線人員變動信息(用戶上線、下線)及時通知當前在線用戶。</p><p> 2.2即時通訊系統(tǒng)的結構</p><p&g
29、t; Chat 系統(tǒng)的結構如圖2-1所示。</p><p> Chat的客戶端通過實際的通信鏈路和Chat服務器建立TCP連接[4]。需要補充的是,Chat服務必須要有管理用戶信息(登錄用戶名、密碼等)的永久性存儲媒介,例如數(shù)據(jù)庫,但是在這個程序中,為了簡化程序把這部分就給刪減了。</p><p> 圖2-1 即時通訊系統(tǒng)的結構</p><p> 3通信協(xié)
30、議和報文格式</p><p> 通信協(xié)議指的是由應用程序定義的數(shù)據(jù)信息的解釋機制,是通信進程交流和溝通的一種“語言”。TCP/IP協(xié)議是一種“低級語言”,它定義的是指介入Internet的主機、路由器之間的信息溝通的方法。TCP/IP各層對數(shù)據(jù)是逐級封裝的,其中每一層都包括本層的數(shù)據(jù)和報文頭兩部分[5]。如UDP數(shù)據(jù)報。UDP、TCP數(shù)據(jù)報的數(shù)據(jù)部分是高層應用需要傳輸?shù)臄?shù)據(jù),這些數(shù)據(jù)的內(nèi)容需要應用程序之間定義的
31、“語言”—即用協(xié)議來解釋并執(zhí)行相應的操作。Chat的通信協(xié)議比較簡單,且數(shù)據(jù)報文都具有如下圖3-1所示的形式。</p><p> 下面詳細討論Chat中定義的各個命令及主要的通信時序。</p><p> 2byte </p><p> 圖3-1 Chat數(shù)據(jù)報文</p><p> 用戶登錄命令—100</p&
32、gt;<p> 這個是客戶端命令。這個命令是用戶用來向服務器發(fā)送登錄信息的命令。這個命令的數(shù)據(jù)包中的數(shù)據(jù)部分是一個包含用戶登錄信息的結構。這個結構主要包含了用戶名和密碼兩部分。</p><p> 用戶登出命令—101</p><p> 它是客戶端命令。該命令用來通知服務器使用戶登出,服務器在收到此命令后向該客戶端發(fā)送一個包含此命令且沒有數(shù)據(jù)的確認數(shù)據(jù)包。客戶端在收到此確
33、認數(shù)據(jù)包之后就可以關閉連接了。它的數(shù)據(jù)包中的數(shù)據(jù)部分是一個包含用戶信息的結構。用戶信息包括用戶名、用戶的IP地址和端口號三個方面</p><p><b> 字符串消息—102</b></p><p> 這個是客戶端命令。該命令指示在Chat數(shù)據(jù)包部分的數(shù)據(jù)是—個"\0"結尾的字符串。事實上,102號命令是僅用于Chat客戶端之間的通信的。服務器
34、和客戶端相互發(fā)送字符串的消息的功能在Chat中是并沒有定義的。在這里規(guī)定,發(fā)送的字符串長度不能4KB。</p><p> 用戶信息列表命令—200</p><p> 這個是服務器端命令。該命令指示數(shù)據(jù)包中的數(shù)據(jù)是一個用戶信息的列表。數(shù)據(jù)包在新用戶登錄并通過驗證后,再由服務器端發(fā)送到新用戶的客戶端。該命令的數(shù)據(jù)包格式如圖3-2所示。</p><p> 圖4-2
35、圖3-1 用戶信息的數(shù)據(jù)包</p><p> 新用戶加入命令—201</p><p> 它是服務器端的命令。該命令指示數(shù)據(jù)包中的數(shù)據(jù)是指新增加的用戶信息。該命令用于在新的用戶登錄并通過驗證后,來通知其他在線用戶該用戶己上線,客戶端在收到該命令后應把數(shù)據(jù)包的新用戶信息添加到自己的用戶列表中。其結構和用戶登出命令結構大致相同。</p><p> 用戶退出命令—20
36、2</p><p> 這個是服務器端命令。該命令指示數(shù)據(jù)包中的內(nèi)容時,離開本服務器的用戶信息。在用戶向服務器發(fā)出登出請求時,服務器會以此用戶的信息通知其他在線用戶從用戶列表中刪除此用戶的信息。其結構也和用戶登出命令結構大致相同。</p><p> 確認用戶登出命令—203</p><p> 這個是服務器端命令。這個命令沒有數(shù)據(jù)部分,用于在收到用戶的登出命令時發(fā)
37、送給用戶以表示確認,然后用戶就可以關閉連接了。</p><p> 服務器關閉命令—204</p><p> 這個是服務器端命令。該命令也無數(shù)據(jù)部分。它用于在服務器即將關閉時通知當前在線用戶服務器將停止服務,并要求客戶端斷開連接。</p><p><b> 用戶登錄時序</b></p><p> 用戶登錄時序如圖所
38、示。見圖3-3。</p><p> 客戶端先向服務器發(fā)出登錄命令,服務器對應客戶端做出反應,向客戶端發(fā)回當前在線用戶列表,并同時向其他用戶端發(fā)出用戶上線命令。</p><p><b> 用戶登出時序</b></p><p> 用戶登出時序如圖所示。見圖3-4。</p><p> 客戶端先向服務器發(fā)出登出命令,服務
39、器對應客戶端做出反應,確認登出,并同時向其他用戶端發(fā)出用戶離線通知。</p><p> 圖3-3 登錄時序 圖3-4 登出時序 </p><p><b> 4結構、類型和宏</b></p><p> Chat的Client和Server在這里共同使用了一
40、個定義了Chat程序間通訊所需求的結構、類型和宏的頭文件,該頭文件的名稱是Commom.h,具體內(nèi)容如下[6]。</p><p> //: Common.h -- 定義了程序所需的數(shù)據(jù)結構和宏</p><p> #include "StdAfx.h"</p><p> #ifndef COMMON_H_</p><p&g
41、t; #define COMMON_H_</p><p><b> // 用戶登陸信息</b></p><p> typedef struct tagLoginInfo {</p><p> char name[32];</p><p> char password[32];</p><p
42、> } LOGIN_INFO;</p><p><b> // 用戶信息</b></p><p> typedef struct tagUserInfo {</p><p> charname[32];</p><p> u_longaddr; // IP addr</p><p&
43、gt; u_short port; // port num</p><p> } USER_INFO;</p><p><b> // 數(shù)據(jù)包格式</b></p><p><b> /*</b></p><p> typedef struct tagPackage {</p>
44、<p> WORDtype; // packge type</p><p> LPVOIDpData; // 數(shù)據(jù) </p><p> } PACKET_TYPE;</p><p><b> */</b></p><p> typedef WORDPACKET_TYPE;</p>
45、<p> // PACKET_TYPE 取值如下:</p><p> #define PACKAGE_LOGIN100</p><p> #define PACKAGE_LOGOUT101</p><p> #define PACKAGE_USERLIST200</p><p> #define PACKAG
46、E_USERADD201</p><p> #define PACKAGE_USERDEL202</p><p> #define PACKAGE_MESSAGE203</p><p> #define PACKAGE_SERVERCLOSE 204</p><p> #endif //COMMON_H_</p>
47、;<p> 5 Chat的UI設計</p><p> Chat的客戶端和服務器端的UI設計的全部利用MFC現(xiàn)有的與界面有關的類,以力求簡潔大方。Chat服務器端是SDI窗口,采用了CListView作為顯示視圖,程序運行的實際界面如圖5-1。 </p><p> 在列表視圖當中,顯示了服務器運行的相關信息,其中最主要是服務器的啟動、終止和用戶的變動信息。</p&g
48、t;<p> Chat的客戶端是一個對戶框應用程序,它主要包括一個顯示信息的CEdit控件和一個編輯發(fā)送消息的CEdit控件。Client實際運行的界面如圖5-2。</p><p> Client中的CComboBox控件則用于保存當前在線的用戶名字,當用戶選擇一項時,對應的IP和端口號便顯示在其右邊的CStatic控件當中。最下邊的兩個CButton控件分別是用于發(fā)送和取消編輯的消息。<
49、/p><p> 圖5-1服務器運行界面</p><p> 圖5-1客戶端運行界面</p><p> 6 Chat主要的類及其關系</p><p> 對于服務器端而言,一般在用于監(jiān)聽連接的套接字上只注冊FD—ACCEPT事件,通常稱為“監(jiān)聽套接字”,對于為某個特定的客戶端進程提供服務的套接字稱為“數(shù)據(jù)套接字”,它們的行為是不同的。面向對象的
50、編程觀念提供了一個區(qū)分它們的概念——類。因此,服務器端設計了兩個類--監(jiān)聽套接字類和數(shù)據(jù)套接字類。而客戶端存在一個服務器通信的套接字,這里把它設計成面向連接的。另外,為了和其他用戶的通信,客戶端還包括一個無連接的套接字,和不同用戶的通信可以共用一個UDP端口[7]。以下分別介紹Client和Server使用的主要類及其成員。 </p><p> 6.1 CClient類</p><p&g
51、t; 1 CClientDlg類</p><p> CClientDlg類是Client端的主對話框類,它主要負責連接信息、用戶信息的保存和在線人員信息的維護,另外,它還要處理用戶的菜單及其他UI控件命令。它的主要數(shù)據(jù)成員如下:</p><p> CClientSocket*m_pSocket; //和服務器通信的Socket類</p><p> CC
52、hatSocket* m_pChatSock; //和其他用戶通信的Socket類</p><p> CList<USER_INFO*, USER_INFO*>m_UserList; // 其他在線用戶信息鏈表</p><p> CStringm_strUserName;//用戶登錄名</p><p> CStringm
53、_strPassword; //用戶登錄密碼</p><p> CStringm_strHostAddr;//服務器IP地址</p><p> UINT m_uHostPort;//服務器端口號</p><p> BOOL m_bConnected;//是否連接到服務器</p><p> CEdit
54、 m_edtsState;//狀態(tài)窗口空間的MFC對象,由AppWizard通過DDX_Contorl生成</p><p> CClientDlg類同時提供了下面的方法:</p><p> BOOLAddNameList();//向CComboBox控件中添加用戶名列表</p><p> voidAddMessage(CStr
55、ing& message);// 向顯示信息的CEdit控件中添加消息</p><p> voidCreateChatSocket();//創(chuàng)建和其他用戶通信的socket類</p><p> voidAddUserInfo(USER_INFO* info) ;// 添加新的用戶信息</p><p> BOOLDelUserInfo(USER_I
56、NFO* info);//刪除info指定的用戶信息</p><p> //USER_INFO*FindUserInfo(SOCKADDR_IN& addr); //根據(jù)addr指定的地//址查找用戶信息刪除鏈表中所有用戶信息并更新相應的顯示以及菜單命令和//控件命令的處理器函數(shù)</p><p> voidResetUserInfo();</p><p
57、> CClientDlg類同時覆蓋了父類CAsyncSocket中的OnConnect()和Onreceive()的方法,并在相應的網(wǎng)絡時間發(fā)生時通過主窗口改變狀態(tài)信息的顯示。</p><p> 2 CClientSocket類</p><p> CClientSocket類是負責連接由CClientDlg數(shù)據(jù)成員指定的Chat服務器并解釋和處理來自服務器的Chat命令格式的數(shù)
58、據(jù)包。CClientSocket類只有一個數(shù)據(jù)成員。如下:</p><p> CClientSocket* m_pMainWnd;//主窗口的指針</p><p> 保留m_pMajnwnd指針的作用是用于通知主對話框根據(jù)到達socket的數(shù)據(jù)包做出相應的反應,此外,CClientSocket類包含了下列的方法:</p><p> int Sen
59、dLoginInfo();//向服務器發(fā)送登錄信息</p><p> void OnOffline(WORD wType);// 登出服務器,wType表示登出的緣由,取值包括PACKAGE—LOGOUT和PACKAG_SERVERCLOSED</p><p> void OnReceiveMessage();//收到來自服務器的PAKCAGE_-MESSAGE命令的數(shù)據(jù)包的處理函數(shù)&
60、lt;/p><p> void OnReceiveUserDel();//收到來自服務器的PACKAGE_USERD~I.命令的數(shù)據(jù)包的處理函數(shù)</p><p> void OnReceiveUserAdd();//收到來自服務器的FACKAGE_USERADD命令</p><p><b> 的數(shù)據(jù)包的處理函數(shù)</b></p>
61、<p> void OnReceiveUserList();//收到來自服務器的PACKAGE_USERLIST命令的數(shù)據(jù)包的處理函數(shù)</p><p> CClientDlg類同時覆蓋了父類CAsyncSocket中的OnConnect()和Onreceive()的方法,并在相應的網(wǎng)絡時間發(fā)生時通過主窗口改變狀態(tài)信息的顯示。</p><p> 3 CChatSocket類&
62、lt;/p><p> CChatSocket類負責和其他Chat客戶端的UDP通信。因此,它主要是發(fā)送和接收包含PACKAGE_MESSAGE命令的數(shù)據(jù)包[8]。cchatsocket類也僅有一個數(shù)據(jù)成員:</p><p> CClientDlg* m_pMainWnd;</p><p> CClientSocket并覆蓋了父類CAsyncSocket類的O
63、Nreceive()方法。</p><p> 4 cclientapp類和clogindlg類</p><p> CClientApp是Client的應用程序類,CLoginDlg是用戶輸入登錄信息對話框的類。它們較為簡單。CLoginDlg類的對話框界面如圖7-1所示。</p><p> 圖6-1客戶端登錄界面</p><p> 6
64、.2 Server類</p><p> Server是一個由VC的Appwizard生成的SDI應用程序。它主要包括下面這類。</p><p> 1 CServer類和CMainFrame類</p><p> CServerApp類是Server的應用程序類,CMainFrame類是程序的主窗口類,它們基本上維持了由AppWizard生成的代碼。</p&
65、gt;<p> 2 CServerDoc類</p><p> CServerDoc類是Server SDI的Document類,從Document/view結構的觀點出發(fā),他它是處理邏輯和存放數(shù)據(jù)的地方[8]。在Server程序中,CServerDoc類的主要作用是:</p><p> 1.維護在線用戶信息的鏈表。</p><p> 2.管理監(jiān)
66、聽套接字對象。</p><p> 3.響應用戶的菜單命令。</p><p> CServerDoc主要包括下面的數(shù)據(jù)成員:</p><p> BOOLm_bStarted; //服務器是否啟動</p><p> UINTm_uPortNum; //監(jiān)聽端口號</p><p> CListenSoc
67、ket*m_pListenSocket; //監(jiān)聽套接字指針</p><p> List<USER_INFO, USER_INFO> m_lstUserInfo; // 用戶信息鏈表</p><p> 以及下面的成員方法:</p><p> void AddUserInfo(USER_INFO& info);//添加info表示的用戶信息
68、</p><p> void RemoveUserInfo(USER_INFO& info);//刪除info表示的用戶信息</p><p> USER_INFO*LookupInfo(UINT IP, UINT port);//根據(jù)IP和Port查找用戶信息</p><p> BOOL AlterUser(WORD type, USER_INFO*
69、 pInfo, CDataSocket* pFrom);</p><p> //type取值為PACKGE_USERADD或PACKAGE_USERDEL,用于表示根據(jù)在</p><p> //pFrom表示的數(shù)據(jù)套接字收到的type類型的PInfo信息是根據(jù)Document</p><p><b> //的數(shù)據(jù)</b></p>
70、;<p> voidSendUserListTo(USER_INFO& userInfo, CDataSocket* pSocket);</p><p> //向PSocket連接的客戶端發(fā)送用戶信息列表,該用戶的信息用userInfo表示</p><p> voidCloseDataSocket(CDataSocket* pSock);//關閉pSoc
71、k表示的數(shù)據(jù)套接字</p><p> afx_msg void OnNetworkStart();//啟動服務器命令的處理函數(shù)</p><p> afx_msg void OnAppExit();//退出應用程序命令的處理函數(shù)</p><p> afx_msg void OnNetworkTerminate();//終止服務器命令的處理函數(shù)</p>
72、<p> 需要說明的是,CServerDoc類不直接負責未關閉的數(shù)據(jù)套接字的管理工作,這部分工作交給監(jiān)聽套接字來完成。</p><p> 3 CServerView類</p><p> CServerView類是Server SDI的view類,它負責數(shù)據(jù)的顯示工作,CServerView類的功能較為簡單。</p><p> 4 CListen
73、Socket類</p><p> CListenSocket類是監(jiān)聽套接字的C++封裝,它派生自CAsyncSocket類。CListenSocket類主要負責維護為客戶連接服務的數(shù)據(jù)套接字[9]。它包括下面的數(shù)據(jù)成員:</p><p> CList<CDataSocket*, CDataSocket*> m_lstDeadSock;//數(shù)據(jù)套接字鏈表</p>
74、<p><b> 和下面的方法成員:</b></p><p> BOOL SendPackageToAll(char* buf, int buflen, CDataSocket* pFrom);//向所有(不包括pFrom)的活動套接字發(fā)消息</p><p> BOOL CloseDataSocket(CDataSocket* pSock);//關閉
75、數(shù)據(jù)套接字pSock</p><p> void CloseAllSocks();//關閉所有套接字</p><p> 在SListenSocket類中僅僅注冊了FD_ACCEPT網(wǎng)絡事件,數(shù)據(jù)收發(fā)的工作全部要由數(shù)據(jù)套接字完成。</p><p> 5 CDatasocke類</p><p> CDatasocke類數(shù)據(jù)套接字的C++封
76、裝,它派生自CAsyncSocket類。CDatasocke類主要負責和客戶端套接字的通信工作。它包括下面一些方法成員:</p><p> void OnReceiveMessage(); //接收客戶端PACkAGE_MESSAGE類型的數(shù)據(jù)包的</p><p><b> //處理函數(shù)</b></p><p> void OnRecei
77、veLogout();//接收客戶端PACkAGE_LOGOUT類型的數(shù)據(jù)包的</p><p><b> //處理函數(shù)</b></p><p> Void OnReceiveLogin(); //接收客戶端PACkAGE_LOGIN類型的數(shù)據(jù)包的處</p><p><b> //處理函數(shù)</b></p>
78、<p> 6 CServerlnfoDig類和CAboutDig類</p><p> CServerlnfoDig和CAboutDig類分別是程序中輸入服務器信息和顯示程序版權信息的對話框,它們的運行界面如圖6-2所示。</p><p> 圖7-2服務器信息對話框</p><p><b> 7 Chat的實現(xiàn)</b><
79、/p><p> 前面詳細地介紹了Chat的命令、時序、定義的類型和類,在這里將會展示Chat客戶端和服務器端的各個類主要的方法成員的實現(xiàn)代碼。</p><p> 7.1 CClient的實現(xiàn)代碼</p><p> CClirntDlg類的實現(xiàn)主要包括ClientDlg.h和ClientDlg.cpp兩個文件。下面是CClirntDlg主要的方法成員[10]。<
80、;/p><p> 1.構造函數(shù),初始化成員變量</p><p> CClientDlg::CClientDlg(CWnd* pParent /*=NULL*/)</p><p> : CDialog(CClientDlg::IDD, pParent)</p><p><b> {</b></p><
81、;p> //{{AFX_DATA_INIT(CClientDlg)</p><p> //}}AFX_DATA_INIT</p><p> // Note that LoadIcon does not require a subsequent DestroyIcon in Win32</p><p> m_hIcon = AfxGetApp()->
82、;LoadIcon(IDR_MAINFRAME);</p><p> m_bConnected = FALSE;</p><p> m_pSocket = NULL;</p><p> m_pChatSock = NULL;</p><p><b> }</b></p><p> 2.解
83、析函數(shù),清楚堆中分配的內(nèi)存</p><p> CClientDlg::~CClientDlg() </p><p><b> {</b></p><p> if (m_pSocket != NULL)</p><p> delete m_pSocket;</p><p> if (m_p
84、ChatSock != NULL)</p><p> delete m_pChatSock;</p><p><b> }</b></p><p><b> 3.初始化顯示</b></p><p> BOOL CClientDlg::OnInitDialog()</p><
85、;p><b> {</b></p><p> CDialog::OnInitDialog();</p><p> // Set the icon for this dialog. The framework does this automatically</p><p> // when the application'
86、;s main window is not a dialog</p><p> SetIcon(m_hIcon, TRUE);// Set big icon</p><p> SetIcon(m_hIcon, FALSE);// Set small icon</p><p> CString strInfo;</p><p>
87、 strInfo.Format(IDS_SERVINFO, "0.0.0.0", 0, "未");</p><p> SetDlgItemText(IDC_SERVINFO_STATIC, strInfo);</p><p> strInfo.Format(IDS_FRIENDINFO, "0.0.0.0", 0);<
88、/p><p> SetDlgItemText(IDC_FRIENDINFO_STATIC, strInfo);</p><p> return TRUE; // return TRUE unless you set the focus to a control</p><p><b> }</b></p><p>
89、 4.向組合框中加入名字列表</p><p> BOOL CClientDlg::AddNameList()</p><p><b> {</b></p><p> // Static 復位</p><p> CString strMsg;</p><p> strMsg.Format
90、(IDS_FRIENDINFO, "0.0.0.0", 0);</p><p> SetDlgItemText(IDC_FRIENDINFO_STATIC, strMsg);</p><p> if (m_UserList.GetCount() == 0)</p><p> return FALSE;</p><p>
91、; CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_NAMELIST_COMBO);</p><p> pCombo->ResetContent();</p><p><b> //清空</b></p><p> POSITION pos = m_UserList.GetHeadP
92、osition();</p><p> USER_INFO* pFirst;</p><p><b> //加入名字</b></p><p> for (int i = 0; i < m_UserList.GetCount(); i++)</p><p><b> {</b></
93、p><p> USER_INFO* pInfo = m_UserList.GetNext(pos);</p><p> if (i == 0) {</p><p> pFirst = pInfo;</p><p><b> }</b></p><p> pCombo->AddStrin
94、g(pInfo->name);</p><p><b> }</b></p><p> //默認情況下組合框中的內(nèi)容是指名字列表當中的第一項</p><p> pCombo->SetCurSel(0);</p><p> OnSelchangeNamelistCombo();</p>&
95、lt;p> return TRUE;</p><p><b> }</b></p><p> 5.刪除plnfo表示的信息</p><p> BOOL CClientDlg::DelUserInfo(USER_INFO* pInfo)</p><p><b> {</b></p
96、><p> // CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_NAMELIST_COMBO);</p><p> POSITION pos = m_UserList.GetHeadPosition();</p><p><b> //</b></p><p> for
97、 (int i = 0; i < m_UserList.GetCount(); i++)</p><p><b> {</b></p><p> POSITION t = pos;</p><p> USER_INFO* pTemp = m_UserList.GetNext(pos);</p><p> i
98、f (strcmp(pInfo->name, pTemp->name) == 0 &&</p><p> pInfo->addr == pTemp->addr &&</p><p> pInfo->port == pTemp->port) {// found it</p><p> m_Us
99、erList.RemoveAt(t);</p><p> delete pTemp;</p><p> // pCombo->ResetContent();</p><p> return TRUE;</p><p><b> }</b></p><p><b> }&l
100、t;/b></p><p><b> //</b></p><p> return FALSE;</p><p><b> }</b></p><p> 6.向m_edtState中加入新消息</p><p> void CClientDlg::AddMess
101、age(CString& message)</p><p><b> {</b></p><p> CTime t = CTime::GetCurrentTime();</p><p> CString strTime = "%m月%d日%h時%M分%S秒";</p><p> str
102、Time = t.Format(strTime);</p><p><b> //</b></p><p> CString strEdit;</p><p> m_edtState.GetWindowText(strEdit);</p><p> if (strEdit.IsEmpty()) {</p&g
103、t;<p> m_edtState.SetWindowText(strEdit + strTime + ": " + message);</p><p><b> }</b></p><p><b> else {</b></p><p> int len = strlen(str
104、Edit);</p><p> m_edtState.SetSel(len, len, TRUE);</p><p> m_edtState.ReplaceSel("\r\n" + strTime + ": " + message);</p><p> m_edtState.SetSel(len, len, TRUE);
105、</p><p><b> }</b></p><p><b> }</b></p><p> 7.“登陸”菜單命令的處理函數(shù)</p><p> void CClientDlg::OnNetworkLogin() </p><p><b> {</b
106、></p><p> if (m_bConnected) // if connected, logout first</p><p> OnNetworkLogout();</p><p><b> //登陸對話框</b></p><p> CLoginDlg dlgLogin;</p>&
107、lt;p><b> //</b></p><p> if (dlgLogin.DoModal() == IDCANCEL) {</p><p> TRACE0("cancel login");</p><p><b> return;</b></p><p><
108、;b> }</b></p><p><b> //提取相應的信息</b></p><p> m_strHostAddr = dlgLogin.m_strHostAddr;</p><p> m_uHostPort = dlgLogin.m_uHostPort;</p><p> m_str
109、UserName = dlgLogin.m_strUserName;</p><p> m_strPassword = dlgLogin.m_strPassword;</p><p> // 創(chuàng)建新的Socket并連接到服務器</p><p> m_pSocket = new CClientSocket(this);</p><p>
110、 if (!m_pSocket->Create()) {</p><p> TRACE0("failed to create client socket");</p><p><b> return;</b></p><p><b> }</b></p><p>
111、// connect to server</p><p> CString strMsg;</p><p> m_pSocket->Connect(m_strHostAddr, m_uHostPort);</p><p> // TRACE0("failed to connected to server\n");</p>
112、<p> //strMsg.Format(IDS_DISCONNECTED, m_strHostAddr, m_uHostPort);</p><p> //strMsg.Format(IDS_CONNECTED, m_strHostAddr, m_uHostPort);</p><p> //AddMessage(strMsg);</p><
113、p><b> }</b></p><p> 8.“登出”菜單命令的處理函數(shù)</p><p> void CClientDlg::OnNetworkLogout() </p><p><b> {</b></p><p> if (!m_bConnected)</p>&
114、lt;p><b> return;</b></p><p> // 向服務器發(fā)送登出消息</p><p> SOCKADDR_IN addr;</p><p> intlen = sizeof(addr);</p><p> m_pSocket->GetSockName((SOCKADDR*)
115、&addr, &len);</p><p> USER_INFO info;</p><p> strcpy(info.name, m_strUserName);</p><p> info.addr = addr.sin_addr.s_addr;</p><p> info.port = addr.sin_port;
116、</p><p> // padding infomation</p><p> const int bufLen = sizeof(WORD) + sizeof(USER_INFO);</p><p> static char buffer[bufLen];</p><p> *(WORD*)buffer = PACKAGE_LOG
117、OUT;</p><p> memcpy((void*)(buffer + sizeof(WORD)), (void*)&info, sizeof(info));</p><p> // send it</p><p> if (m_pSocket->Send((void*)buffer, bufLen, 0) <= 0) {</p&
118、gt;<p> TRACE0("Unable to send logout message.");</p><p><b> return;</b></p><p><b> }</b></p><p><b> }</b></p><p&
119、gt; 9.“退出”菜單命令的處理函數(shù)</p><p> void CClientDlg::OnNetworkExit() </p><p><b> {</b></p><p> if (m_bConnected) {</p><p> OnNetworkLogout();</p><p&
120、gt;<b> }</b></p><p> PostQuitMessage(EXIT_SUCCESS);</p><p><b> }</b></p><p> 10.名字列表組合框的選項改變的處理函數(shù),更新顯示</p><p> void CClientDlg::OnSelchange
121、NamelistCombo() </p><p><b> {</b></p><p> CString strSel;</p><p> CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_NAMELIST_COMBO);</p><p> pCombo->Get
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 基于vc的簡單即時通信軟件開發(fā)【畢業(yè)設計】
- 基于vc的簡單即時通訊軟件開發(fā)【文獻綜述】
- linux下基于c++語言開發(fā)的即時通信軟件畢業(yè)設計
- 基于vb的即時通信系統(tǒng)畢業(yè)設計
- 畢業(yè)設計---局域網(wǎng)即時通信軟件設計
- 畢業(yè)論文-開題報告-文獻綜述汽車銷售軟件開發(fā)
- 基于bs模式的即時通信軟件設計
- 安卓軟件開發(fā)--畢業(yè)設計開題報告安卓軟件文獻翻譯(精)
- 畢業(yè)設計(論文)-jsp簡單的即時通訊工具的設計與開發(fā)
- 即時通信工具安全性的設計與實現(xiàn)【文獻綜述】
- 基于web的簽章控件開發(fā)【開題報告+文獻綜述+畢業(yè)設計】
- 畢業(yè)論文--基于java的即時通信軟件設計與實現(xiàn)
- 畢業(yè)論文--基于java的即時通信軟件設計與實現(xiàn)
- 基于cs結構的即時通信系統(tǒng)的設計與實現(xiàn)畢業(yè)設計
- 基于無線通信的點菜系統(tǒng)軟件設計【畢業(yè)設計+開題報告+文獻綜述】
- 空調的設計與開發(fā)【開題報告+文獻綜述+畢業(yè)設計】
- 基于cs結構的即時通信系統(tǒng)設計與實現(xiàn)畢業(yè)設計
- 局域網(wǎng)即時通信軟件畢業(yè)論文
- 畢業(yè)論文---基于j2se的即時通信軟件
- 基于android平臺的手機游戲開發(fā)【畢業(yè)設計+開題報告+文獻綜述】
評論
0/150
提交評論