版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
編號畢業(yè)設(shè)計(jì)〔論文〕題目基于局域網(wǎng)的聊天工具的設(shè)計(jì)與實(shí)現(xiàn)二級學(xué)院專業(yè)班級學(xué)生姓名學(xué)號指導(dǎo)教師職稱時間
目錄摘要 IAbstract II1引言 11.1開發(fā)背景 11.2課題研究的意義 22系統(tǒng)概述 22.1國內(nèi)外開展現(xiàn)狀 22.2系統(tǒng)實(shí)現(xiàn)技術(shù) 32.2.1MFC窗口控件重繪 32.2.2Winsock編程 5基于UDP的文件傳輸 6多線程編程 7擴(kuò)展功能——廣域網(wǎng)聊天 83系統(tǒng)分析 93.1需求分析 93.2可行性分析 10技術(shù)可行性 10操作可行性 10經(jīng)濟(jì)可行性 10進(jìn)度可行性 113.3系統(tǒng)業(yè)務(wù)流程分析 11會員處理業(yè)務(wù)流程圖 113.4系統(tǒng)數(shù)據(jù)流程分析 12頂層數(shù)據(jù)流程圖 12第一層數(shù)據(jù)流程圖 12第二層數(shù)據(jù)流程圖 123.5系統(tǒng)數(shù)據(jù)模型 16系統(tǒng)E-R圖 163.5.2CDM圖 183.5.3PDM圖 194系統(tǒng)詳細(xì)設(shè)計(jì) 204.1系統(tǒng)功能設(shè)計(jì) 20主要功能模塊 20主要功能描述 214.2重要模塊的具體實(shí)現(xiàn) 23網(wǎng)絡(luò)通信的實(shí)現(xiàn) 23登陸驗(yàn)證模塊 29添加好友和參加群模塊 31基于UDP的文件傳輸模塊 32群聊天模塊 36網(wǎng)絡(luò)通信平安模塊 374.3數(shù)據(jù)設(shè)計(jì) 37數(shù)據(jù)庫設(shè)計(jì) 37數(shù)據(jù)結(jié)構(gòu) 394.4用戶界面設(shè)計(jì) 444.4.1用戶界面設(shè)計(jì)原那么 444.4.2登陸會員界面 484.4.3登陸驗(yàn)證界面 484.4.4已登陸界面 494.4.5修改個人資料界面 504.4.6查找好友/群的界面 514.4.7好友聊天界面 524.4.8群聊天界面 534.4.9好友信息界面 544.4.10簡潔模式界面 554.5代碼設(shè)計(jì) 565系統(tǒng)實(shí)施 675.1系統(tǒng)實(shí)施 67軟件開發(fā)工具的選擇 67開發(fā)平臺 67模式選擇 67程序設(shè)計(jì)與調(diào)試 675.2系統(tǒng)測試 685.3系統(tǒng)維護(hù) 686總結(jié) 69致謝 70參考文獻(xiàn) 71文獻(xiàn)綜述 72
摘要如今網(wǎng)絡(luò)的飛速開展,網(wǎng)絡(luò)世界這一概念早已不再陌生,正是因?yàn)榧磿r通訊軟件的誕生,網(wǎng)絡(luò)世界才蓬勃開展。即時通訊軟件給人們提供了一個交流的平臺,這種平臺逐漸衍生開展成為一種特殊的社區(qū),但是脫離這樣的社區(qū)就會影響到人們的正常生活,工作和學(xué)習(xí)。隨著通信,網(wǎng)絡(luò)的整合,即時通訊軟件將進(jìn)一步開展成為新一代的通訊軟件,有著巨大的開展前景。iMessaging局域網(wǎng)聊天軟件正是介于這樣的開展背景之下開發(fā)而成,后續(xù)將探索更為便捷,更多元化的聊天模式,隨著后期的逐步完善,將會提高人們學(xué)習(xí),辦公,交流的效率,提供更為直觀的聊天方式,開創(chuàng)聊天軟件的新局面。關(guān)鍵詞:聊天軟件,即時通訊
Abstract Today,withtherapiddevelopmentofthenetwork,thenetworkconceptisnolongernewtotheworld.Becauseofthebirthofinstantmessagingsoftware,precisely,theonlineworldwasbooming.Instantmessagingsoftwaretoprovidepeoplewithacommunicationplatformthatgraduallydevelopedintoaspecialkindofderivativeofcommunity,butfromsuchacommunitywillaffectpeople'snormallife,workandstudyandsoon.Ascommunications,networkintegration,instantmessagingsoftwarewillbefurtherdevelopedintoanewgenerationofcommunicationssoftware,hasgreatprospectsfordevelopment.iMessagingbetweenLANchatsoftwareisdevelopedunderthebackgroundthatmadethedevelopmentoffollow-uptoexploremoreconvenient,morediversifiedchatmode,withthegradualimprovementoflate,willincreasepeopletostudy,office,communicationefficiencyprovideamoreintuitivewaytochat,andchatsoftwaremustbearriveatanewsituation.Keywords:instantmessaging
1引言聊天工具的出現(xiàn),促進(jìn)了網(wǎng)絡(luò)社會的形成,人們的生活世界也逐漸的劃分為真實(shí)世界和虛擬世界。這里的虛擬世界就是指以網(wǎng)絡(luò)為載體的生活,人們通常并不需要知道對方是誰,也不需要了解網(wǎng)絡(luò)上的資源是誰提供的,便可以遨游于這個虛擬的世界,尋找屬于自己的天空。虛擬世界從某種程度上促進(jìn)了社會各個方面的開展,無論從經(jīng)濟(jì)上,文化上,教育上都有著舉足輕重的地位。而作為網(wǎng)絡(luò)社會的交通工具之一聊天工具扮演著極為重要的角色,它促進(jìn)了人們思想交流,加快了信息流通的速度,使這個信息化的世界高速的運(yùn)轉(zhuǎn)著。在社會方面,聊天工具提供了一個交流的平臺,就好比一個虛擬的社會,廣闊的使用者可以通過這個社會里暢所欲言,以特殊的方式營造出了一種社會屬性。在教育方面,聊天工具帶給我們新式的教學(xué)體驗(yàn),使在線文字,語音,視頻教學(xué)成為了可能,更重要的是,人們可以分享彼此的思想和經(jīng)驗(yàn),促進(jìn)精神和教育文化的開展。在工作方面,人們利用聊天室和聊天群招開工作會議,利用聊天工具的文件效勞實(shí)現(xiàn)文件共享和文件傳輸,提高了工作的效率。綜觀聊天工具的開展史,從單一的一對一聊天,到多對多的互動式聊天,聊天工具正在進(jìn)行了一場人類思想交流觀的革命。目前的主流聊天工具更是將工作、娛樂、購物整合在了一起,逐漸開展成了綜合化的聊天軟件。人們對聊天工具的開發(fā)與研究將不會懈怠,反而會更深入的探索其意義。在我看來,由于互聯(lián)網(wǎng)的飛速開展,其必定會整合通信行業(yè),而聊天工具將會取代,成為最流行普及的交流工具。1.1開發(fā)背景1970年早期,一種更早的即時通訊形式是柏拉圖系統(tǒng)(PLATOsystem)。在這之后在1980年,UNIX/Linux的交談即時通訊被廣泛的使用于工程師與學(xué)術(shù)界,1990年即時通訊更跨越了網(wǎng)際網(wǎng)路交流。1996年11月,ICQ是首個廣泛被非UNIX/Linux使用者用于網(wǎng)路的即時通訊軟體。在ICQ的介紹之后,同時在許多地方有一定數(shù)量的即時通訊方式開展,且各式的即時通訊程式有獨(dú)立的協(xié)定,無法彼此互通。這引導(dǎo)著使用者同時執(zhí)行兩個以上的即時通訊軟體,或者他們可以使用支援多協(xié)定的終端軟體,如Gaim、Trillian或Jabber。在中國,QQ是目前最主流的聊天軟件,具有龐大的用戶群體,功能具有多樣化。1.2課題研究的意義 研究該課題,具有重大意義,這對于今后研究網(wǎng)絡(luò)與通信融合具有指導(dǎo)作用。雖然目前的聊天軟件已經(jīng)具備強(qiáng)大多種的功能,并且支持廣域網(wǎng)的聊天,但是他們?nèi)匀淮嬖诟鞣N各樣的問題,如平安問題。雖然該課題僅僅包含了即時通訊軟件的簡單的功能,但對于后續(xù)的研究與開發(fā),有輔助作用。2系統(tǒng)概述iMeassaging即時通訊程序是基于windows下的聊天程序,采用Winsock實(shí)現(xiàn)網(wǎng)絡(luò)通訊,其設(shè)計(jì)架構(gòu)為集中式的P2P,即效勞器為中心,所有相關(guān)的核心數(shù)據(jù)全部存放在效勞器上,客戶端只能按照規(guī)定的方式讀取其數(shù)據(jù)。該軟件主要采用UDP協(xié)議,但某些特殊情況也采用了TCP協(xié)議。比方,命令消息和聊天消息均基于UDP協(xié)議,而獲取用戶列表那么采用的是TCP協(xié)議,兩種協(xié)議的混用更能保證客戶端與效勞器通訊時的效率和準(zhǔn)確性。iMessaging實(shí)現(xiàn)了在局域網(wǎng)下進(jìn)行個人聊天,群聊天,文件發(fā)送等的功能,其組成部份是客戶端和效勞器兩大局部。其中效勞器局部進(jìn)行對會員,群數(shù)據(jù)的增添,刪除,存儲,查詢等,并即時相應(yīng)客戶端發(fā)送而來的命令,進(jìn)行相關(guān)的數(shù)據(jù)讀寫,并返回客戶端相應(yīng)的命令消息??蛻舳司植磕敲词菍?shí)現(xiàn)用戶的操作界面,實(shí)現(xiàn)用戶間的聊天或者文件發(fā)送,以及群聊天等功能。2.1國內(nèi)外開展現(xiàn)狀隨著移動互聯(lián)網(wǎng)的開展,互聯(lián)網(wǎng)即時通信也在向移動化擴(kuò)張。目前,微軟、AOL、Yahoo、UcSTAR等重要即時通信提供商都提供通過接入互聯(lián)網(wǎng)即時通信的業(yè)務(wù),用戶可以通過與其他已經(jīng)安裝了相應(yīng)客戶端軟件的或電腦收發(fā)消息。即時聊天軟件最早的創(chuàng)始人是三個以色列青年,是他們在1996年做出來的,取名叫ICQ。1998年當(dāng)ICQ注冊用戶數(shù)到達(dá)1200萬時,被AOL看中,以2.87億美元的天價買走。目前ICQ有1億多用戶,主要市場在美洲和歐洲,已成為世界上最大的即時通信系統(tǒng)?,F(xiàn)在國內(nèi)的即時通信工具按照使用對象分為兩類:一類是個人IM,如:QQ,百度hi,網(wǎng)易泡泡,盛大圈圈,淘寶旺旺等等。QQ的前身OICQ在1999年2月第一次推出,目前幾乎接近壟斷中國在線即時通訊軟件市場。百度Hi具備文字消息、音視頻通話、文件傳輸?shù)裙δ埽赏ㄟ^它找到志同道合的朋友,并隨時與好友聯(lián)絡(luò)感情;另一類是企業(yè)用IM,簡稱EIM,如:E話通,UC,EC企業(yè)即時通信軟件,UcSTAR、商務(wù)通等。即時通信最初是由AOL、微軟、雅虎、騰訊等獨(dú)立于電信運(yùn)營商的即時通信效勞商提供的。但隨著其功能日益豐富、應(yīng)用日益廣泛,特別是即時通信增強(qiáng)軟件的某些功能如IP等,已經(jīng)在分流和替代傳統(tǒng)的電信業(yè)務(wù),使得電信運(yùn)營商不得不采取措施應(yīng)對這種挑戰(zhàn)。2006年6月,中國移動已經(jīng)推出了自己的即時通信工具——Fetion,中國聯(lián)通也將推出即時通訊工具“超信〞,但由于進(jìn)入市場較晚,其用戶規(guī)模和品牌知名度還比不上原有的即時通信效勞提供商。2.2系統(tǒng)實(shí)現(xiàn)技術(shù)2.2.1MFC窗口控件重繪MFC(MicrosoftFoundationClasses),是一個微軟公司提供的類庫〔classlibraries〕,以C++類的形式封裝了Windows的API,并且包含一個應(yīng)用程序框架,以減少應(yīng)用程序開發(fā)人員的工作量。其中包含的類包含大量Windows句柄封裝類和很多Windows的內(nèi)建控件和組件的封裝類。確實(shí),MFC給我們提供了很便捷的編程方式,我們幾乎可以不需要寫任何代碼就能生成一個帶有菜單,工具欄和視圖的窗口,MFC也提供了豐富的控件類,在設(shè)計(jì)對話框的時候,我們也只需要直接將控件拖進(jìn)對話框里,而不用寫任何代碼。iMessaging就是典型的MFC應(yīng)用程序,采用了MFC對話框設(shè)計(jì)框架,但是為了設(shè)計(jì)一個友好美觀的操作界面,僅用微軟提供的控件類庫達(dá)不到預(yù)期的效果,因此,就必須重新繪制其對話框和控件的界面。而正由于微軟將這些控件封裝得很好,對于要修改它的屬性,派生一些美觀的子控件難度就顯得比擬大。一般來說,實(shí)現(xiàn)對控件的重繪技術(shù)主要有子類化,自繪和重繪技術(shù),由于MFC框架太過于標(biāo)準(zhǔn)化,因此實(shí)現(xiàn)這些技術(shù)也是有一定的難度,這必須要對框架的結(jié)構(gòu)有一定的了解。iMessaging采用了的窗體背景重繪,listctrl自繪,按鈕貼圖等方式實(shí)現(xiàn)了操作界面的美觀。主要核心技術(shù)是GDI雙緩沖繪圖。雙緩沖繪圖就是將待繪制的圖片保存到內(nèi)存里,當(dāng)需要繪制到屏幕上時,再一次性投遞到設(shè)備描述表里,這樣既防止了窗口重繪時的閃爍,又提高了繪制的速度和效率。BOOLCDC::CreatieCompatibleDC(CDC*pDC)函數(shù)用來創(chuàng)立一個兼容DC,即在內(nèi)存里創(chuàng)立一個DC,以后的任何繪圖所需的操作,如選用何種畫筆,畫刷,字體等,都將在內(nèi)存中進(jìn)行,而不是在真實(shí)設(shè)備上下文里。隨后可以創(chuàng)立一張兼容位圖,需要繪制的圖像將,函數(shù)原型如下BOOLCBitmap::CreateCiompatibleBitmap(CDC*pDC,intnWidth,intnHeight)。最后需要將兼容DC里的東西投射到真實(shí)的DC里,BOOLBitBlt(HDChdcDest,intnXDest,intnYDest,intnWidth,intnHeight,HDChdcSrc,intnXSrc,intnYSrc,DWORDdwRop)函數(shù)可以實(shí)現(xiàn)該功能,具體用法可參考MSDN。對話框的繪制比擬容易,MFC為對話框提供了OnPaint消息相應(yīng)函數(shù),但是在該函數(shù)下繪制并不能從根本上重繪對話框,因?yàn)樵摵瘮?shù)還會調(diào)用CDialog::OnPaint函數(shù),在內(nèi)部還會再去重繪背景,因此要實(shí)現(xiàn)完全意義上的重繪背景,就必須響應(yīng)WM_ERASEBKGND消息,在消息響應(yīng)函數(shù)里實(shí)現(xiàn)我們自己的繪制方法,然后直接返回TRUE,不再調(diào)用CDialog::OnEraseBkgnd()函數(shù)。為了實(shí)現(xiàn)像QQ那樣的界面,必須將對話框的屬性設(shè)置為None屬性,即沒有標(biāo)題欄,因此只有自己去實(shí)現(xiàn)標(biāo)題欄的功能。CListCtrl重繪的方法有兩種,一種是采用微軟提供的OWNERDRAW屬性,通過重載DrawItem虛函數(shù)來進(jìn)行重繪。另外一種就是Custom-draw屬性,通過定義自繪消息響應(yīng)函數(shù)來進(jìn)行重繪。兩種方式有不同之處,前者需要對整個ListCtrl繪制,必須考慮到每一個item項(xiàng)的繪制情況。而后者相比照擬簡便,系統(tǒng)會在四個狀態(tài)的時候通知重繪,這四個狀態(tài)分別是繪制前,繪制后,擦除前,擦除后,我們就可以按照自己的需要去繪制,并且我們只用考慮其中一項(xiàng)item的繪制方法,就可以應(yīng)用于所有項(xiàng)。iMessaging采用了后者進(jìn)行對列表控件的重繪,實(shí)現(xiàn)了好友列表控件,群列表控件類。對于VC6開發(fā)環(huán)境,微軟提供的通用button控件的外觀從現(xiàn)在看來確實(shí)不太美觀,無法實(shí)現(xiàn)動態(tài)狀態(tài)的效果。那么因此就必須重新創(chuàng)立一個派生于CButton的按鈕類,由于該類將應(yīng)用于本軟件的所有按鈕控件,因此做成可貼狀態(tài)圖的按鈕控件最為適宜。狀態(tài)分為移出按鈕,懸浮按鈕,按下按鈕,禁用按鈕四種狀態(tài),我們只需要提供相應(yīng)的狀態(tài)的Bitmap就可以。具體重繪方法就是采用前面提到的OWNERDRAW屬性,重載虛函數(shù)DrawItem。而捕獲鼠標(biāo)的移入移出消息可以使用_TrackMouseEvent函數(shù),通過設(shè)置TRACEMOUSEEVENT結(jié)構(gòu)體的值來捕捉該消息。其移出消息對應(yīng)的是WM_MOUSELEAVE,移入按鈕消息是WM_MOUSEHOVER,分別定義其消息相應(yīng)函數(shù),這樣就能實(shí)現(xiàn)狀態(tài)的更替,再進(jìn)行相應(yīng)的繪制。2.2.2Winsock編程Windows下網(wǎng)絡(luò)編程的標(biāo)準(zhǔn)-WindowsSockets是Windows下得到廣泛應(yīng)用的、開放的、支持多種協(xié)議的網(wǎng)絡(luò)編程接口。它實(shí)現(xiàn)了標(biāo)準(zhǔn)socket編成的函數(shù),提供了一套屬于windows下的套接子API。其通信的根底是套接字〔Socket〕,一個套接字是通訊的一端。在這一端上你可以找到與其對應(yīng)的一個名字。一個正在被使用的套接字都有它的類型和與其相關(guān)的進(jìn)程。套接字存在于通訊域中。通訊域是為了處理一般的線程通過套接字通訊而引進(jìn)的一種抽象概念。套接字通常和同一個域中的套接字交換數(shù)據(jù)〔數(shù)據(jù)交換也可能穿越域的界限,但這時一定要執(zhí)行某種解釋程序〕。WindowsSockets標(biāo)準(zhǔn)支持單一的通訊域,即Internet域。各種進(jìn)程使用這個域互相之間用Internet協(xié)議族來進(jìn)行通訊〔WindowsSockets1.1以上的版本支持其他的域,例如WindowsSockets2〕。套接字可以根據(jù)通訊性質(zhì)分類;這種性質(zhì)對于用戶是可見的。應(yīng)用程序一般僅在同一類的套接字間通訊。不過只要底層的通訊協(xié)議允許,不同類型的套接字間也照樣可以通訊。用戶目前可以使用兩種套接字,即流套接字和數(shù)據(jù)報(bào)套接字。流套接字提供了雙向的,有序的,無重復(fù)并且無記錄邊界的數(shù)據(jù)流效勞。數(shù)據(jù)報(bào)套接字支持雙向的數(shù)據(jù)流,但并不保證是可靠,有序,無重復(fù)的。也就是說,一個從數(shù)據(jù)報(bào)套接字接收信息的進(jìn)程有可能發(fā)現(xiàn)信息重復(fù)了,或者和發(fā)出時的順序不同。數(shù)據(jù)報(bào)套接字的一個重要特點(diǎn)是它保存了記錄邊界。對于這一特點(diǎn),數(shù)據(jù)報(bào)套接字采用了與現(xiàn)在許多包交換網(wǎng)絡(luò)〔例如以太網(wǎng)〕非常類似的模型。其中TCP協(xié)議就是基于流套接字,而UDP協(xié)議基于數(shù)據(jù)報(bào)套接字,iMessaing聊天程序主要基于UDP協(xié)議,而在特殊操作下又采用TCP協(xié)議保證其數(shù)據(jù)的可靠性。在設(shè)計(jì)階段,需分析該軟件適用于什么樣的地協(xié)議進(jìn)行通訊,還必須分析該系統(tǒng)應(yīng)該適合于何種套接字IO操作。目前,windows提供了多種套接字IO模型,如阻塞式IO,非阻塞式IO,事件IO,重疊IO〔可提醒IO〕,完成端口等,每一種IO模型都具有自身的優(yōu)勢和缺陷,其中完成端口可以到達(dá)目前windows平臺下最高IO性能。由于是基于UDP協(xié)議,并且考慮到在同一時間處理得命令并不會很大的情況,效勞器和客戶端均采用基于非阻態(tài)的IO模型實(shí)現(xiàn)命令的傳輸。windows提供了一個CAysncSocke異步套接字類,它是基于非阻塞模型,對Socket函數(shù)進(jìn)行了良好的封裝,CAsyncSocket::Create()有一個參數(shù)指明了你想要處理哪些Socket事件,你關(guān)心的事件被指定以后,這個Socket默認(rèn)就被用作了異步方式。CAsyncSocket的Create()函數(shù),除了創(chuàng)立了一個SOCKET以外,還創(chuàng)立了個CSocketWnd窗口對象,并使用WSAAsyncSelect()將這個SOCKET與該窗口對象關(guān)聯(lián),以讓該窗口對象處理來自Socket的事件(消息),然而CSocketWnd收到Socket事件之后,只是簡單地回調(diào)CAsyncSocket::OnReceive()等虛函數(shù)。所以CAsyncSocket的派生類,只需要在這些虛函數(shù)里添加發(fā)送和接收的代碼。因此介于微軟提供的強(qiáng)大類方法,就很容易實(shí)現(xiàn)數(shù)據(jù)的通信。2.2.3基于UDP的文件傳輸要實(shí)現(xiàn)文件傳輸?shù)姆绞接泻芏喾N,常用的方式就是像MSN那樣基于TCP的文件傳輸,這樣的傳輸很穩(wěn)定,可靠,容易實(shí)現(xiàn),但傳輸?shù)乃俣群托蕰葦M慢。為了提高傳輸速度,我們可以采用UDP協(xié)議來傳輸文件,由于UDP協(xié)議傳輸?shù)臄?shù)據(jù)不具有可靠性,在網(wǎng)絡(luò)環(huán)境差的地方很容易出現(xiàn)丟包,亂序等現(xiàn)象,直接采用UDP來傳輸文件是不行的,那么就必須采用某種算法對其傳輸?shù)目煽啃赃M(jìn)行保證。我們可以模仿TCP的通訊機(jī)制來實(shí)現(xiàn)可靠的UDP傳輸。實(shí)際上,TCP的三次握手確實(shí)讓通訊數(shù)據(jù)得到了有序,有效地保證,但是正是因?yàn)檫@樣繁瑣的數(shù)據(jù)驗(yàn)證,導(dǎo)致它傳輸大量數(shù)據(jù)效率低下,在TCP實(shí)現(xiàn)內(nèi)部,實(shí)際上是采用了窗口大小為1的滑動窗口算法進(jìn)行數(shù)據(jù)驗(yàn)證,因此,UDP可以借于此思想,采用滑動窗口算法和CRC冗余效驗(yàn)來保證數(shù)據(jù)的有效性,同時也會提高傳輸?shù)乃俣?。由于基于UDP的文件傳輸在網(wǎng)絡(luò)環(huán)境差的情況下可能會大量丟包,因此不斷重復(fù)發(fā)包會導(dǎo)致網(wǎng)絡(luò)擁塞〔TCP在內(nèi)部實(shí)現(xiàn)了流量控制,因此發(fā)生網(wǎng)絡(luò)擁塞可能性很小〕,這是其最大的缺陷。為了保證速度,就會造成網(wǎng)絡(luò)擁塞,為了網(wǎng)絡(luò)的暢通,就不能保證速度,兩種傳輸方式的各據(jù)優(yōu)劣勢。2.2.4多線程編程多線程編成是網(wǎng)絡(luò)編成的根底,幾乎所有的網(wǎng)絡(luò)編程都將涉及到多個線程的數(shù)據(jù)傳輸,并且還要實(shí)現(xiàn)界面和數(shù)據(jù)處理互不影響。多線程編成雖說是根底,但是卻是一個難點(diǎn),因?yàn)榫€程同步確實(shí)比我們想象的復(fù)雜得多。要理解多線程編成就必須從以下幾個方面理解:一、操作系統(tǒng)多任務(wù)概念;二、線程和進(jìn)程的聯(lián)系與區(qū)別;三、如何創(chuàng)立并管理銷毀一個線程;四、何謂線程同步,怎樣同步。什么是多任務(wù)概念?用通俗易懂的話就是幾個運(yùn)行的任務(wù)“同時〞進(jìn)行,比方Windows就是典型的多任務(wù)操作系統(tǒng),我們可以同時進(jìn)行聽歌,打游戲,聊QQ,在基于這種理念的系統(tǒng)感覺就像所有的程序在同時運(yùn)行一樣。但實(shí)際上在單CPU的機(jī)子上,這些程序并不是同時在運(yùn)行〔即便是在多CPU的電腦上,也不可能所有程序同時運(yùn)行〕,所有的程序都以某種調(diào)度算法,按照優(yōu)先級,依次獲取CPU時間,每當(dāng)一個程序獲得CPU時間后,它就會得到運(yùn)行,而當(dāng)運(yùn)行一段時間后,操作系統(tǒng)會將其暫停,再接換新的線程來運(yùn)行。由于電腦的速度很快,這種非并發(fā)的模式卻可以到達(dá)類似并發(fā)的效果。實(shí)際上,正如前面所說,操作系統(tǒng)并非是給某一程序分配時間片,準(zhǔn)確的說是給這個程序里的某一線程分配了時間片。因此,在多任務(wù)操作系統(tǒng)中〔假設(shè)有線程的話〕,線程將是運(yùn)行的最小單位。在windows系統(tǒng)中,進(jìn)程和線程是最為重要的兩個概念,因?yàn)檎麄€系統(tǒng)就是基于進(jìn)程和線程的。那么進(jìn)程和線程有什么區(qū)別和聯(lián)系呢?進(jìn)程實(shí)際就是一個運(yùn)行的程序,該程序有自己的堆棧空間,有自己的線程〔至少有一個主線程〕,并且可以創(chuàng)立其它進(jìn)程或線程。有一個概念容易搞錯,就是進(jìn)程是否能獲得CPU時間片?實(shí)際上,進(jìn)程是無法獲取CPU時間片,只有該進(jìn)程里的線程才能,所以說,真正執(zhí)行代碼的是線程,而進(jìn)程只能管理線程,管理內(nèi)存等。在iMessaging程序里,涉及了諸多對線程的創(chuàng)立,管理和銷毀工作,特別是在效勞器局部,為了保證數(shù)據(jù)響應(yīng)的即時性,必須對每一個處理創(chuàng)立一個線程。常用的創(chuàng)立線程函數(shù)為CreateThread和_beginthreadex,兩函數(shù)功能幾乎一樣〔在某些特殊地方,兩者用法需注意,推薦用后者〕,在創(chuàng)立前必須定義一個按照線程函數(shù)原型的函數(shù),將其地址傳給創(chuàng)立線程函數(shù),讓操作系統(tǒng)知道即將從哪個地方運(yùn)行線程。除此之外,還可以傳遞參數(shù),供線程使用。假設(shè)創(chuàng)立成功,該函數(shù)會返回一個HANDLE,這個句柄標(biāo)示了剛創(chuàng)立的線程內(nèi)核對象,當(dāng)線程創(chuàng)立成功后,必須調(diào)用CloseHandle函數(shù)將其關(guān)閉,這是因?yàn)槿绻魂P(guān)閉該內(nèi)核句柄,當(dāng)線程退出后,操作系統(tǒng)并沒有銷毀該線程,造成資源浪費(fèi),這是因?yàn)楂@取一個實(shí)內(nèi)核句柄都會增加內(nèi)核使用計(jì)數(shù),只有當(dāng)該內(nèi)核對象的使用計(jì)數(shù)為0時,才會銷毀該內(nèi)核對象,線程也是如此。常用的銷毀線程函數(shù)是ExitThread,TermelateThread函數(shù),但推薦使用函數(shù)返回的方式結(jié)束進(jìn)程,因?yàn)椴僮飨到y(tǒng)會自動調(diào)用ExitThread函數(shù),并回收分配的內(nèi)存資源。由于多個線程在同時運(yùn)行的時候,會對共享數(shù)據(jù)進(jìn)行訪問或修改,那么就必須要注意數(shù)據(jù)同步,windows給我們提供了多種數(shù)據(jù)同步的方法,比方基于用戶模式的原子鎖,臨界區(qū),Slim讀寫鎖等,還有基于內(nèi)核模式的內(nèi)核對象,如互斥對象,事件對象,信號量,條件變量等。在iMessaging聊天程序中,最常用的是臨界區(qū),原因是基于用戶模式,同步效率快,效勞器可以進(jìn)行更多的操作,其次還用到了事件對象,由于臨界區(qū)太過單一的功能,并不能滿足有些數(shù)據(jù)同步的需要,因此用到了功能強(qiáng)大的事件對象,在MFC中,事件對象被封裝成了CEvent類,在SDK下,可以用調(diào)用CreateEventAPI函數(shù)創(chuàng)立一個事件對象。2.2.5擴(kuò)展功能——廣域網(wǎng)聊天由于該課題是基于局域網(wǎng)的聊天軟件,那如何實(shí)現(xiàn)廣域網(wǎng)的聊天呢?實(shí)際上,在廣域網(wǎng)中實(shí)現(xiàn)基于UDP的聊天功能幾乎不可能,那是因?yàn)榇蠖鄶?shù)的電腦用戶在其小型網(wǎng)內(nèi)都會有一道NAT屏障擋住,由于UDP是不可靠的,NAT發(fā)現(xiàn)當(dāng)前IP和端口是不可信任的,那么就會將該數(shù)據(jù)包擋在墻外,這樣就無法實(shí)現(xiàn)聊天功能。那么為了解決這個問題,就必須了解何謂信任的IP和端口。一般來講,只要發(fā)現(xiàn)該主機(jī)曾經(jīng)主動向該IP發(fā)送過信息,那么NAT會紀(jì)錄下來,并添加到任信列表里面去。由于iMessaging聊天程序的效勞器是所有客戶端的受信任者,因此,效勞器可以發(fā)送任何信息給客戶端。借于此功能,假設(shè)某一客戶端要與另一客戶端進(jìn)行聊天通訊,假設(shè)發(fā)現(xiàn)無法PING通對方,就可以借助效勞器的功能讓雙方正常通信,這就是UDP打洞技術(shù)。原理可以簡述為,假設(shè)客戶端A無法與另一客戶端B通訊,A可以向效勞器發(fā)送打洞請求,讓效勞器告知B客戶端A此時要與你進(jìn)行通訊,你必需將其A添加到你的受信任列表里。隨后,B就會發(fā)送一個消息到A,NAT發(fā)現(xiàn)此行為,自動將A添加到B的受信列表中,這樣就可以實(shí)現(xiàn)正常的通訊了。iMessaging在客戶端聊天模塊局部添加了該功能,但由于效勞器環(huán)境的限制,暫時沒有測試環(huán)境。3系統(tǒng)分析3.1需求分析根據(jù)現(xiàn)目前聊天軟件的普遍功能優(yōu)勢和缺點(diǎn),以及用戶體驗(yàn)所反映的情況,總結(jié)歸納出以下幾點(diǎn)需求分析。注冊會員。任何非會員都可以登陸注冊界面注冊一個自己的iMessaging賬號,今后就可以通過該帳號登陸iMessaging進(jìn)行聊天。注冊時填寫根本信息,注冊成功后效勞器會返回一個唯一的iM賬號。添加好友。會員可以通過查詢iM會員,添加自己的好友,成為好友后,兩會員便可以自由的通訊,還可以實(shí)現(xiàn)后續(xù)的多種功能。好友聊天。會員可以與自己所有的好友進(jìn)行聊天,同時可以翻開多個好友的對話框窗口進(jìn)行文本聊天。文件傳輸。好友與好友之間可以互相傳送文件,同時可以發(fā)送多個文件。創(chuàng)立新群。會員有創(chuàng)立新群的功能,創(chuàng)立新群后,自身默認(rèn)為該群的管理員。參加群。非群會員可以申請參加某個已存在的群,假設(shè)該群的管理員批準(zhǔn)了該申請,該會員便成為該群的一員。群聊天。群里的所有成員的聊天都是公開的,即該群所有成員能看到群里所有的發(fā)送的消息。發(fā)送離線消息。假設(shè)發(fā)送的好友當(dāng)時處于離線狀態(tài),發(fā)送的內(nèi)容或請求將保存在效勞器里,待該好友登陸后,再發(fā)送過去。3.2可行性分析技術(shù)可行性iMessaging聊天軟件是基于windows平臺下的應(yīng)用軟件。開發(fā)該軟件,應(yīng)具備一定的windows編成根底,熟悉常用的API函數(shù),深入了解MFC框架和窗口重繪技術(shù)。除此之外,必須深入理解socket編程,能熟練編寫基于tcp,udp的網(wǎng)絡(luò)通信。另外,還應(yīng)具備多線程編程,線程同步,數(shù)據(jù)庫操作的根本知識和技術(shù)。本人在大一時開始學(xué)習(xí)windows編程,大二時做過網(wǎng)絡(luò)通信演示的工程,大四實(shí)習(xí)時也是做的windows工程,通過三年的學(xué)習(xí)與積累對MFC框架設(shè)計(jì)有深入認(rèn)識,并熟悉windows內(nèi)存管理結(jié)構(gòu),DLL編程,網(wǎng)絡(luò)編程,多線程編程等,能熟練編寫基于windows下的應(yīng)用程序,能夠獨(dú)立完成iMessaging的設(shè)計(jì)和編碼。因此,在技術(shù)上是可行的。操作可行性iMessaging的操作界面是借鑒QQ界面設(shè)計(jì)而成,操作習(xí)慣完全符合于現(xiàn)在的網(wǎng)絡(luò)聊天用戶。界面簡潔,大方,美觀,操作簡單,便捷。在查看好友發(fā)送得消息上,創(chuàng)立了信息提示欄面板,給用戶更友好的操作方式,具有操作可行性。經(jīng)濟(jì)可行性在開發(fā)本錢上,除了在設(shè)計(jì)界面上,制作圖片上可能需要專業(yè)的人士進(jìn)行制作,會造成一定的經(jīng)濟(jì)開銷。后期效勞器升級,維護(hù)需要一定的資金。假設(shè)僅局限在局域網(wǎng)里使用本軟件,那經(jīng)濟(jì)本錢較低,具有經(jīng)濟(jì)可行性。進(jìn)度可行性鑒于本軟件的目標(biāo)要求和特點(diǎn),以及工作量評估,能夠保證在預(yù)期的時間內(nèi)完成該聊天軟件的設(shè)計(jì)和開發(fā)。3.3系統(tǒng)業(yè)務(wù)流程分析業(yè)務(wù)流程圖的圖形表示的意義:3.3.1會員處理業(yè)務(wù)流程圖圖3.1會員處理業(yè)務(wù)流程圖
3.4系統(tǒng)數(shù)據(jù)流程分析頂層數(shù)據(jù)流程圖圖3.2數(shù)據(jù)總流程圖3.4.2第一層數(shù)據(jù)流程圖圖3.3iMessaging會員操作數(shù)據(jù)流程圖3.4.3第二層數(shù)據(jù)流程圖1.會員登陸數(shù)據(jù)流程圖圖3.4會員登陸數(shù)據(jù)流程圖2.注冊會員數(shù)據(jù)流程圖圖3.5注冊會員數(shù)據(jù)流程圖
3.添加好友數(shù)據(jù)流程圖圖3.6添加好友數(shù)據(jù)流程圖4.參加群數(shù)據(jù)流程圖圖3.7參加群數(shù)據(jù)流程圖5.查詢好友數(shù)據(jù)流程圖圖3.8查詢好友數(shù)據(jù)流程圖6.查詢?nèi)簲?shù)據(jù)流程圖圖3.9查詢?nèi)簲?shù)據(jù)流程圖7.創(chuàng)立群數(shù)據(jù)流程圖圖3.10創(chuàng)立群數(shù)據(jù)流程圖
8.更新信息數(shù)據(jù)流程圖圖3.11更新會員信息數(shù)據(jù)流程圖9.群聊天數(shù)據(jù)流程圖圖3.12群聊天數(shù)據(jù)流程圖3.5系統(tǒng)數(shù)據(jù)模型系統(tǒng)E-R圖E-R圖的圖形表示的意義:圖3.13會員E-R圖圖3.14群E-R圖圖3.15群關(guān)系E-R圖圖3.16好友關(guān)系E-R圖圖3.17離線消息E-R圖圖3.18總體E-R圖3.5.2CDM圖圖3.19CDM圖3.5.3PDM圖圖3.20PDM圖
4系統(tǒng)詳細(xì)設(shè)計(jì)4.1系統(tǒng)功能設(shè)計(jì)4.1.1主要功能模塊1.效勞器功能模塊框架圖圖4.1效勞器功能模塊框架圖2.客戶端功能模塊圖4.2客戶端功能模塊框架圖4.1.2主要功能描述1.效勞器功能描述〔1〕登陸驗(yàn)證功能:當(dāng)客戶端發(fā)送了登陸驗(yàn)證命令后,效勞器會驗(yàn)證傳入的帳號和密碼是否為已注冊的會員,并返回驗(yàn)證后的信息?!?〕注冊會員:當(dāng)客戶端發(fā)送了注冊會員命令后,效勞器會添加注冊的信息到會員表里,并更新在線會員列表,同時返回會員帳號給客戶端?!?〕獲取好友或群信息:效勞器可以查詢會員表和群表信息,返回指定ID的信息。該功能主要用于獲取好友列表和群成員列表信息?!?〕添加好友:效勞器提供添加好友功能,主要啟到一個中介的功能,實(shí)現(xiàn)添加命令的轉(zhuǎn)發(fā)。假設(shè)添加成功,還會更新好友關(guān)系表?!?〕參加群:該功能同添加好友功能類似,效勞器會將參加請求發(fā)送到群管理員處,管理員的回應(yīng)也將被效勞器轉(zhuǎn)發(fā)回客戶端。假設(shè)成功參加該群,還會更新群成員表?!?〕發(fā)送離線消息:當(dāng)客戶端給未在線的好友發(fā)送消息或請求時,會將該消息或請求保存到數(shù)據(jù)庫里,待下次該好友上線后,將消息一次性發(fā)送過去?!?〕心跳功能:為了防止客戶端因非正常退出而導(dǎo)致效勞器誤認(rèn)為其還在線,客戶端會每隔一段時間向效勞器發(fā)送心跳命令,因此效勞器也會每隔一段時間檢測各在線會員是否按時發(fā)送心跳事件。假設(shè)發(fā)現(xiàn)某會員超時,強(qiáng)迫其下線,并通知他的所有好友。〔8〕UDP打洞效勞:當(dāng)客戶端無法正常與好友進(jìn)行通訊時,會請求效勞器進(jìn)行UDP打洞效勞,即是通知另一會員向該申請的好友IP和端口發(fā)生一個數(shù)據(jù)包,使其成為信任IP和端口。〔9〕創(chuàng)立IM群:客戶端發(fā)送創(chuàng)立信息,效勞器負(fù)責(zé)對群表進(jìn)行修改?!?0〕登陸離線日志功能:效勞器可以將所有用戶的登陸和離線的信息記錄到數(shù)據(jù)庫里,便于管理員進(jìn)行信息觀察2.客戶端功能描述〔1〕會員登陸:要想使用iMessaging進(jìn)行聊天,就必須在登陸界面進(jìn)行會員登陸,客戶端會發(fā)送驗(yàn)證的帳號和密碼給效勞器,假設(shè)驗(yàn)證通過,就能登陸進(jìn)該帳號,進(jìn)行后續(xù)的效勞功能?!?〕注冊會員:假設(shè)第一次使用iMessaging,沒有iM帳號的話,可以在登陸界面下進(jìn)行注冊,客戶端會將待注冊的信息發(fā)送給效勞器處理,假設(shè)注冊成功,用戶會得到一個iM帳號?!?〕創(chuàng)立IM群:在客戶端下,iM會員可以創(chuàng)立多個iM群,客戶端將待創(chuàng)立的信息發(fā)送給效勞器,效勞器返回創(chuàng)立信息。假設(shè)創(chuàng)立成功,客戶端能獲得一個唯一的iM群號?!?〕添加好友:iM會員能夠添加其他用戶為好友,通過對該用戶發(fā)送添加請求,假設(shè)該會員統(tǒng)一添加,兩會員便成為好友,更新好友列表,可以進(jìn)行好友間的功能?!?〕參加群:iM會員可以選擇參加任意的iM群,客戶端會發(fā)送請求給該群的管理員進(jìn)行驗(yàn)證,假設(shè)驗(yàn)證通過,該會員便成為該群的一員,并更新群成員列表?!?〕文件傳輸:好友與好友之間可以任意互相傳輸文件,并且同時支持多個文件的高速傳輸?!?〕好友聊天:好友與好友之間可以進(jìn)行基于文本的文字聊天?!?〕群聊天:好友能在自己所加的群里,進(jìn)行群聊天,其它人在群里的任何對話均能被接受到?!?〕退出登陸:iM會員退出登陸時將發(fā)送命令給效勞器,效勞器獲得退出命令后將更新在線列表,并通知所有該會員的好友,更新他們的好友在線列表。〔10〕查詢會員或群信息:iM會員可以通過查詢界面,查詢指定會員或群的信息?!?1〕UDP打洞請求:客戶端無法與另一客戶端進(jìn)行UDP通訊時,將向效勞器發(fā)送打洞請求。效勞器將打洞的結(jié)果返回給客戶端?!?2〕更改會員資料:可以更新自己的根本信息。〔13〕心跳功能:在線的客戶端能定期的向效勞器發(fā)送心跳命令,防止非正常結(jié)束iMessaging后導(dǎo)致的非法的登出。
4.2重要模塊的具體實(shí)現(xiàn)4.2.1網(wǎng)絡(luò)通信的實(shí)現(xiàn)1.基于UDP的數(shù)據(jù)發(fā)送與接收圖4.3效勞器與客戶端通信模型圖圖4.4效勞器與客戶端的通信圖〔1〕效勞器端的數(shù)據(jù)接收效勞器基于UDP的數(shù)據(jù)發(fā)送與接受主要采用的是MFC提供的CAsyncSocket類,該類提供了基于異步非阻塞式的IO操作。iMessaging程序里根據(jù)CAsyncSocket派生了一個CIMSocket類,效勞器用該類進(jìn)行數(shù)據(jù)的發(fā)送與接收,并將接收后的數(shù)據(jù)按照命令類型分發(fā)給各處理子模塊。創(chuàng)立該類在CIMessageDlg對話框類〔效勞器運(yùn)行的主窗口〕的OnInitDialog函數(shù)里,每當(dāng)程序運(yùn)行時都將自動調(diào)用該函數(shù),進(jìn)行對話框的初始化操作,這是將是創(chuàng)立CIMSocket類的最正確場所。該對話框類提供一個內(nèi)部接口函數(shù)BOOLCIMessageDlg::CreateUDPSocket(),用于創(chuàng)立CIMSocket類。當(dāng)CIMSocket類創(chuàng)立成功后,將其指針保存在對話框里保護(hù)類型成員變量里CIMSocket*m_pSocket,方便以后的使用。CIMSocket類重載了虛函數(shù)OnReceive用來接收網(wǎng)絡(luò)信息,該函數(shù)是一個系統(tǒng)自動調(diào)用的消息相應(yīng)函數(shù),每當(dāng)系統(tǒng)發(fā)現(xiàn)該套接字的接收緩沖區(qū)里有數(shù)據(jù)的時候,將調(diào)用該函數(shù),那么我們就可以在該函數(shù)里,調(diào)用RecvFrom或Recv來獲取數(shù)據(jù)。由于正是考慮到基于命令的信息傳輸,接收緩沖區(qū)里不一定時刻都有數(shù)據(jù)到來,那么采用了基于消息響應(yīng)的異步套接字類。在OnRecevie函數(shù)里,可能同時會有多個數(shù)據(jù)包到來,假設(shè)按照每到一個數(shù)據(jù)包進(jìn)行解析和分發(fā),將可能延誤整個接收處理過程,造成接收緩沖區(qū)溢出,喪失大量數(shù)據(jù)包,因此iMessaging在處理接收來的數(shù)據(jù)時,會先將接收到的數(shù)據(jù)包參加到一個數(shù)據(jù)包隊(duì)列里面去,用另一個獨(dú)立的接收線程讀取該隊(duì)列里的數(shù)據(jù)包,再根據(jù)其命令類型分發(fā)處理〔在iMessaging里封裝了一個CPacket類,用來存儲各種接收到的數(shù)據(jù)包〕。在接收線程里〔如圖4.6〕,會不斷的判斷數(shù)據(jù)包隊(duì)列里是否有數(shù)據(jù)到來,假設(shè)沒有數(shù)據(jù),那么進(jìn)入等待〔iMessaging里使用的時事件內(nèi)核對象,當(dāng)現(xiàn)在數(shù)據(jù)包隊(duì)列里沒有任何數(shù)據(jù)時進(jìn)入睡眠狀態(tài),這樣可以降低該線程因反復(fù)執(zhí)行判斷循環(huán)而造成占用大量CPU時候,當(dāng)OnRecevie里接收到一個數(shù)據(jù)后,就會將觸發(fā)事件對象,喚醒接收線程〕。假設(shè)發(fā)現(xiàn)有數(shù)據(jù)到來,那么分析數(shù)據(jù)包類型,創(chuàng)立相關(guān)的處理線程執(zhí)行相關(guān)的處理操作,這樣可以在同一時間同時處理多個任務(wù)請求,提高了效勞器的工作效率。程序執(zhí)行流程圖如下:圖4.5基于UDP的接收數(shù)據(jù)的程序流程圖圖4.6接收線程程序流程圖〔效勞器端〕〔2〕客戶機(jī)端的數(shù)據(jù)接收客戶端的接收流程與效勞器大致相同,同樣將UDP發(fā)送與接收封裝到一個CIMSocket類里〔這個類與前面的CIMSocket不是同一個〕。在程序啟動后同樣會在OnInitDialog里調(diào)用一個原型為BOOLCIMessagingDlg::CreateSocket(CStringszIP,UINT16nPort)的函數(shù)創(chuàng)立CIMSocket對象,接收原理與效勞器接收相同,同樣要提供一個數(shù)據(jù)包隊(duì)列,同樣要單獨(dú)創(chuàng)立一個接收線程進(jìn)行數(shù)據(jù)包的解析與分發(fā),唯一不同的是處理后的數(shù)據(jù)包并不單獨(dú)創(chuàng)立線程進(jìn)行處理,而是通過發(fā)送消息,將處理分發(fā)到各對應(yīng)的對話框里,自行處理。因?yàn)榭蛻舳酥饕筛鞣N類型的窗口構(gòu)成,而窗口本身就是一個線程,因此不會阻塞到接收線程的正常運(yùn)行?!步邮諗?shù)據(jù)流程圖參考圖4.6〕圖4.7接收線程程序流程圖〔客戶端〕〔3〕效勞器端的數(shù)據(jù)發(fā)送效勞器端的數(shù)據(jù)發(fā)送相比照擬簡單,除了在獲取好友列表和群成員時是基于TCP協(xié)議的數(shù)據(jù)傳輸,其余的均是基于UDP協(xié)議。因此在CIMSockt類中封裝了一個intCIMSocket::SendToClient(CPacket&packet)成員函數(shù),在需要發(fā)送數(shù)據(jù)的時候〔效勞器端大多在處理線程里回復(fù)數(shù)據(jù)給客戶端〕直接調(diào)用該公共成員函數(shù)即可。〔4〕客戶機(jī)端的數(shù)據(jù)發(fā)送客戶端的數(shù)據(jù)發(fā)送相對于效勞器端稍微要復(fù)雜一點(diǎn)。這是因?yàn)榭蛻舳瞬粌H需要發(fā)送給效勞器,還要處理發(fā)送給其他客戶端的情況,特別是在發(fā)送給客戶端的時候,假設(shè)在廣域網(wǎng)環(huán)境下還要進(jìn)行PING驗(yàn)證,假設(shè)PING失敗還需要向效勞器申請打洞效勞??蛻舳说腃IMSocket提供了兩個成員函數(shù)來進(jìn)行數(shù)據(jù)發(fā)送,一個是用來向效勞器發(fā)送數(shù)據(jù),函數(shù)原型為BOOLCIMSocket::SendInfo(void*lpData,intnBufLen)。另一個用來向其它客戶端發(fā)送數(shù)據(jù),函數(shù)原型為BOOLCIMSocket::SendToFriend(void*lpData,intnBufLen,DWORDnAddr,UINTnPort)。特別說明一下,文件傳輸?shù)墓δ懿]有封裝在CIMSocket里,它并不支持基于UDP的文件傳輸。2.TCP連接為了保證數(shù)據(jù)的可靠性,對于連續(xù)發(fā)送大量有序的數(shù)據(jù)包,采用UDP協(xié)議并不保險(xiǎn),因此在必要的時候,也必須采用TCP協(xié)議來支持?jǐn)?shù)據(jù)的穩(wěn)定和可靠性。在iMessaing里,由于獲取好友列表或獲取群成員時會連續(xù)發(fā)送大量的數(shù)據(jù),因此此時最好使用TCP協(xié)議進(jìn)行數(shù)據(jù)通信。圖4.8TCP接收請求處理流程圖〔效勞器端〕在效勞器端,iMessaging同樣是在主窗口的OnInitDialog里創(chuàng)立TCP連接,同樣提供了一個內(nèi)部接口函數(shù)BOOLCIMessageDlg::CreateTCPSocket()來創(chuàng)立TCP連接。由于有兩種情況需要用到TCP連接,因此分別設(shè)計(jì)了BOOLCreateTcpSocketToGetLoginUserInfo()和BOOLCreateTcpSocketToGetGroupMemberInfo()這兩個函數(shù)完成對應(yīng)的TCP創(chuàng)立工作。由于考慮到同時將會有多個獲取好友列表或群成員列表的請求,為了提高效勞器的響應(yīng)速度,也應(yīng)該為獲取好友列表和群成員分別創(chuàng)立一個線程來accept客戶端的請求連接。為了充分發(fā)揮多效勞器多CPU的特點(diǎn),在accept請求后效勞器會創(chuàng)立一個線程池來管理每個處理線程,線程池的最大線程數(shù)應(yīng)該等于CPU的個數(shù),這個是基于最大化提高CPU處理效率的特點(diǎn)而確定的,這是因?yàn)樯僖粋€線程,不能發(fā)揮到所有CPU的并發(fā)優(yōu)勢,假設(shè)多一個線程,同樣會等待CPU時間片,所以沒有必要。當(dāng)處理線程執(zhí)行結(jié)束后,不應(yīng)該立即退出,這樣會由于反復(fù)創(chuàng)立和銷毀線程而浪費(fèi)大量的CPU時間和資源。正確的做法應(yīng)該在完成處理后,查詢當(dāng)前是否有TCP連接請求未處理,假設(shè)有就讀取該請求數(shù)據(jù)進(jìn)行處理,這樣就防止了銷毀和創(chuàng)立線程時浪費(fèi)的時間,這個思想是基于完成端口的內(nèi)部實(shí)現(xiàn)原理而設(shè)計(jì)的。圖4.9TCP接收處理線程執(zhí)行流程圖〔效勞器端〕登陸驗(yàn)證模塊圖4.10登陸驗(yàn)證模塊實(shí)現(xiàn)原理圖iMessaing的會員登陸采用了UDP和TCP相結(jié)合的方式,涉及到地的對話框切換較多,登陸過程較為復(fù)雜。用戶輸入帳號和密碼,點(diǎn)擊登陸后,會響應(yīng)CIMessagingDlg主窗口的OnLogin函數(shù),該函數(shù)里創(chuàng)立了一個登陸對話框CIMLoginedDlg,該對話框主要起到一個會員登陸,并獲取登陸信息的作用。創(chuàng)立該對話框1秒之后,會開始向效勞器發(fā)送會員驗(yàn)證包,iMessaing定義的命令包主要采用結(jié)構(gòu)體的方式,每一個命令包都含有一個命名包頭和命令包數(shù)據(jù),其中頭部被定義為:structIM_Header{UINT32cmd;UINT16seg;UINT16id;UNT32reserved;}該結(jié)構(gòu)體的cmd字段便是命令,所有的命令被定義為宏,在IM_Protocol.h文件里。其中會員登陸的命令為IM_LOGIN,其值為0x0001,其他的命令將在后面會提到。登陸所發(fā)送的數(shù)據(jù)包被定義為了一個名為login_info的結(jié)構(gòu)體〔所有網(wǎng)絡(luò)通信用的結(jié)構(gòu)體均定義在了structinfo.h文件里〕,該結(jié)構(gòu)體除了包含命令頭部外,還包含了待登陸的賬號和密碼??蛻舳税l(fā)送了會員登陸命令后,便等待效勞器的回應(yīng)了,假設(shè)等待超時便提示連接失敗。在效勞器局部,通過前面描述的udp的接收流程,效勞器在接收到登陸請求后,最終會創(chuàng)立一個LoginThread線程來進(jìn)行登陸驗(yàn)證。在該線程中效勞器首先讀取數(shù)據(jù)庫進(jìn)行驗(yàn)證,所有的數(shù)據(jù)庫操作被封裝到了CSql類里,該類提供了一個公用方法,Excute,具體用法見代碼。驗(yàn)證后將返回信息給客戶端,在iMessaging里,幾乎所有由server回應(yīng)給客戶端的數(shù)據(jù)包結(jié)構(gòu)體被定義為XXX_back的名字,如登陸回應(yīng),用到了login_back結(jié)構(gòu)體。假設(shè)效勞器發(fā)現(xiàn)驗(yàn)證成功,并且當(dāng)前該會員沒有在其他處登陸過,那么就通知該會員所有的在線好友的上線通知,這里調(diào)用了CIMSocket::NotifyMember函數(shù)。圖4.11客戶端驗(yàn)證登陸流程圖當(dāng)效勞器執(zhí)行完登陸處理線程后,客戶端進(jìn)入接收流程,假設(shè)驗(yàn)證失敗,根據(jù)錯誤信息進(jìn)行錯誤提示,假設(shè)發(fā)現(xiàn)驗(yàn)證成功,便開始獲取登陸信息。iMessaging在獲取好友列表和群列表的時候用到了TCP短連接,客戶端會創(chuàng)立一個RecvInfoThread線程去接收數(shù)據(jù),在線程內(nèi)部會創(chuàng)立TCP套接字連接效勞器,并依次獲取群信息和好友信息。iMessaging在獲取好友信息時并不是全部獲取,除非是該計(jì)算機(jī)第一次登陸該賬號,因?yàn)樵诘顷懞?,客戶端會將登陸信息記錄在文件里,下次本機(jī)登陸時就可以直接從文件中獲取,加快登陸速度。在獲取完登陸信息后,將好友信息和群信息分別添加到g_fredAllList和g_groupList鏈表里,隨后便創(chuàng)立登陸后的用戶界面CIMLogonDlg對話框。在初始化該對話框時,會將之前獲取的信息參加到兩個CIMListCtrl里面〔登陸界面的列表控件〕,隨后會向效勞器發(fā)送離線消息請求,效勞器接收到消息后,會將保存在數(shù)據(jù)庫里的離線消息發(fā)送給該會員。當(dāng)客戶端接收完離線消息后,登陸過程完畢。添加好友和參加群模塊圖4.12添加好友流程圖在添加好友和參加群功能實(shí)現(xiàn)都大同小異,其中效勞器起到了中間紐帶的作用。其主要用到了add_friends_info命令數(shù)據(jù)包,命令為IM_ADD_FRIENDS。其次,該結(jié)構(gòu)含有一個子命令字段sub_cmd,表示現(xiàn)在發(fā)送到效勞器端的命令時請求,還是通知回復(fù)。添加好友被大致分為請求和通知回應(yīng)兩個階段,如上圖所示,上面局部就是添加好友的請求階段,下面部門就是通知回應(yīng)階段??蛻舳讼雀鶕?jù)待加好友特征查詢好友信息,假設(shè)有該好友,客戶端可以選擇添加該好友,隨后,客戶端會發(fā)送一個add_friends_info的數(shù)據(jù)包給效勞器,當(dāng)效勞器接收到該請求后,便進(jìn)入AddFriends線程進(jìn)行處理,首先效勞器會驗(yàn)證該好友是否在線,假設(shè)不在線,便發(fā)送離線請求〔保存在離線消息數(shù)據(jù)庫里〕,假設(shè)在線,將立即發(fā)送請求給待加好友。這個過程就是添加好友的請求階段。當(dāng)待加好友的客戶端接到好友申請后,用戶可以選擇同意或者拒絕,隨后又將回復(fù)的信息發(fā)送給效勞器,讓效勞器來回復(fù)起初申請?zhí)砑雍糜训目蛻舳?。此時,效勞器仍然調(diào)用了AddFriends線程進(jìn)行回應(yīng)申請者,同樣要先驗(yàn)證是否在線,假設(shè)在線便將信息發(fā)送回申請者。假設(shè)對方同意了,兩方客戶端都均更新好友列表,同時效勞器要更新好友關(guān)系表里的內(nèi)容。參加群的流程與添加好友的流程大致一樣,唯一的區(qū)別是效勞器在處理過程中創(chuàng)立JoinGroup線程來處理,在發(fā)送申請數(shù)據(jù)包的過程中,需要在數(shù)據(jù)庫中查詢?nèi)旱墓芾韱T,將申請轉(zhuǎn)發(fā)給管理員?;赨DP的文件傳輸模塊在系統(tǒng)實(shí)現(xiàn)技術(shù)章節(jié)介紹了基于UDP的文件傳輸?shù)拇蟾诺脑O(shè)計(jì)思想,現(xiàn)在就全面分析下在iMessaging里是如何實(shí)現(xiàn)基于多個任務(wù)的UDP文件傳輸。在iMessaging里,實(shí)現(xiàn)UDP文件傳輸?shù)暮诵拇a封裝到了CFiletransPageItem類里,該類實(shí)際上是一個chlid類型的面板對話框,依附在CSendFilePage類上。當(dāng)客戶端選擇發(fā)送文件請求后,將立即創(chuàng)立該類,同時會在對話框初始化代碼局部創(chuàng)立一個基于UDP的套接字,用于文件傳輸,該套接字的收發(fā)封裝到CIMUdpSendFileSocket類里,并采用阻塞式的IO模型。接著,客戶端會將文件名,文件大小和文件分塊數(shù)以及自己的ID號和剛創(chuàng)立的端口號填入send_file_request_info結(jié)構(gòu)體里,其中頭命令為IM_SEND_FILE_REQUEST_INFO,隨后用CIMSocket對象來發(fā)送該請求。接收請求的客戶端收到命令后,會創(chuàng)立一個CFiletransPageItem對象進(jìn)行文件傳輸,同時也創(chuàng)立一個專門用于該任務(wù)的套接字。假設(shè)用戶作了回應(yīng)行為,在CFiletransPageItem類中,就會發(fā)送send_file_request_info_back命令〔同樣用CIMSocket對象發(fā)送〕通知請求方是否開始文件傳輸。文件傳輸開始后,所有關(guān)于該文件的數(shù)據(jù)傳輸都發(fā)生在該CFiletransPageItem對象和CIMUdpSendFileSocket對象里。CIMUdpSendFileSocket對象負(fù)責(zé)數(shù)據(jù)的接收和發(fā)送,CFiletransPageItem對象負(fù)責(zé)UDP文件傳輸?shù)乃惴ê徒缑娌僮?。發(fā)送方會創(chuàng)立一個名為FileTransferThread的發(fā)送線程,不斷地向?qū)Ψ桨l(fā)送文件數(shù)據(jù)。發(fā)送文件的數(shù)據(jù)包結(jié)構(gòu)體為send_file_info,其中包含了IM_Header頭部和512B的文件數(shù)據(jù),其中該頭部的seg字段標(biāo)示著當(dāng)前發(fā)送到文件哪一塊,reserved標(biāo)志著文件的大小。接收方會創(chuàng)立一個名為RecvThread的接收線程和一個名為WriteToFileThread的寫文件線程。由于是UDP的文件傳輸,就要對數(shù)據(jù)進(jìn)行重組排序和重發(fā)驗(yàn)證,最好的方法就是用到滑動窗口的思想。因此,發(fā)送方需創(chuàng)立一個發(fā)送窗口,接收方需創(chuàng)立一個接收窗口。iMessaging將發(fā)送窗口定義為SendWindow結(jié)構(gòu)體其結(jié)構(gòu)如下:typedefstructSendWindow{ unsignedintnLastAckSeg; unsignedintnLastSendSeg; unsignedintnWidth;}SendWindow;接收窗口RecvWindow結(jié)構(gòu)體如下:typedefstructRecvWindow{ unsignedintnLastRecvSeg; unsignedintnAvaliableSegRecved; unsignedintnWidth;}RecvWindow;其中發(fā)送窗口中nLastAckSeg表示最近由接收段發(fā)送而來確實(shí)認(rèn)段的最大序號〔圖中用LAR表示〕,必須保證其小于該序號的所有段均得到確認(rèn);nLastSendSeg表示發(fā)送端最近發(fā)送的序號〔圖中用LFS〕;nWidth表示窗口大小〔圖中用SWS表示〕。發(fā)送端必須始終滿足nLastSendSeg-nLastAckSeg<=m_sendWindow.nWidth的原那么,假設(shè)發(fā)現(xiàn)某序號包在規(guī)定時間內(nèi)沒有得到ack,便重發(fā)該數(shù)據(jù)包,假設(shè)接收到確實(shí)認(rèn)包的序號recvSeg>nLastAckSeg+1的話,只能將此包拋棄或添加到一個數(shù)組中暫存起來,直到該序列號前面所有的序號都均接收到才將nLastAckSeg更新為recvSeg,原理圖如下。圖4.13發(fā)送窗口原理圖在接收窗口中,nLastRecvSeg〔圖中用NFE表示〕表示最近收到的最大段號,必須保證其小于該號的所有塊均已收到,nAvaliableSegRecved〔圖中用LFA表示〕表示可接收偵的序號,nWidth〔圖中由RWS表示〕是窗口大小,始終保證nAvaliableSegRecved–nLastRecvSeg<=nWidth的原那么。圖4.14接受窗口原理圖基于以上原理,CFiletransPageItem實(shí)現(xiàn)了該協(xié)議算法。在接收段,由于為了同步寫文件操作和接收文件,iMessaging封裝了一個CWriteBuffer緩沖區(qū)類作為同步紐帶,并提高了接收和寫的效率。圖4.15發(fā)送文件端的執(zhí)行流程圖圖4.16接收文件端的執(zhí)行流程圖群聊天模塊群聊天設(shè)計(jì)思路是讓效勞器轉(zhuǎn)發(fā)消息給所有群成員。文字流程如下:客戶端翻開群聊天窗口〔CGroupChatDlg〕,創(chuàng)立TCP短連接獲取群成員信息,并更新到群成員列表中??蛻舳嗽谌豪锇l(fā)送即時消息,程序內(nèi)部實(shí)際上發(fā)送了IM_GROUP_MSG命令給效勞器,效勞器接收到該命令后,創(chuàng)立SendGroupMsg處理線程。在該線程內(nèi)部,首先會調(diào)用CSql對象里的GetGroupMem函數(shù)來獲取該群的所有成員,其次將消息發(fā)送給在線的群成員,其余的按照離線消息處理。當(dāng)在線的群成員客戶端收到該消息后,判斷該群窗口是否翻開,假設(shè)未翻開,創(chuàng)立并顯示消息。網(wǎng)絡(luò)通信平安模塊為保證iMessaging通訊時的平安性能,iM在通訊的時候采用數(shù)據(jù)加密。加密算法利用DES(數(shù)據(jù)加密算法)來加密明文,以保證socket通信的平安性。DES加密算法的原理是DES使用一個56位的密鑰以及附加的8位奇偶校驗(yàn)位,產(chǎn)生最大64位的分組大小。這是一個迭代的分組密碼,使用稱為Feistel的技術(shù),其中將加密的文本塊分成兩半。使用子密鑰對其中一半應(yīng)用循環(huán)功能,然后將輸出與另一半進(jìn)行“異或〞運(yùn)算;接著交換這兩半,這一過程會繼續(xù)下去,但最后一個循環(huán)不交換。DES使用16個循環(huán),使用異或,置換,代換,移位操作四種根本運(yùn)算。DES是平安性比擬高的一種算法,目前只有一種方法可以破解該算法,那就是窮舉法.它采用64位密鑰技術(shù),實(shí)際只有56位有效,8位用來校驗(yàn)的.譬如,有這樣的一臺PC機(jī)器,它能每秒計(jì)算一百萬次,那么256位空間它要窮舉的時間為2285年.所以這種算法比擬平安的一種算法。除此之外,為了防止惡意軟件偽造命令包而大量傳輸數(shù)據(jù)包造成效勞器癱瘓,因此效勞器采用限制命令數(shù)的方法,也就是一段時間里只能接受幾條同樣的命令,假設(shè)發(fā)現(xiàn)某條命令反復(fù)發(fā)送或異常發(fā)送,便發(fā)送終止命令給客戶端,假設(shè)發(fā)現(xiàn)無法終止客戶端,那么強(qiáng)行屏蔽所有該IP和端口發(fā)來的消息包。效勞器是整個iMessaing的核心,假設(shè)效勞器癱瘓那么將影響到所有用戶的使用。4.3數(shù)據(jù)設(shè)計(jì)4.3.1數(shù)據(jù)庫設(shè)計(jì)數(shù)據(jù)庫名稱:iMessaging1.MemberInfo表,存儲了關(guān)于會員的所有信息。字段名類型是否為空會員號bigintNotNull密碼varchar(20)NotNull昵稱varchar(30)NotNull出生日期varchar(20)Null性別intNull國家varchar(20)NotNull地區(qū)varchar(20)Null年齡intNull職業(yè)varchar(20)Null學(xué)校varchar(40)Nullvarchar(20)Null電子郵箱varchar(50)Null其他信息varchar(100)Null最近更新時間bigintNotNull2.Friends_Relationship表,存儲了好友信息字段名類型是否為空會員號bigintNotNull好友號bigintNotNull3.GroupInfo表,存儲了群信息字段名類型是否為空群號bigintNotNull群名稱varchar(20)Null群管理員號bigintNotNull群描述varchar(320)Null最近更新時間bigintNotNull創(chuàng)立時間bigintNotNull4.GroupMem_Relationship表,存儲了群成員信息字段名類型是否為空群號bigintNotNull成員號bigintNotNull5.OfflineInfoRec表,用于記錄離線消息字段名類型是否為空發(fā)送時間BigintNotNull信息類別IntNotNull發(fā)送者號BigintNotNull待發(fā)好友號BigintNull待發(fā)群號BigintNull附加信息Varchar(320)Null4.3.2數(shù)據(jù)結(jié)構(gòu)4.3.2.1根本數(shù)據(jù)結(jié)構(gòu)1.?dāng)?shù)據(jù)包頭結(jié)構(gòu)structIM_Header{ UINT16cmd; UINT32id; UINT32seg; UINT32reserved;};2.用戶信息結(jié)構(gòu)typedefstructuser_baseinfo{ UINT32user_id; UINT8nick[MAX_NICK_LEN+1]; UINT8gender; UINT8age; UINT8country[MAX_COUNTRY_LEN+1]; UINT8province[MAX_PROVINCE_LEN+1]; UINT8birthday[MAX_BIRTHDAY_LEN+1]; UINT8email[MAX_EMAIL_LEN+1]; UINT8telephone[MAX_TEL_LEN+1]; UINT8college[MAX_COLLEGE_LEN+1]; UINT8profession[MAX_PROFESSION_LEN+1]; UINT8note[MAX_NOTE_LEN+1];}user_baseinfo;typedefstructusr_info{ user_baseinfouser_baseInfo; UINT32last_update_time;}usr_info;3.在線用戶信息結(jié)構(gòu)structusr_info_online{ UINT32user_id; UINT32IP; UINT16im_udp_port; UINT8status; //狀態(tài):在線=0,離線=1;};4.群信息結(jié)構(gòu)體structgroup_info_base{ UINT32group_id; UINT8name[MAX_NAME_LEN+1]; UINT8note[MAX_NOTE_LEN+1]; UINT32administrator_id; UINT32last_update_time;};5.內(nèi)存映射文件里的結(jié)構(gòu),用于存放從文件里讀取的用戶信息typedefstruct_MEMBER_FRIEND_DATA{ DWORDdwCount; usr_infouseInfo[1];}MEMBER_FRIEND_DATA,*PMEMBER_FRIEND_DATA;typedefstruct_MEMBER_GROUP_DATA{ DWORDdwCount; group_info_basegroup_info[1]; }MEMBER_GROUP_DATA,*PMEMBER_GROUP_DATA;4.3.2.2網(wǎng)絡(luò)通訊數(shù)據(jù)結(jié)構(gòu)1.客戶端所用到的數(shù)據(jù)結(jié)構(gòu)結(jié)構(gòu)體命令說明register_infoIM_ACCOUNT_REGISTER注冊會員命令結(jié)構(gòu)體login_infoIM_LOGIN登陸命令結(jié)構(gòu)體status_change_infoIM_STATUS_CHANGE更新會員在線狀態(tài)結(jié)構(gòu)體heartbeat_infoIM_HEARTBEAT心跳命令結(jié)構(gòu)體logout_infoIM_SEESION_LOGOUT會員登出命令結(jié)構(gòu)體search_friends_infoIM_SEARCH_FRIENDS查找好友命令結(jié)構(gòu)體add_friends_infoIM_ADD_FRIEND添加好友命令結(jié)構(gòu)體get_online_infoIM_GET_ONLINE_INFO獲取好友在線狀態(tài)信息結(jié)構(gòu)體create_group_infoIM_NEW_GROUP創(chuàng)立群命令結(jié)構(gòu)體join_group_infoIM_JOIN_GROUPS參加群命令結(jié)構(gòu)體search_group_infoIM_SEARCH_GROUP查找群命令結(jié)構(gòu)體set_infoIM_ACCOUNT_SET_INFO 更新會員信息命令結(jié)構(gòu)體send_msg_acceptIM_SEND_MSG_ACCEPT驗(yàn)證好友是否能正常通訊的命令結(jié)構(gòu)體send_msg_infoIM_SEND_MSG_CLIENT發(fā)送好友信息命令結(jié)構(gòu)體udp_hole_infoIM_UDP_HOLE_INFOUDP打洞信息命令結(jié)構(gòu)體group_msg_infoIM_GROUP_MSG發(fā)送群信息命令結(jié)構(gòu)體send_file_request_infoIM_SEND_FILE_REQUEST_INFO發(fā)送文件請求命令結(jié)構(gòu)體send_file_request_info_backIM_SEND_FILE_REQUEST_BACK發(fā)送文件回應(yīng)命令結(jié)構(gòu)體send_file_infoIM_SEND_FILE_INFO發(fā)送文件數(shù)據(jù)包命令結(jié)構(gòu)頭體send_file_cancelIM_SEND_FILE_CANCEL取消發(fā)送文件數(shù)據(jù)包結(jié)構(gòu)體UPDATEINFO無獲取更新本地好友列表請求2.效勞器所用到的數(shù)據(jù)結(jié)構(gòu)結(jié)構(gòu)體命令說明register_backIM_ACCOUNT_REGISTER注冊會員命令結(jié)構(gòu)體login_backIM_LOGIN登陸命令結(jié)構(gòu)體set_info_backIM_ACCOUNT_SET_INFO更新會員信息命令結(jié)構(gòu)體status_change_backIM_STATUS_CHANGE更新會員在線狀態(tài)結(jié)構(gòu)體search_friends_backIM_SEARCH_FRIENDS查找好友命令結(jié)構(gòu)體add_friends_backIM_ADD_FRIEND添加好友命令結(jié)構(gòu)體get_online_backIM_GET_ONLINE_INFO獲取好友在線狀態(tài)信息結(jié)構(gòu)體create_group_backIM_JOIN_GROUPS創(chuàng)立群命令結(jié)構(gòu)體join_group_backIM_JOIN_GROUPS參加群命令結(jié)構(gòu)體search_group_backIM_SEARCH_GROUP查找群命令結(jié)構(gòu)體send_offline_backIM_LEAVE_MSG發(fā)送離線消息命令結(jié)構(gòu)體group_msg_backIM_GROUP_MSG發(fā)送群消息命令結(jié)構(gòu)體4.3.2.3主要的類結(jié)構(gòu)1.客戶端類結(jié)構(gòu)類名稱描述相關(guān)數(shù)據(jù)結(jié)構(gòu)CGlobalData封裝了所有全局?jǐn)?shù)據(jù)和全局函數(shù)。g_globalDataCPacket封裝了數(shù)據(jù)包屬性和操作,是一個能存儲各種數(shù)據(jù)包的類。CList<CPacket,CPacket&>g_sendMsgList;發(fā)送信息鏈表CList<CPacket,CPacket&>g_msgStack;信息棧鏈表CWriteBuffer內(nèi)部實(shí)現(xiàn)了一個內(nèi)存緩沖區(qū),主要用于文件傳輸。m_writeBuffer用于文件傳輸?shù)牡谝粚泳彌_m_writeBuffer2第二層緩沖CGroup定義為群數(shù)據(jù)類,包含群的根本信息。CList<CGroup,CGroup&>g_groupList;群信息鏈表CFriend定義為好友數(shù)據(jù)類,包含了其在線信息,根本信息。CList<CFriend,CFriend&>g_fredAllList;好友信息鏈表CIMSocket定義為主要UDP通信的類,封裝了通信的接受和發(fā)送相關(guān)函數(shù)。CIMessagingDlg里的m_pSocket字段CGlobalData里的g_pSocket字段CIMUdpSendFileSocket定義為基于UDP的文件傳輸?shù)耐ㄐ蓬?。CFiletransPageItem里的m_pSocket字段CImageBmpList定義為CIMListCtrl所用到的圖標(biāo)鏈表CGlobalData里的g_grayImageBmpList字段,g_colorImageBmpList字段。CIMessagingDlg主窗口類,也為登陸窗口類略CIMLoginedDlg登陸時的窗口類CGlobalData里的g_pIMLogingDlg字段CIMLogonDlg登陸成功后的主窗口類CGlobalData里的g_pIMLogonDlg字段CChatDlg好友聊天窗口CList<CChatDlg*,CChatDlg*>g_chatDlgList;CGroupChatDlg群聊天窗口CList<CGroupChatDlg*,CGroupChatDlg*>g_groupChatDlgList;CSearchDlg查詢對話框略CFiletransPageItem文件傳輸類略CNotifyDlg通知對話框類略CCreateGroupDlg創(chuàng)立群對話框類CGlobalData里的g_pCreateGroupDlg字段CRegisterDlg注冊對話框類略2.效勞器類結(jié)構(gòu)類名稱描述相關(guān)數(shù)據(jù)結(jié)構(gòu)CGlobalData封裝了所有全局?jǐn)?shù)據(jù)和全局函數(shù)。g_globalDataCPacket封裝了數(shù)據(jù)包屬性和操作,能存儲各種數(shù)據(jù)包的類。略CMember定義為會員數(shù)據(jù)類,包含了其會員根本信息。CList<CMember,CMember&>g_memberOnlineList;會員在線信息CGroupInfo定義為群數(shù)據(jù)類,包含了群的根本信息。略CSql定義了數(shù)據(jù)庫操作的所有函數(shù)與方法每個處理線程都會創(chuàng)立一個CSqlCIMSocket定義為主要UDP通信的類,封裝了通信的接受和發(fā)送相關(guān)函數(shù)。CIMessageDlg中的m_pSocket;字段CAdoDB鏈接數(shù)據(jù)庫源的類略CIMessageDlg效勞器的主窗口類略
4.4用戶界面設(shè)計(jì)用戶界面設(shè)計(jì)原那么本軟件界面均以對話框?yàn)楦?,以簡潔,大方的外觀,便捷,簡單的操作為設(shè)計(jì)目的,模仿騰訊QQ的外觀界面設(shè)計(jì)而成。具體設(shè)計(jì)原那么如下。1.由于本軟件主要針對年輕人,根據(jù)現(xiàn)在年輕人的操作習(xí)慣,審美觀念,應(yīng)將界面設(shè)計(jì)得時尚,大方,簡潔。操作便捷,能提高年輕人聊天的效率2.界面統(tǒng)一采用淺藍(lán)色為主色調(diào),白色為輔色,給人一種清新,愉快地感覺。3.按鈕控件統(tǒng)一設(shè)計(jì)為動態(tài)效果,使界面的操作具有立體感,更能夠吸引用戶。4.為了更方便用戶的使用,提供大量的使用幫助導(dǎo)航條,使用戶輕松熟悉該軟件的所有操作。5.提供最為便捷的消息提取方式,可以直接雙擊好友項(xiàng),也可以點(diǎn)擊托盤區(qū)的iMessaging圖標(biāo),或者還能夠用快捷鍵進(jìn)行消息提取。在簡潔模式下,可以直接觀察當(dāng)前所有好友發(fā)來的消息,完全滿足用戶的便捷需求。1.界面面板的設(shè)計(jì)客戶端對話框主要分為用戶主操作界面面板,子操作界面面板,便捷操作界面面板三種類型組成,三種類型均運(yùn)用在不同功能的界面上。其中主操作界面面板主要運(yùn)用在登陸界面〔分為登陸會員界面,登陸驗(yàn)證界面和已登陸界面〕,子操作界面主要運(yùn)用在子功能模塊上〔如聊天對話界面,查詢界面,用戶信息界面〕,便捷操作界面面板主要運(yùn)用在簡潔模式上。以下是三種界面模型的原型。圖4.17主操作界面面板圖4.18子操作界面面板圖4.19便捷操作界面面板2.控件的設(shè)計(jì)本軟件的控件設(shè)計(jì)原那么為分為兩大類,可貼圖按鈕型控件和列表控件。其中按鈕型控件又分為簡單型按鈕,Check型按鈕和Tab型按鈕。其中簡單型按鈕有四狀態(tài),離開,懸浮,按下,禁用。如登陸按鈕:離開狀態(tài)懸浮狀態(tài)按下狀態(tài)圖4.20簡單型按鈕模型圖其中Check型按鈕有四種狀態(tài),離開未選中,懸浮未選中,離開選中,懸浮選中,如:離開未選中懸浮未選中離開選中懸浮選中圖4.21Check型按鈕模型圖 其中Tab型按鈕同樣分為離開,懸浮,和按下,但該按下狀態(tài)一直保存,當(dāng)用戶按其他在該Tab里的Tab按鈕時才彈起,如:圖4.22當(dāng)前按下群列表Tab按鈕圖 列表控件派生于CListCtrl,iMessaing里主要構(gòu)造了兩個列表控件,其中一個是CIMListCtrl,用來顯示好友列表,群列表,如4.22圖;另一個是CIMTipListCtrl,用于在簡潔模式下的短消息控件,如4.23圖。圖4.23好友列表控件圖圖4.24簡潔模式下的短消息控件3.圖標(biāo)的設(shè)計(jì)iMessaging圖標(biāo)是根據(jù)本軟件的命名設(shè)計(jì)而成,以
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 動物園裝修施工合同樣本
- 飛機(jī)場地勤個人鏟車租賃協(xié)議
- 金融行業(yè)文秘人才聘用合同
- 建筑工程合同變更渠道施工合同
- 市場調(diào)研合作協(xié)議三篇
- 林地拆遷合同范例
- 能源管理合同(2篇)
- 集體所有制企業(yè)合同制工人退休新規(guī)定
- 常熟房屋租賃合同范例
- 采購垃圾桶合同范例
- 房屋市政工程生產(chǎn)安全重大事故隱患判定標(biāo)準(zhǔn)(2024版)宣傳畫冊
- 2024-2025學(xué)年七年級上學(xué)期歷史觀點(diǎn)及論述題總結(jié)(統(tǒng)編版)
- 國開 2024 年秋《機(jī)電控制工程基礎(chǔ)》形考任務(wù)1234答案+【2020形考1234答案】全析
- 2024年秋兒童發(fā)展問題的咨詢與輔導(dǎo)終考期末大作業(yè)案例分析1-5答案
- 帶式輸送機(jī)機(jī)械設(shè)計(jì)課程設(shè)計(jì)(帶式輸送機(jī))
- 部編版五年級語文上冊快樂讀書吧測試題及答案
- 中國近代人物研究學(xué)習(xí)通超星期末考試答案章節(jié)答案2024年
- 泵用機(jī)械密封沖洗方案及操作方法
- 辣椒介紹PPT課件
- RCA成果報(bào)告書(2021參考模版)10docx
- 中國傳統(tǒng)節(jié)日
評論
0/150
提交評論