版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p> P2P的視頻會(huì)議軟件的開(kāi)發(fā)</p><p><b> 摘要</b></p><p> J2EE往往使許多簡(jiǎn)單問(wèn)題變得復(fù)雜,尤其是采用EJB技術(shù)開(kāi)發(fā)中小型Web應(yīng)用程序,往往會(huì)面臨諸多問(wèn)題:復(fù)雜的J2EE多層結(jié)構(gòu)導(dǎo)致開(kāi)發(fā)組開(kāi)發(fā)質(zhì)量和效率均無(wú)法保障:部分開(kāi)發(fā)人員缺乏J2EE經(jīng)驗(yàn),很難在短時(shí)間內(nèi)進(jìn)入角色;項(xiàng)目組成員在整個(gè)開(kāi)發(fā)過(guò)程中無(wú)法清晰分工,要掌
2、握的技術(shù)層面太多:技術(shù)水平往往不能體現(xiàn)項(xiàng)目小組整體水平,而是個(gè)人水平;中小型項(xiàng)目無(wú)法承擔(dān)應(yīng)用服務(wù)器較高的平臺(tái)成本,而且系統(tǒng)運(yùn)行速度可能很慢。</p><p> 由于傳統(tǒng)J2EE的諸多問(wèn)題,本人使用了一種基于輕量級(jí)J2EE框架的簡(jiǎn)明、高效、可靠的BBS系統(tǒng),該系統(tǒng)采用三層Web體系結(jié)構(gòu)模式,它們分別是表現(xiàn)層、業(yè)務(wù)邏輯層和持久化層。在表現(xiàn)層上使用了JSF框架,在業(yè)務(wù)邏輯層上使用了Spring框架,在持久化層上使用了
3、Hibernate框架。通過(guò)使用這三個(gè)框架,比較好地解決了上面提出的問(wèn)題。</p><p> 本論文闡述了如何使用三個(gè)著名的框架來(lái)開(kāi)發(fā)BBS系統(tǒng)。首先論述傳統(tǒng)J2EE與輕量級(jí)J2EE的對(duì)比,突出輕量級(jí)J2EE的優(yōu)點(diǎn),然后對(duì)在每一層上使用的框架進(jìn)行了介紹,接著對(duì)系統(tǒng)進(jìn)行了需求分析,最后使用框架技術(shù)對(duì)系統(tǒng)進(jìn)行了設(shè)計(jì)和實(shí)現(xiàn)。</p><p> 關(guān)鍵字:BBS,J2EE,Spring,Hibe
4、rnate,JSF</p><p><b> Abstract</b></p><p> The use of J2EE in developing middle-to-small-sized web applications introduces usually a lot of problems to project team due to its relat
5、ively complicated infrastructure. In particular, it requires much more skilled developers than the application domain does, it makes the whole project task difficult to be divided into smaller ones. And thus it increases
6、 the project cost, makes the project quality and progress difficult to control.</p><p> Because tradition J2EE has lot of problems , so I use A new BBS system architecture based on lightweight J2EE Framewor
7、k which is elegant, effective and reliable was proposed.I partition the system architecture into three tier, they are presentation, business-logic and persistence. The presentation uses JSF; the business-logic uses the
8、Spring Framework the persistence uses Hibernate. I have solved better these problems by using the three fames.</p><p> This paper addresses how to use the three frames to develop the BBS System Above all di
9、scusses the comparison of tradition J2EE and lightweight J2EE , extrude the excellence of lightweight J2EE. afterward introduces the frame used at each tier, next analyzes the system requirement, last designs and implem
10、ents the system by using the frame technology.</p><p> Keywords: BBS,J2EE,Spring,Hibernate,JSF</p><p><b> 1 緒論</b></p><p> 1.1 論文課題概述</p><p> 1.1.1 課題背景
11、</p><p> 可以說(shuō)文件交換的需求直接引發(fā)了P2P技術(shù)熱潮。在傳統(tǒng)的WEB方式中,要實(shí)現(xiàn)文件交換需要服務(wù)器的大力參與,通過(guò)將文件上傳到某個(gè)特定的網(wǎng)站,用戶再到某個(gè)網(wǎng)站搜索需要的文件,然后下載,這種方式的不便之處不言而喻。電子郵件是方便了個(gè)人間文件傳遞問(wèn)題,卻沒(méi)法解決大范圍的交換。這也是WEB的重要缺陷,P2P就是在情況下橫空出世。P2P很好的解決了傳統(tǒng)的C/S模式下瓶頸問(wèn)題,讓資源共享變的更方便,快捷。用
12、戶直接和用戶之間進(jìn)行數(shù)據(jù)交換,改變了傳統(tǒng)的模式。</p><p> 1.1.2 課題目的和意義</p><p> 本課題最終成果是完成一個(gè)基于P2P的文件共享系統(tǒng)。該系統(tǒng)可以發(fā)現(xiàn)網(wǎng)絡(luò)上的共享資源,并根據(jù)自己的需求下載自己需要的資源。在傳輸過(guò)程中還要保證數(shù)據(jù)傳輸?shù)耐暾桶踩?lt;/p><p> 本課題的基礎(chǔ)是文件共享和P2P理論,涉及到知識(shí)管理、計(jì)算機(jī)網(wǎng)絡(luò)、分布
13、式存儲(chǔ)和心理學(xué)等領(lǐng)域相關(guān)理論。針對(duì)不同的應(yīng)用需求,人們提出了許多共享方式,以不同的方式來(lái)共享不同的內(nèi)容以滿足人們的需求。但是這些方法都不夠全面,沒(méi)有提出很好的文件共享模式,更加沒(méi)有很好的解決文件共享的需求。特別是在信息飛速增長(zhǎng)的年代,人們對(duì)于信息的篩選即真正知識(shí)的共享的需求越來(lái)越強(qiáng)烈,而人類社會(huì)發(fā)展至今,亦未能找到很好的文件共享的模式和手段。</p><p> 在理論上,本課題探尋文件共享的基礎(chǔ)理論——知識(shí)管理
14、理論、計(jì)算機(jī)網(wǎng)絡(luò)、分布式存儲(chǔ)和心理學(xué)——中相關(guān)研究成果的新結(jié)合點(diǎn),研究在現(xiàn)有理論基礎(chǔ)上如何更好的滿足人們文件共享的需求,采用分布式、高效的基于P2P技術(shù)構(gòu)建的文件共享網(wǎng)絡(luò)這種文件共享模式,并明確提出了P2P文件共享網(wǎng)絡(luò)的整個(gè)架構(gòu),同時(shí),提出了一個(gè)P2P環(huán)境下維護(hù)數(shù)據(jù)一致性和可用性的算法;在實(shí)踐上,課題要實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的P2P知識(shí)共享網(wǎng)絡(luò)的框架,給出了原型實(shí)現(xiàn),經(jīng)過(guò)小范圍的實(shí)驗(yàn)和部署,能夠證明P2P文件共享網(wǎng)絡(luò)能夠提供很高的可用性,并且文
15、件共享的效果也應(yīng)該很好。</p><p> 此外,通過(guò)編寫此系統(tǒng),我又進(jìn)一步熟悉了網(wǎng)絡(luò)體系結(jié)構(gòu),TCP/IP協(xié)議的知識(shí),熟練掌握了Socket編程,MFC編程,多線程編程,掌握了利用VC++進(jìn)行網(wǎng)絡(luò)開(kāi)發(fā)的過(guò)程和步驟,為今后從事軟件行業(yè)奠定了基礎(chǔ)。</p><p> 1.2 論文內(nèi)容概述</p><p> 論文主要論述P2P文件共享的相關(guān)的理論知識(shí),工作原理,編
16、程思路,以及具體實(shí)現(xiàn)細(xì)節(jié)。當(dāng)實(shí)現(xiàn)同一種功能有多種方法時(shí),對(duì)這些方法進(jìn)行了比較,并說(shuō)明選用該方法的理由。論文分以下幾個(gè)部分:第一部分是簡(jiǎn)要介紹所選課題;第二部分是系統(tǒng)可行性研究;第三部分是論文所用到的一些理論知識(shí)概述;第四部分是系統(tǒng)概要設(shè)計(jì);第五部分是系統(tǒng)詳細(xì)設(shè)計(jì);第六部分是系統(tǒng)測(cè)試和實(shí)現(xiàn)。最后對(duì)系統(tǒng)的設(shè)計(jì)進(jìn)行了總結(jié)。英文翻譯、參考文獻(xiàn)和致謝詞是整個(gè)論文的結(jié)束。</p><p><b> 2 系統(tǒng)可行性
17、研究</b></p><p> 2.1 系統(tǒng)可行性分析</p><p> 可行性分析[1]包括兩個(gè)部分:分析建立新系統(tǒng)的必要性和可能性。分析建立系統(tǒng)的必要性時(shí)要注意用戶提出的理由是否充分和合理。分析建立系統(tǒng)的可能性主要包括經(jīng)濟(jì)可行性、技術(shù)可行性和運(yùn)營(yíng)可行性等。</p><p> 2.1.1 系統(tǒng)設(shè)計(jì)的必要性</p><p>
18、 現(xiàn)代社會(huì)網(wǎng)絡(luò)已經(jīng)成為我們生活中的一部分,針對(duì)不同的應(yīng)用需求,人們提出了許多共享方式,以不同的方式來(lái)共享不同的內(nèi)容以滿足人們的需求。但是這些方法都不夠全面,沒(méi)有提出很好的文件共享模式,更加沒(méi)有很好的解決文件共享的需求。特別是在信息飛速增長(zhǎng)的年代,人們對(duì)于信息的篩選即真正知識(shí)的共享的需求越來(lái)越強(qiáng)烈,而人類社會(huì)發(fā)展至今,亦未能找到很好的文件共享的模式和手段。本論文結(jié)合P2P文件共享的原理,利用VC++工具編寫一個(gè)P2P系統(tǒng),不僅實(shí)現(xiàn)了文件
19、共享的目的,而且鍛煉了自己的編程能力和動(dòng)手能力,更重要的是有自己學(xué)習(xí)的滿足感,及由此而帶來(lái)的成就感。</p><p> 此外,畢業(yè)設(shè)計(jì)也是大學(xué)生在校的一個(gè)必修環(huán)節(jié),所以無(wú)論從主觀上還是客觀上,設(shè)計(jì)此系統(tǒng)都是必要的。</p><p> 2.1.2 設(shè)計(jì)系統(tǒng)的可行性</p><p> 分析建立系統(tǒng)的可行性包括經(jīng)濟(jì)可行性、技術(shù)可行性和運(yùn)營(yíng)可行性,法律可行性。<
20、/p><p> 經(jīng)濟(jì)可行性:與請(qǐng)求別人幫助設(shè)計(jì)相比,省去一筆費(fèi)用和溝通時(shí)間。</p><p> 技術(shù)可行性:使用Visual C++作為開(kāi)發(fā)工具,利用MFC進(jìn)行編程,便于高效開(kāi)發(fā)GUI應(yīng)用程序,ClassWizard使得消息映射簡(jiǎn)便易行,文檔/視結(jié)構(gòu)輕松處理和更新數(shù)據(jù)。在此集成開(kāi)發(fā)環(huán)境下,開(kāi)發(fā)Windows應(yīng)用程序是一件比較容易的事情。</p><p> 運(yùn)營(yíng)可行
21、性: 此掃描系統(tǒng)軟件可以用于商業(yè)銷售,為作者贏取部分收入。</p><p> 法律可行性:此系統(tǒng)是應(yīng)畢業(yè)設(shè)計(jì)的要求而開(kāi)發(fā)的,以后也只是用于個(gè)人或正當(dāng)?shù)纳虡I(yè)活動(dòng),不會(huì)觸犯法律。</p><p> 經(jīng)分析,本系統(tǒng)是可以進(jìn)行開(kāi)發(fā)和研究的。</p><p><b> 3 相關(guān)理論和技術(shù)</b></p><p><b&
22、gt; 3.1 網(wǎng)絡(luò)協(xié)議</b></p><p> 3.1.1 TCP協(xié)議</p><p> TCP[2]協(xié)議(Transfer Control Protocol)即傳輸控制協(xié)議,它為網(wǎng)絡(luò)應(yīng)用程序提供面向連接的可靠的傳輸服務(wù),工作在網(wǎng)絡(luò)體系結(jié)構(gòu)中的傳輸層。TCP在數(shù)據(jù)傳輸之前首先要利用三步握手協(xié)議建立連接,并且提供了分組編號(hào),數(shù)據(jù)校驗(yàn)和重傳機(jī)制,確保數(shù)據(jù)傳輸?shù)恼_無(wú)誤。&
23、lt;/p><p> 3.1.2 UDP協(xié)議</p><p> UDP[2]協(xié)議(User Datagram Protocol)即用戶數(shù)據(jù)報(bào)協(xié)議,它為網(wǎng)絡(luò)應(yīng)用程序提供無(wú)連接的數(shù)據(jù)傳輸服務(wù),和TCP協(xié)議一樣,也工作在網(wǎng)絡(luò)體系結(jié)構(gòu)的傳輸層。UDP在數(shù)據(jù)傳輸之前不需要建立連接,數(shù)據(jù)準(zhǔn)備好就直接發(fā)送出去,不能保證分組準(zhǔn)確到達(dá)目的地。然而由于沒(méi)有三步握手和數(shù)據(jù)重傳操作,傳輸比較方便。</p&g
24、t;<p> 3.1.3 IP協(xié)議</p><p> IP協(xié)議(Internet Protocol)即互聯(lián)網(wǎng)協(xié)議,它被用于異構(gòu)網(wǎng)絡(luò)的互聯(lián),是各種各樣種類繁多的網(wǎng)絡(luò)的粘合劑,工作在網(wǎng)絡(luò)體系結(jié)構(gòu)的網(wǎng)絡(luò)層,為傳輸層提供獨(dú)立于網(wǎng)路的分組路由服務(wù)。每一臺(tái)連在網(wǎng)絡(luò)上的主機(jī)都會(huì)分配到一個(gè)IP地址,用以在網(wǎng)絡(luò)上標(biāo)識(shí)這臺(tái)主機(jī)。</p><p> 3.1.4 ICMP協(xié)議</p>
25、;<p> ICMP[2]協(xié)議(Internet Control Management Protocol)即互聯(lián)網(wǎng)控制報(bào)文協(xié)議。是IP協(xié)議的附屬協(xié)議,主要負(fù)責(zé)在主機(jī)之間,主機(jī)與路由器之間傳遞差錯(cuò)信息或者其它需要需要注意的信息。</p><p><b> 3.1.5 說(shuō)明</b></p><p> 對(duì)于從源主機(jī)將數(shù)據(jù)傳輸?shù)侥康闹鳈C(jī)來(lái)說(shuō),IP地址和物理
26、地址是必需的。但是數(shù)據(jù)到達(dá)目的主機(jī)并不是在互聯(lián)網(wǎng)上通信的目的?;ヂ?lián)網(wǎng)上數(shù)據(jù)通信的最終目的是提供端到端的數(shù)據(jù)傳輸,即使一臺(tái)主機(jī)上的某個(gè)進(jìn)程能夠和另一臺(tái)主機(jī)上的某個(gè)進(jìn)程進(jìn)行通信。然而主機(jī)上通常有很多網(wǎng)絡(luò)應(yīng)用進(jìn)程,怎樣去區(qū)別呢?傳輸層提供了一種方法:凡是利用傳輸層進(jìn)行通信的進(jìn)程都被唯一地分配了一個(gè)16位的標(biāo)識(shí),稱為端口號(hào)(Port)。這樣,借助于IP地址和端口號(hào),就可以在網(wǎng)絡(luò)上唯一地表示一個(gè)進(jìn)程了,進(jìn)而完成進(jìn)程之間的通信。所以,一個(gè)端口就是一
27、個(gè)潛在的通信通道,也是一個(gè)潛在的入侵通道,對(duì)目標(biāo)計(jì)算機(jī)進(jìn)行端口掃描可以得到許多有用的信息。</p><p> 3.2 Socket套接字</p><p> 3.2.1 套接字概述</p><p> 網(wǎng)絡(luò)層為我們提供分組路由服務(wù),傳輸層為我們提供數(shù)據(jù)傳輸服務(wù),那么我們?cè)鯓釉趹?yīng)用程序中利用這些服務(wù)呢?答案是使用套接字[4]。</p><p>
28、; 套接字是一種網(wǎng)絡(luò)編程界面,它方便了我們使用網(wǎng)絡(luò)傳輸服務(wù),為我們進(jìn)行基于網(wǎng)絡(luò)的應(yīng)用開(kāi)發(fā)提供了一整套編程接口。套接字是網(wǎng)絡(luò)的基本構(gòu)件,是可以被命名和尋址的通信端點(diǎn),使用中的每一個(gè)套接字都有其類型和一個(gè)與之相連的監(jiān)聽(tīng)進(jìn)程。套接字存在于通信區(qū)域(通信區(qū)域又稱地址簇)中。套接字只與同一區(qū)域中的套接字交換數(shù)據(jù)(跨區(qū)域時(shí),需要執(zhí)行某和轉(zhuǎn)換進(jìn)程才能實(shí)現(xiàn))。</p><p> Socket包含兩個(gè)方面的含義:</p&
29、gt;<p> 其一它是由操作系統(tǒng)或外部過(guò)程提供的一組網(wǎng)絡(luò)編程接口函數(shù),是被廣泛接受的網(wǎng)絡(luò)編程方法;</p><p> 其二它表示一種網(wǎng)絡(luò)參數(shù),通常將IP地址和網(wǎng)絡(luò)應(yīng)用端口的結(jié)合稱作Socket(插口)。</p><p> 3.2.2 Windows Sockets基礎(chǔ)</p><p> Windows Sockets(套接字)是在Window
30、s下的一套開(kāi)放的、支持多種網(wǎng)絡(luò)協(xié)議的、二進(jìn)制兼容的網(wǎng)絡(luò)編程接口規(guī)范。</p><p> WinSock(Windows Sockets簡(jiǎn)寫為WinSock。)的目的是抽象隱藏網(wǎng)絡(luò)底層細(xì)節(jié),它獨(dú)立于底層的協(xié)議,編程人員無(wú)需精通網(wǎng)絡(luò)和協(xié)議的細(xì)節(jié),即可實(shí)現(xiàn)網(wǎng)絡(luò)編程。使用WinSock的應(yīng)用程序可以在遵從Windows Sockets API的任何網(wǎng)絡(luò)上進(jìn)行通信。</p><p> 每個(gè) so
31、cket 都有一個(gè)類型,它是根據(jù)用戶可見(jiàn)的通信特征進(jìn)行描述的。一般應(yīng)用程序只在同一類套接字間通信。不過(guò)只要它依據(jù)的協(xié)議支持,也完全可以在不同類型的套接字間通信。</p><p> 在 WinSock 1.1 只支持兩種 socket 類型:</p><p> #define SOCK_STREAM 1 /* stream socket */</p>&
32、lt;p> #define SOCK_DGRAM 2 /* datagram socket */</p><p> 使用最多的是 SOCK_STREAM(流套接字)和SOCK_DGRAM(數(shù)據(jù)報(bào)套接字)。</p><p> (1) 流式套接字(Stream sockets)</p><p> 它適用于沒(méi)有記錄邊界的字節(jié)數(shù)據(jù)流,保證
33、分組投遞(delivered)、順序正確并且沒(méi)有重復(fù)分組。一般用于TCP協(xié)議。</p><p> (2) 數(shù)據(jù)報(bào)套接字(Datagram sockets)</p><p> 它支持面向記錄的數(shù)據(jù)流,但不保證分組投遞、不保證順序、可能有重復(fù)分組。一般用于UDP傳輸協(xié)議中。</p><p> 在Winsock 2.1以后添加了對(duì)原始套接字的支持:</p>
34、;<p> #define SOCK_RAW 3 /* raw-protocol interface */</p><p> 通過(guò)使用原始套接字我們可以從網(wǎng)絡(luò)接口捕獲到原始的數(shù)據(jù)包,從而可以對(duì)感興趣的數(shù)據(jù)做出自己的處理,或者自己構(gòu)造原始數(shù)據(jù)包發(fā)送到網(wǎng)絡(luò)上。在本系統(tǒng)程序中就利用WinSock庫(kù)創(chuàng)建原始套接字,以實(shí)現(xiàn)對(duì)局域網(wǎng)的監(jiān)聽(tīng)。</p><p>
35、 關(guān)于進(jìn)程是如何利用套接字進(jìn)行通信的,見(jiàn)圖3.1。</p><p> 圖3.1 套接字的使用</p><p><b> 3.3 數(shù)據(jù)庫(kù)編程</b></p><p> 常見(jiàn)的DBMS(數(shù)據(jù)庫(kù)管理系統(tǒng))有SQL2000,Oracle,Sybase,Access等。其中的前三個(gè)都是屬于大型數(shù)據(jù)庫(kù)管理系統(tǒng),用于大量數(shù)據(jù)的管理,Access數(shù)據(jù)庫(kù)比
36、較適用于小型數(shù)據(jù)的管理。所以在本掃描系統(tǒng)的實(shí)現(xiàn)中選用了與Access數(shù)據(jù)庫(kù)建立連接。</p><p> 然而,要是應(yīng)用程序中直接與DBMS打交道,將會(huì)面臨數(shù)據(jù)庫(kù)類型的多樣性所導(dǎo)致的編程的繁瑣。面對(duì)不同類型的數(shù)據(jù)庫(kù),微軟提供了ODBC數(shù)據(jù)庫(kù)接口,用來(lái)以一種統(tǒng)一的方式處理與所有的數(shù)據(jù)庫(kù)的連接。這里我們就要用ODBC與Access數(shù)據(jù)庫(kù)建立連接</p><p> 使用ODBC連接數(shù)據(jù)庫(kù)如圖3
37、.2所示:</p><p> 圖3.2 ODBC訪問(wèn)數(shù)據(jù)庫(kù)</p><p> 應(yīng)用程序要訪問(wèn)一個(gè)數(shù)據(jù)庫(kù),首先必須用ODBC管理器注冊(cè)一個(gè)數(shù)據(jù)源,管理器根據(jù)數(shù)據(jù)源提供的數(shù)據(jù)庫(kù)位置、數(shù)據(jù)庫(kù)類型及ODBC驅(qū)動(dòng)程序等信息,建立起ODBC與具體數(shù)據(jù)庫(kù)的聯(lián)系。這樣,只要應(yīng)用程序?qū)?shù)據(jù)源名提供給ODBC,ODBC就能建立起與相應(yīng)數(shù)據(jù)庫(kù)的連接。</p><p> 在ODBC中
38、,ODBC API不能直接訪問(wèn)數(shù)據(jù)庫(kù),必須通過(guò)驅(qū)動(dòng)程序管理器與數(shù)據(jù)庫(kù)交換信息。驅(qū)動(dòng)程序管理器負(fù)責(zé)將應(yīng)用程序?qū)DBC API的調(diào)用傳遞給正確的驅(qū)動(dòng)程序,而驅(qū)動(dòng)程序在執(zhí)行完相應(yīng)的操作后,將結(jié)果通過(guò)驅(qū)動(dòng)程序管理器返回給應(yīng)用程序。</p><p> 由于是采用MFC編程,而在MFC的ODBC類對(duì)較復(fù)雜的ODBC API進(jìn)行了封裝,提供了簡(jiǎn)化的調(diào)用接口,從而大大方便了數(shù)據(jù)庫(kù)應(yīng)用程序的開(kāi)發(fā)。程序員不必了解ODBC API
39、和SQL的具體實(shí)現(xiàn)細(xì)節(jié),利用ODBC有關(guān)的類即可完成對(duì)數(shù)據(jù)庫(kù)的大部分操作。</p><p><b> 3.4 多線程編程</b></p><p> 3.4.1 一些概念</p><p> 進(jìn)程。進(jìn)程是操作系統(tǒng)分配資源的基本單位,是程序運(yùn)行的一個(gè)實(shí)例,它是動(dòng)態(tài)的。每個(gè)進(jìn)程都在各自的私有地址空間中運(yùn)行,進(jìn)程之間是不能直接進(jìn)行通信的。</
40、p><p> 線程。線程是操作系統(tǒng)分配CPU資源的基本單位,即是系統(tǒng)中最小的執(zhí)行單元。線程運(yùn)行于進(jìn)程空間之中,一個(gè)進(jìn)程中可以有多個(gè)線程,且共享進(jìn)程地址空間,所以線程之間的通信是比較方便的。然而也正是這種便捷,再加上線程的并發(fā)運(yùn)行,使得線程之間的互斥成為必要。</p><p> 進(jìn)程只是線程的容器,是線程執(zhí)行的環(huán)境。它本身是不活潑的,它必須有一個(gè)在它的環(huán)境中運(yùn)行的線程,此線程執(zhí)行進(jìn)程地址空間
41、中的代碼。</p><p> 3.4.2 線程互斥</p><p> 線程由于共享進(jìn)程地址空間,從而共享進(jìn)程資源,對(duì)于一些資源,一次只能有一個(gè)線程進(jìn)行訪問(wèn),稱為臨界資源。多線程編程帶來(lái)的一個(gè)問(wèn)題是線程調(diào)度的隨機(jī)性,執(zhí)行順序的不確定性。所以為了保證線程之間協(xié)調(diào)工作,必須采用線程互斥[11]技術(shù)。</p><p> 常用的線程互斥手段有以下幾種:</p>
42、;<p><b> (1) 關(guān)鍵代碼段</b></p><p> 用戶方式下的一種互斥手段。關(guān)鍵代碼段是指這樣一段代碼,它可以在代碼執(zhí)行前,獨(dú)占對(duì)某種資源的訪問(wèn)權(quán),即使用資源之前對(duì)資源上鎖,使用完畢后再對(duì)資源解鎖,釋放資源的使用權(quán)。這是能讓多個(gè)線程能夠“以原子方式”來(lái)使用資源的一種方法。</p><p><b> (2)互斥對(duì)象</
43、b></p><p> 互斥對(duì)象屬于內(nèi)核對(duì)象的一種。它能夠確保線程擁有對(duì)單個(gè)資源的互斥訪問(wèn)權(quán)。它包含一個(gè)使用計(jì)數(shù)器,一個(gè)線程ID。ID用于標(biāo)識(shí)系統(tǒng)中的哪個(gè)線程當(dāng)前擁有互斥對(duì)象,計(jì)數(shù)器用于說(shuō)明該線程擁有互斥對(duì)象的次數(shù)。</p><p> 首先創(chuàng)建一個(gè)互斥對(duì)象,然后去申請(qǐng)互斥對(duì)象,申請(qǐng)到之后,線程就可以繼續(xù)運(yùn)行下去,否則線程就會(huì)被阻塞,最后擁有者線程釋放互斥對(duì)象。</p>
44、<p><b> (3) 事件對(duì)象</b></p><p> 事件對(duì)象也是一種內(nèi)核對(duì)象。它包含引用計(jì)數(shù),一個(gè)用于指定該事件是自動(dòng)重置還是人工重置事件的布爾值,另一個(gè)用于指明該事件是處于未通知還是已通知狀態(tài)。</p><p> 事件能夠通知一個(gè)操作已完成。有兩種類型事件,一種是人工重置事件,一種是自動(dòng)重置事件。當(dāng)人工重置的事件得到通知時(shí),等待該事件的
45、所有線程均變?yōu)榭烧{(diào)度線程。當(dāng)一個(gè)自動(dòng)重置的事件得到通知時(shí),等待該事件的線程中只有一個(gè)線程變?yōu)榭烧{(diào)度線程。</p><p> 一般情況下,當(dāng)一個(gè)線程執(zhí)行初始化操作,然后通知另一個(gè)線程執(zhí)行剩余的操作時(shí),事件對(duì)象使用得最多。借助于操作系統(tǒng)提供的API,可以很易地改變事件對(duì)象的狀態(tài)。它的使用方法和互斥對(duì)象類似。</p><p><b> 3.5 MFC編程</b><
46、/p><p> 本論文設(shè)計(jì)的P2P文件共享系統(tǒng)采用的編程工具是VC++6.0,基于MFC(微軟基礎(chǔ)類庫(kù))實(shí)現(xiàn)。MFC對(duì)象是C++中類的對(duì)象,它內(nèi)部封裝了Windows對(duì)象,封裝了種類繁多的資源句柄。使用MFC對(duì)象進(jìn)行編程,就像使用C++對(duì)象進(jìn)行編程一樣自然,利用面向?qū)ο蟮木幊谭椒?,無(wú)須為各種句柄所困擾。</p><p> AppWizard為我們生成應(yīng)用程序框架,資源編輯器為我們提供GUI
47、(圖形用戶界面)設(shè)計(jì),這些使得定制一個(gè)應(yīng)用程序外觀更為容易。ClassWizard輔助我們進(jìn)行消息映射,使得我們的主要精力集中于事務(wù)邏輯控制上,消息響應(yīng)函數(shù)的編寫上。文檔/視結(jié)構(gòu)把數(shù)據(jù)和數(shù)據(jù)操作分離,使得我們處理數(shù)據(jù)更加方便。整個(gè)MFC框架為我們生成了一個(gè)應(yīng)用程序的輪廓,我們只需要按照需要進(jìn)行添加或者修改代碼即可。</p><p> 消息是windows編程中一個(gè)重要的概念。程序運(yùn)行起來(lái)之后,就處于消息循環(huán)之中
48、,不斷地接收消息,響應(yīng)消息。消息一般可分為標(biāo)準(zhǔn)消息、命令消息、控件通知消息,而且在MFC中用戶還可以自定義消息,自行添加消息映射,這就極大地提高了編程的靈活性。在做這個(gè)掃描和監(jiān)聽(tīng)程序時(shí),就自定義了許多消息,以協(xié)調(diào)程序的運(yùn)行。</p><p> 正是由于MFC的以上特性,為我們快速開(kāi)發(fā)應(yīng)用程序提供了可能,所以選擇了VC++6.0作為軟件開(kāi)發(fā)平臺(tái)。</p><p><b> 4
49、概要設(shè)計(jì)</b></p><p><b> 4.1 程序框架</b></p><p> 設(shè)計(jì)的主要內(nèi)容是P2P文件共享下載系統(tǒng),網(wǎng)絡(luò)中的用戶知道其他用戶的存在;在現(xiàn)有網(wǎng)絡(luò)架構(gòu)的基礎(chǔ)上,構(gòu)建了一個(gè)虛擬網(wǎng)絡(luò),對(duì)互聯(lián)的各個(gè)節(jié)點(diǎn)的復(fù)雜性進(jìn)行了抽象,不用考慮現(xiàn)有防火墻、NAT和特定網(wǎng)絡(luò)服務(wù)的缺乏;每個(gè)計(jì)算機(jī)用戶既是服務(wù)器,也是客戶端;各個(gè)計(jì)算機(jī)用戶可能形成組,成
50、為一定數(shù)據(jù)和應(yīng)用程序運(yùn)行的共同體。由于以前只是了解相關(guān)內(nèi)容,現(xiàn)在那些知識(shí)是不夠用的了。還有就是功能擴(kuò)展上,為了不落窠臼,在界面設(shè)計(jì),功能上應(yīng)具有一定的獨(dú)創(chuàng)性。</p><p> 文件共享系統(tǒng)是一個(gè)在點(diǎn)組中的多個(gè)點(diǎn)之間共享內(nèi)容的系統(tǒng)。該服務(wù)使得Peer可以共享自己的內(nèi)容以及定位和獲取其他Peer上的內(nèi)容。不僅為本地Peer管理被共享的內(nèi)容,并能瀏覽和下載遠(yuǎn)程Peer的內(nèi)容。</p><p>
51、; 共享的內(nèi)容由一個(gè)獨(dú)一無(wú)二的內(nèi)容ID以及一個(gè)內(nèi)容廣告表示,內(nèi)容廣告提供了有關(guān)被共享內(nèi)容的元信息,例如名字、長(zhǎng)度、MIME類型以及內(nèi)容描述。目前的搜索機(jī)制和內(nèi)容的分發(fā)機(jī)制不是很強(qiáng)大。</p><p> 4.2 系統(tǒng)軟件結(jié)構(gòu)</p><p> 4.2.1 系統(tǒng)一級(jí)層次圖</p><p> 有人認(rèn)為,對(duì)等網(wǎng)絡(luò)是一種分布式動(dòng)態(tài)網(wǎng)絡(luò)體系結(jié)構(gòu),網(wǎng)絡(luò)中的參與者應(yīng)當(dāng)動(dòng)態(tài)地
52、共享它們的部分資源(處理器、存儲(chǔ)資源、網(wǎng)絡(luò)帶寬、外設(shè)、軟件資源、服務(wù)等等),并且這些資源不需通過(guò)中介就能被其他參與者直接訪問(wèn);從而,網(wǎng)絡(luò)的參與者既是資源(服務(wù)和內(nèi)容)的提供者,又是資源的消費(fèi)者。對(duì)等網(wǎng)絡(luò)又可以細(xì)分為兩種類型:“純粹”的對(duì)等網(wǎng)絡(luò)和“混合”的對(duì)等網(wǎng)絡(luò)。所謂“純粹”的對(duì)等網(wǎng)絡(luò)是指在對(duì)等網(wǎng)絡(luò)中,任意一個(gè)參與者的加入和退出都不會(huì)導(dǎo)致網(wǎng)絡(luò)整體服務(wù)的損失。所謂“混合” 的對(duì)等網(wǎng)絡(luò)是指對(duì)等網(wǎng)絡(luò)中需要一個(gè)中心實(shí)體來(lái)保證網(wǎng)絡(luò)服務(wù)的提供,我們
53、所做的就是一個(gè)混合的P2P共享軟件,簡(jiǎn)單描述如下:</p><p><b> 圖4.1 </b></p><p> 4.2.2 系統(tǒng)二級(jí)層次圖</p><p><b> 圖4.2系統(tǒng)層次圖</b></p><p> 性能:包括最大下載速率和每個(gè)節(jié)點(diǎn)可以同時(shí)為多少個(gè)節(jié)點(diǎn)服務(wù),因?yàn)橄螺d速率受網(wǎng)絡(luò)
54、傳輸速率的影響,所以對(duì)每個(gè)節(jié)點(diǎn)來(lái)說(shuō)必須限制其下載的速率,由于每個(gè)節(jié)點(diǎn)都是一個(gè)服務(wù)器,節(jié)點(diǎn)的處理能力不能和大型服務(wù)器比,處理能力有限,為了保證節(jié)點(diǎn)的負(fù)載不止過(guò)大,必須限制最大的服務(wù)對(duì)象。下載速度快、安全性好。</p><p> 安全與保密要求:要高,不能輕易被破壞,防止用戶的隱私信息被竊聽(tīng)和泄露,對(duì)斷電、死機(jī)、系統(tǒng)崩潰等問(wèn)題有有力措施以保障數(shù)據(jù)不受損失。</p><p> 4.3 系統(tǒng)分
55、流程圖</p><p> 系統(tǒng)分流程圖中,分別繪制了文件上傳,文件下載和網(wǎng)絡(luò)監(jiān)聽(tīng)的概要流程圖。但沒(méi)有包含其下的各子功能的具體實(shí)現(xiàn)流程,這些細(xì)節(jié)將會(huì)在詳細(xì)設(shè)計(jì)中予以描述,并繪出進(jìn)一步的流程。系統(tǒng)分流程圖基于各子模塊要實(shí)現(xiàn)的功能,并且將這些模塊再進(jìn)一步細(xì)化,即采用了“自頂向下,逐步求精”的軟件設(shè)計(jì)思路。</p><p> 當(dāng)然,由于本系統(tǒng)所要實(shí)現(xiàn)的功能比較多,而且各功能之下又細(xì)化為許多,所
56、以若是全然繪出,勢(shì)必會(huì)比較臃腫,因此這里只是繪出關(guān)鍵性的環(huán)節(jié),</p><p> 簡(jiǎn)略地闡述了系統(tǒng)實(shí)現(xiàn)的過(guò)程。</p><p> 4.3.1 上傳模塊</p><p><b> 如圖4.5所示:</b></p><p><b> 圖4.5上傳模塊</b></p><p&g
57、t; 4.3.2 下載模塊</p><p><b> 如圖4.6所示:</b></p><p><b> 圖4.4 下載模塊</b></p><p> 4.3.3 P2P文件下載概要流程</p><p> 調(diào)用WINSOCKET編程接口(API),通過(guò)利用它下層提供的服務(wù),達(dá)到與遠(yuǎn)程進(jìn)程交
58、換信息的目的。架在TCP/IP協(xié)議族上的軟件要想利用它們提供的服務(wù)就必須要有適當(dāng)?shù)慕涌?,接口一方面向用戶程序提供了調(diào)用界面(這與操作系統(tǒng)有關(guān)),另一方面還要和TCP/IP協(xié)議族打交道,利用它提供的服務(wù)完成程序的請(qǐng)求。INTERNET在通訊層次上主要表現(xiàn)在連接的建立上:一方(服務(wù)器端)配置好SOCKET并綁定(BIND)到約定的端口,然后偵聽(tīng)等待連接,另一方(客戶端)與建立SOCKET,連接到服務(wù)器主機(jī)上約定的端口,主動(dòng)向?qū)Ψ桨l(fā)出連接請(qǐng)求
59、。服務(wù)器端用新建的SOCKET或ACCEPT函數(shù)把它與遠(yuǎn)方的連接起來(lái)。連接建立后雙方通過(guò)兩個(gè)SOCKET交換信息,直到最后結(jié)束對(duì)話。</p><p><b> 圖4.5 </b></p><p><b> 圖4.6</b></p><p> 本模塊的實(shí)現(xiàn)輸入是:對(duì)方IP和要傳輸?shù)奈募窂剑?lt;/p>&l
60、t;p> 輸出是遠(yuǎn)方主機(jī)的文件下載到本地;</p><p><b> 圖4.7 </b></p><p> 圖4.8 聊天功能概要流程</p><p> 4.4 數(shù)據(jù)庫(kù)的設(shè)計(jì)</p><p> 之所以選擇Access作為系統(tǒng)的后臺(tái)數(shù)據(jù)庫(kù),一方面由于它良好的性能、穩(wěn)定性、便于管理和易于開(kāi)發(fā)等優(yōu)勢(shì),另一方面是
61、由此系統(tǒng)所用數(shù)據(jù)量不大,數(shù)據(jù)表結(jié)構(gòu)簡(jiǎn)單。</p><p> 本系統(tǒng)中,數(shù)據(jù)庫(kù)僅用于服務(wù)器存儲(chǔ)用戶相關(guān)說(shuō)明信息,數(shù)據(jù)表只有兩個(gè)屬性:用戶名和用戶地址信息,用戶為主屬性。當(dāng)A用戶搜索到的資源在B用戶共享中時(shí)。A向服務(wù)器中的數(shù)據(jù)庫(kù)查找B用戶的地址,此時(shí)將進(jìn)行數(shù)據(jù)庫(kù)連接和查詢,檢索操作。然后A直接和B相連進(jìn)行文件共享傳輸。數(shù)據(jù)庫(kù)還應(yīng)該提供資源的檢索,保存索引功能。</p><p><b&g
62、t; 5 系統(tǒng)詳細(xì)設(shè)計(jì)</b></p><p> 在詳細(xì)設(shè)計(jì)中,將會(huì)細(xì)致地討論系統(tǒng)的實(shí)現(xiàn)細(xì)節(jié)、編程中遇到的問(wèn)題及解決方法,以及多種解決方案中選擇某種方案的理由。此外,本部分中還將進(jìn)一步論述第三部分,第四部分所涉及到的理論和技術(shù)。</p><p> 首先,在VC++6.0中新建一個(gè)工程,命名為IPScan(IP掃描)。選擇單文檔結(jié)構(gòu),視類從CFormView類得到繼承。下面
63、分述:</p><p> 5.1 系統(tǒng)實(shí)現(xiàn)中用到的類</p><p> CIPScanApp:AppWizard生成。應(yīng)用程序類</p><p> CIPScanDoc:AppWizard生成。文檔類,用于數(shù)據(jù)的存儲(chǔ)和加載。</p><p> CIPScanView:AppWizard生成。視類,用于對(duì)數(shù)據(jù)進(jìn)行操作。這里選擇了從CFo
64、rmView類繼承,是為了利用其可以作為容器的功能。提供了主機(jī)掃描的界面。</p><p> CMainFrame:AppWizard生成。應(yīng)用程序框架類,表示應(yīng)用程序框架窗口。</p><p> CPortScan:自定義的類。繼承于CDialog類,用來(lái)管理端口掃描界面的對(duì)話框資源。</p><p> CsnifferNetDlg:自定義的類。繼承于Cdi
65、alog類,用來(lái)管理網(wǎng)絡(luò)監(jiān)聽(tīng)界面的對(duì)話框資源。</p><p> CUDP:自定義的類。派生于CSocket類,借助于此類中的SendTo()函數(shù)來(lái)發(fā)送消息,且在該類中還重載了OnReceive()函數(shù),用來(lái)接收返回的消息,并可以添加自己的處理代碼。</p><p> CPortRecord:自定義的類。繼承于CRecordset類,作為一個(gè)記錄集,用來(lái)保存從數(shù)據(jù)庫(kù)中返回的結(jié)果,以供查
66、詢和檢索使用。在建立記錄集時(shí),可用利用CRecordset類中的成員函數(shù),結(jié)合一些參數(shù)構(gòu)造一個(gè)SELECT語(yǔ)句來(lái)查詢數(shù)據(jù)源,并用查詢的結(jié)果創(chuàng)建記錄集。</p><p> CHyperLink:添加的類。該類的主要功能是提供文字超鏈接,在本程序的關(guān)于對(duì)話框中,我使用了此類??梢枣溄拥轿业泥]箱和個(gè)人主頁(yè)。</p><p> NetInfo:自定義的結(jié)構(gòu)。該結(jié)構(gòu)主要用于端口掃描中保存一些輸入
67、信息,如IP,端口號(hào)等。定義如下:</p><p> struct NetInfo</p><p><b> {</b></p><p> CString ip;//掃描主機(jī)IP地址</p><p> int nStartPort;//掃描起始端口</p><p> int nEndPo
68、rt;//掃描終止端口</p><p> BOOL isStop;//為false時(shí)終止端口掃描線程</p><p><b> };</b></p><p> Iphdr:自定義的結(jié)構(gòu)。用于描述IP包頭的信息。定義如下:</p><p> typedef struct Iphdr</p><p
69、><b> {</b></p><p> unsigned char h_lenver;//4位版本號(hào)+4位首部長(zhǎng)度</p><p> unsigned char tos;//8位服務(wù)類型</p><p> unsigned short total_len;//16位總長(zhǎng)度字節(jié)</p><p> unsi
70、gned short ident;//16位標(biāo)識(shí)</p><p> unsigned short frag_and_flags;//3位標(biāo)志位+13位的分段偏移</p><p> unsigned char ttl;//8位生存時(shí)間TTL</p><p> unsigned char proto;//8位協(xié)議</p><p> uns
71、igned short checksum;//16位的IP首部校驗(yàn)和</p><p> unsigned int sourceIP;//32源地址</p><p> unsigned int destIP;//32位目的地址</p><p> } IP_HEADER;</p><p> Tcphdr:自定義的結(jié)構(gòu)。用于描述TCP包頭的
72、信息。定義如下:</p><p> typedef struct Tcphdr</p><p><b> {</b></p><p> unsigned short th_sport;//源端口</p><p> unsigned short th_dport;//目標(biāo)端口</p><p>
73、; unsigned int th_seq;//序列號(hào)</p><p> unsigned int th_ack;//確認(rèn)號(hào)</p><p> unsigned char th_lenres;//4位首部長(zhǎng)度+4位保留字</p><p> unsigned char th_flags;//2位保留字+6位標(biāo)志位</p><p> u
74、nsigned short th_win;//16位窗口大小</p><p> unsigned short th_sum;//16位校驗(yàn)和</p><p> unsigned short th_urp;//16位的緊急數(shù)據(jù)偏移量</p><p> } TCP_HEADER;</p><p> Udphdr:自定義的結(jié)構(gòu)。用于描述UD
75、P協(xié)議的頭部信息。定義如下:</p><p> typedef struct Udphdr</p><p><b> {</b></p><p> unsigned short uh_sport;//16位源端口</p><p> unsigned short uh_dport;//16目的端口</p>
76、;<p> unsigned short uh_len;//16位長(zhǎng)度</p><p> unsigned short uh_sum;//16位校驗(yàn)和</p><p> } UDP_HEADER;</p><p> Icmphdr:自定義的結(jié)構(gòu)。用于描述ICMP協(xié)議的頭部信息。定義如下:</p><p> typede
77、f struct Icmphdr</p><p><b> {</b></p><p> BYTE i_type;//8位類型</p><p> BYTE i_code;//8位代碼</p><p> unsigned short i_cksum;//16位校驗(yàn)和</p><p> un
78、signed short i_id;//識(shí)別號(hào)</p><p> unsigned short i_seq;//報(bào)文序列號(hào)</p><p> ULONG timestamp;//時(shí)間戳</p><p> } ICMP_HEADER;</p><p> 5.2 系統(tǒng)圖標(biāo)變換</p><p> 程序運(yùn)行起來(lái)之后,
79、左上角的圖標(biāo)是動(dòng)態(tài)變換的,即可以在幾個(gè)不同的圖標(biāo)之間來(lái)回切換,而且在此程序中打開(kāi)的所有對(duì)話框都繼承了此特性。為了達(dá)到此效果,我采用了下面的設(shè)計(jì)方法:</p><p> (1) 在CMainFrame類中創(chuàng)建一個(gè)定時(shí)器,用以發(fā)送定時(shí)消息,且在其中定義了一個(gè)圖標(biāo)句柄數(shù)組變量成員m_hIcons,保存更換的圖標(biāo)資源,即</p><p> HICON m_hIcons[3]。</p>
80、;<p> (2) 在CMainFrame類的構(gòu)造函數(shù)中初始化此句柄數(shù)組。</p><p> m_hIcons[0]=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));</p><p> m_hIcons[1]=LoadIcon(AfxGetInstanceHandle(),MAKEINTRE
81、SOURCE(IDI_ICON1));</p><p> m_hIcons[2]=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON2));</p><p><b> 函數(shù)說(shuō)明如下:</b></p><p> HICON LoadIcon(</p><p&g
82、t; HINSTANCE hInstance, // 應(yīng)用程序?qū)嵗浔?lt;/p><p> LPCTSTR lpIconName // 指向圖標(biāo)名字的指針 </p><p><b> );</b></p><p> 該函數(shù)的功能是從一個(gè)與應(yīng)用程序?qū)嵗嚓P(guān)的可執(zhí)行文件中加載圖標(biāo)資源。</p><p> HINS
83、TANCE AfxGetInstanceHandle( );</p><p> 該函數(shù)用于返回當(dāng)前應(yīng)用程序的一個(gè)實(shí)例句柄。</p><p> LPTSTR MAKEINTRESOURCE(WORD wInteger// integer to convert);</p><p> 一個(gè)轉(zhuǎn)換宏,用以將ID標(biāo)示的資源轉(zhuǎn)換為符合要求的類型。</p>&l
84、t;p> (3) 在定時(shí)器的消息響應(yīng)函數(shù)中,進(jìn)行動(dòng)態(tài)改變圖標(biāo)的動(dòng)作。</p><p> void CMainFrame::OnTimer(UINT nIDEvent) </p><p><b> {</b></p><p> static int index=1;//需要設(shè)置靜態(tài)成員變量</p><p>
85、 //動(dòng)態(tài)設(shè)置要顯示的圖標(biāo)</p><p> SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIcons[index]);</p><p> SetClassLong(m_dlgPortScan.m_hWnd,GCL_HICON,(LONG)m_hIcons[index]);</p><p> index=++index%3;//
86、循環(huán)顯示圖標(biāo)</p><p> ......................//</p><p><b> }</b></p><p><b> 函數(shù)說(shuō)明:</b></p><p> DWORD SetClassLong(</p><p> HWND hWnd,
87、 // 窗口句柄</p><p> int nIndex, // 類型索引</p><p> LONG dwNewLong // 新的值</p><p><b> );</b></p><p> 該函數(shù)用于改變窗口類的風(fēng)格,如窗口的圖標(biāo),光標(biāo),背景色等。</p><p&g
88、t; 5.3 顯示提示信息</p><p> 5.3.1 控件信息提示</p><p> 該功能是實(shí)現(xiàn)當(dāng)鼠標(biāo)放對(duì)話框上的某個(gè)控件上時(shí),彈出某個(gè)提示框,顯示相應(yīng)的提示信息。在VC中,用CToolTipCtrl類可以做到這種效果,該類派生于CWnd類,所以是一個(gè)窗口類。</p><p> 通過(guò)以下步驟,我達(dá)到了預(yù)期的目的。</p><p>
89、; (1) 在CIPScanView類中添加成員變量</p><p> CToolTipCtrl m_toolTip;//提示控件對(duì)象</p><p> (2) 在適當(dāng)?shù)奈恢谜{(diào)用EnableToolTips(TRUE),允許使用消息提示框。接著創(chuàng)建m_toolTip對(duì)象,并激活它:</p><p> m_toolTip.Create(this);//創(chuàng)建對(duì)象
90、</p><p> m_toolTip.Activate(true);//激活對(duì)象</p><p> 然后調(diào)用CToolTipCtrl類的AddTool函數(shù)。這些代碼我選擇了放在CIPScanView類的OnInitialUpdate()函數(shù)中,該函數(shù)用于初始化視對(duì)話框。如下:</p><p> void CIPScanView::OnInitialUpdat
91、e()</p><p><b> {</b></p><p> ..................//</p><p> EnableToolTips(true);//允許使用此信息提示通用控件</p><p> m_toolTip.Create(this);</p><p> m_t
92、oolTip.Activate(true);</p><p> CWnd * pWnd=GetDlgItem(IDC_LISTVIEW); </p><p><b> //設(shè)置提示信息</b></p><p> m_toolTip.AddTool(pWnd,"雙擊主機(jī)掃描其端口"); </p><p
93、> ...................//</p><p><b> }</b></p><p> (3) 在CIPScanView類中添加虛函數(shù)PreTranslateMessage,并在此函數(shù)中調(diào)用CToolTipCtrl類的RelayEvent函數(shù)。如下:</p><p> BOOL CIPScanView::PreTr
94、anslateMessage(MSG* pMsg) </p><p><b> {</b></p><p> m_toolTip.RelayEvent(pMsg);//調(diào)用進(jìn)行消息過(guò)濾</p><p> return CFormView::PreTranslateMessage(pMsg);</p><p><
95、;b> }</b></p><p> PreTranslateMessage函數(shù)可以在消息被派發(fā)之前對(duì)消息進(jìn)行預(yù)處理。</p><p> 經(jīng)過(guò)上述幾個(gè)步驟之后,當(dāng)我們把鼠標(biāo)放在相應(yīng)的控件上時(shí),就會(huì)顯示出相應(yīng)的提示信息了。</p><p> 5.3.2 工具欄信息提示</p><p> 在文檔/視結(jié)構(gòu)中,為工具欄上的
96、按鈕設(shè)置提示信息,是很容易的事情。然而在對(duì)話框中,MFC并沒(méi)有直接為此提供便利。在本系統(tǒng)中,端口掃描界面和網(wǎng)絡(luò)監(jiān)聽(tīng)界面都是基于對(duì)話框的,并且我又為它們添加了工具欄。那么該如何做才能出現(xiàn)提示信息呢?</p><p> 對(duì)話框中的工具欄使用提示信息的功能,需要響應(yīng)兩個(gè)消息:TTN_NEEDTEXTA和TTN_NEEDTEXTW。在對(duì)話框的實(shí)現(xiàn)文件中,使用消息映射宏ON_NOTIFY_EX來(lái)添加消息響應(yīng)函數(shù)。如下:&
97、lt;/p><p> ON_NOTIFY_EX(TTN_NEEDTEXT,0,OnTipText)</p><p> 其中OnTipText()為響應(yīng)函數(shù)。原型如下:</p><p> BOOL OnTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult)</p><p><b> 代碼簡(jiǎn)要分
98、析:</b></p><p> BOOL OnTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult)</p><p><b> {</b></p><p><b> ……………//</b></p><p> TOOLTIPTEXTA* pT
99、TTA = (TOOLTIPTEXTA*)pNMHDR;</p><p> TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;</p><p> CString strTipText;//暫存提示信息</p><p> nID = ::GetDlgCtrlID((HWND)nID);//工具欄ID</p>&
100、lt;p> if (nID != 0) //不是分隔符</p><p><b> {</b></p><p> strTipText.LoadString(nID); </p><p><b> //獲取提示信息</b></p><p> strTipText = strTipTex
101、t.Mid(strTipText.Find('\n',0)+1); </p><p> if (pNMHDR->code == TTN_NEEDTEXTA)</p><p><b> {</b></p><p> //將提示信息拷貝到結(jié)構(gòu)體的szText成員中,以供顯示 lstrcpyn(pTTTA->s
102、zText,strTipText,sizeof(pTTTA->szText));</p><p><b> }</b></p><p><b> else</b></p><p><b> {</b></p><p> _mbstowcsz(pTTTW->s
103、zText,strTipText,sizeof(pTTTW->szText));</p><p><b> }</b></p><p> …………………// </p><p><b> }</b></p><p> return TRUE;</p><p>&l
104、t;b> }</b></p><p> 5.4 最小化到系統(tǒng)托盤</p><p> 一般情況下,程序最小化后都會(huì)到任務(wù)欄上。但是有時(shí)候又不希望程序占用任務(wù)欄的空間,這時(shí)候就可以考慮把程序圖標(biāo)放到系統(tǒng)托盤中。本局域網(wǎng)掃描和監(jiān)聽(tīng)系統(tǒng)就實(shí)現(xiàn)了這個(gè)功能,通過(guò)自己編程把圖標(biāo)放到托盤里,體驗(yàn)了一下“尊貴”感覺(jué),很讓人興奮的。</p><p> 5.4.
105、1 實(shí)現(xiàn)原理</p><p> 將程序放到系統(tǒng)托盤里的原理是很簡(jiǎn)單的,先在托盤區(qū)放置一個(gè)圖標(biāo),然后把程序的主窗口隱藏不見(jiàn),最后對(duì)托盤圖標(biāo)消息進(jìn)行編程就可以了。</p><p> 5.4.2 實(shí)現(xiàn)細(xì)節(jié)</p><p> 顯示托盤圖標(biāo)和向圖標(biāo)傳遞消息的函數(shù)僅有一個(gè):</p><p> BOOL WINAPI Shell_NotifyIco
106、n(DWORD dwMessage, PNOTIFYICONDATA pnid);</p><p> 函數(shù)功能是負(fù)責(zé)向系統(tǒng)傳遞信息,以添加,刪除,或者修改圖標(biāo)。究竟實(shí)現(xiàn)何種功能,是由參數(shù)來(lái)指定的。執(zhí)行成功返回零值,否則返回非零值。</p><p> 參數(shù)dwMessage:發(fā)送的消息。為NIM_ADD時(shí),表示向托盤區(qū)添加一個(gè)圖標(biāo);為NIM_DELETE時(shí),表示從托盤區(qū)刪除一個(gè)圖標(biāo);為
107、NIM_MODIFY時(shí),表示修改托盤區(qū)的圖標(biāo)。</p><p> 參數(shù)pnid:是一個(gè)指向NOTIFYICONDATA結(jié)構(gòu)的指針,它的值取決于dwMessage參數(shù)的值。結(jié)構(gòu)NOTIFYICONDATA定義如下:</p><p> typedef struct _NOTIFYICONDATA </p><p><b> { </b><
108、;/p><p> DWORD cbSize;//本結(jié)構(gòu)大小 </p><p> HWND hWnd; //與托盤圖標(biāo)相關(guān)的窗口句柄</p><p> UINT uID; //程序中定義的托盤圖標(biāo)的ID</p><p> UINT uFlags; //指示本結(jié)構(gòu)中哪些成員有效的標(biāo)志</p><p> UINT uC
109、allbackMessage;//程序中自定義的回調(diào)消息</p><p> HICON hIcon;//托盤圖標(biāo)的句柄</p><p> char szTip[64];//鼠標(biāo)放到圖標(biāo)上時(shí)的提示信息</p><p> } NOTIFYICONDATA, *PNOTIFYICONDATA; </p><p><b> 下面分述
110、:</b></p><p> (1) 添加消息響應(yīng)函數(shù)</p><p> 在類CMainFrame中添加響應(yīng)WM_SIZE消息的響應(yīng)函數(shù)OnSize,這樣當(dāng)點(diǎn)擊最小化按鈕時(shí),程序就會(huì)最小化到托盤:</p><p> void CMainFrame::OnSize(UINT nType, int cx, int cy) </p><
111、;p><b> { </b></p><p> .........................//</p><p> if(nType==SIZE_MINIMIZED)</p><p><b> {</b></p><p> NOTIFYICONDATA nid;</p&g
112、t;<p> nid.cbSize=(DWORD)sizeof(NOTIFYICONDATA);</p><p> nid.hWnd=pMfrm->m_hWnd;</p><p> nid.uID=IDR_MAINFRAME;</p><p> nid.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP; </p
113、><p> //自定義的在托盤區(qū)顯示圖標(biāo)的消息</p><p> nid.uCallbackMessage=WM_SHOW_PROGRAM;nid.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));</p><p> strcpy(nid.szTip,"網(wǎng)絡(luò)主機(jī)和
114、端口掃描程序");//信息提示</p><p> Shell_NotifyIcon(NIM_ADD,&nid);//在托盤區(qū)添加圖標(biāo)</p><p> ShowWindow(SW_HIDE);//隱藏主框架窗口</p><p><b> } </b></p><p><b> }<
115、;/b></p><p> 從函數(shù)中可以看出,首先是填充NOTIFYICONDATA結(jié)構(gòu),設(shè)置相關(guān)信息,然后調(diào)用Shell_NotifyIcon函數(shù)。還是比較簡(jiǎn)單的。</p><p> (2) 操作托盤區(qū)的圖標(biāo)</p><p> 當(dāng)程序最小化到托盤后,應(yīng)該能夠使程序還原到正常狀態(tài),還可以對(duì)托盤圖標(biāo)添加一些快捷菜單操作。此時(shí)NOTIFYICONDATA結(jié)構(gòu)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 基于P2P技術(shù)的視頻會(huì)議系統(tǒng).pdf
- 基于P2P的網(wǎng)絡(luò)視頻會(huì)議系統(tǒng)的研究和開(kāi)發(fā).pdf
- 基于P2P的視頻會(huì)議系統(tǒng)的研究.pdf
- 基于P2P的多點(diǎn)視頻會(huì)議技術(shù)研究.pdf
- 基于P2P技術(shù)的視頻會(huì)議系統(tǒng)的研究與設(shè)計(jì).pdf
- 視頻會(huì)議中基于P2P技術(shù)的視頻分發(fā)原型系統(tǒng)的實(shí)現(xiàn).pdf
- 基于DirectShow的P2P視頻會(huì)議系統(tǒng)研究與設(shè)計(jì).pdf
- 基于混合P2P架構(gòu)的視頻會(huì)議系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn).pdf
- 視頻會(huì)議中基于P2P的協(xié)作通信的研究與實(shí)現(xiàn).pdf
- 基于P2P的視頻會(huì)議系統(tǒng)體系結(jié)構(gòu)的研究.pdf
- P2P視頻會(huì)議系統(tǒng)關(guān)鍵技術(shù)研究.pdf
- 構(gòu)建IPV6和P2P模式下的視頻會(huì)議系統(tǒng).pdf
- p2p的研究-畢業(yè)設(shè)計(jì)論文
- p2p軟件的實(shí)現(xiàn)
- 基于P2P的軟件協(xié)同開(kāi)發(fā)平臺(tái)的研究.pdf
- P2P的視頻直播系統(tǒng)的設(shè)計(jì)和實(shí)現(xiàn).pdf
- P2P視頻點(diǎn)播內(nèi)容分發(fā)系統(tǒng)開(kāi)發(fā).pdf
- 視頻會(huì)議終端軟件系統(tǒng)的設(shè)計(jì)與開(kāi)發(fā).pdf
- 基于P2P技術(shù)的視頻點(diǎn)播系統(tǒng)的設(shè)計(jì).pdf
- 我國(guó)p2p現(xiàn)狀和對(duì)策研究畢業(yè)設(shè)計(jì)論文
評(píng)論
0/150
提交評(píng)論