版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
摘要目前,關于即時通訊系統(tǒng)(InstantMessagingSystem)的研究是互聯網中一個熱門方向,尤其是關于企業(yè)級的即時通訊系統(tǒng)更是成為了國內外應用的熱點。企業(yè)版的即時通訊軟件的誕生,給企業(yè)的管理帶來了新的思路和方法,提高了企業(yè)的工作效率,降低了辦公費用,引發(fā)了工程應用領域的新研究熱潮。即時通訊系統(tǒng)基本上均采用客戶機/服務器(C/S)模式。在此模式下,服務器無疑是處于核心地位的。本文正是圍繞即時通訊系統(tǒng)服務器端軟件開發(fā)這一核心展開。首先,本文選擇了當今流行的各種即時通訊軟件,進行對比分析,確定了即時通訊系統(tǒng)的功能,提出了不同的即時通訊服務器的架構。其次,本文介紹了本系統(tǒng)使用的目前流行的一些技術,如多線程技術TCP/IP協(xié)議和OSI模型、套接字(socket)通信結構等圍繞即時通訊的基本文字交流功能,設計了不同用戶之間的文字通訊。本系統(tǒng)就是在此企業(yè)即時通信市場日益高漲的時候,采用先進的JavaSocket技術,開發(fā)出一個C/S模式的基于TCP/UDP協(xié)議的網絡通信系統(tǒng)。該系統(tǒng)充分利用了Java的跨平臺性,結合目前已有的典型通訊軟件BBS和OICQ的某些技術,采用TCP/UDP協(xié)議與服務器轉發(fā)的技術,擴展了文件發(fā)送的功能,使得客戶間發(fā)送文件不受防火墻限制。同時在時間允許的情況下增加語音、視頻以及網絡電視等功能。關鍵詞:即時通訊系統(tǒng)OICQC/S模式ITheInternetMessagingSystemBasedonJavaAbstractNowtheresearchaboutinstantmessagingsystemisahotdirectionininternet,especiallytheinstantmessagingsystemforenterprisegroupisahotspotinpracticingintheworld.Theinstantmessagingsystemforenterprisegroupbringsnewthoughtsandwaysforenterprisemanagement,raisestheworkingefficiency,cutsdowntheadministrativeexpenses,andinitiatesthenewtrendinindustrialpracticingfield.InstantmessagingsystemmainlyselectsC/Smode.Serveristhecorepartinthismode.Thispaperjustbasesonthedevelopmentofinstantmessagingsystemsoftware.First,thispaperselectsseveralkindsofpopularinstantmessagingsoftware,contrastsandanalyzeseachone,definesthefunctionsofinstantmessagingsystem,advancesthedifferentstructuresofinstantmessagingservers.Second,thispaperintroducessometechniqueswhichareusedinthissystem,eg:TCP/IP,OSIandsocketetc.basiccommunicatingfunctionsofinstantmessagingsystem,designsthecharactersandwritingcommunicationbetweendifferentusers.ThissystemselectsadvancedJavaSockettechnique,developsaC/SmodeinternetcommunicationsystemwhichisbasedonTCP/UDP.ThissystemusestheJava’smulti-platformfeaturefully,combinessometechniquesofthetypicalinstantmessagingsoftwarelikeOICQwhichexistnow,selectsTCP/UDPagreementandservertransmittingtechniques,expandsthefilestransmittingfunction,whichenablesnorestrictionfromfirewallwhilesendingfilesbetweenusers.Meanwhile,itaddsfunctionslikeinternetcall,videocallandinternetTVetc.whenthetimeissufficient.Keywords:InstantMessagingSystemOICQC/SModeII目錄摘要……………IAbstract……………………II1引言…………52研究綜述……………………62.1Internet通信概述……………72.2目前流行的即時通信軟件簡介………………72.2.1ICQ…………72.2.2騰訊OICQ……………………82.2.3MSN…………82.2.4雅虎通Yahoo!Messenger…………………82.2.5朗瑪UC………82.3即時通信軟件在企業(yè)中的運用情況簡介……83相關技術簡介………………103.1主流的網絡通信模型……103.1.1C/S模型……………………103.1.2B/S模型……………………113.1.3P2P模型……………………123.2TCP/IP協(xié)議和OSI模型………133.2.1OSI模型……………………133.2.2TCP/IP協(xié)議………………143.2.3套接字………153.3程序采用的主要技術…………163.3.1多線程技術…………………163.3.2客戶/服務器程序設計范式………………173.4MySQL簡介……………………184系統(tǒng)設計……………………194.1總體設計………194.2系統(tǒng)功能設計…………………194.3數據庫設計……………………205詳細設計與實現……………215.1服務器程序……………………215.2客戶端…………296系統(tǒng)測試……………………426.1軟件測試………426.2軟件測試目的…………………427總結…………43參考文獻……………………44謝辭…………451引言近年來,即時通信發(fā)展迅速,呈現出繼語音、視頻、短信之后的通信網絡基本業(yè)務能力,成為越來越多的人在交友、工作、交易和咨詢中的首選方式。當前,即時通信正從單純的呈現和即時消息向多媒體綜合通信方向發(fā)展,逐步占領企業(yè)和個人綜合通信市場。無縫溝通是即時通信發(fā)展的方向。近期中國移動推出的“飛信”業(yè)務,就是突出在線即時消息與下線短信的轉換,保持信息的無縫溝通。不僅如此,覆蓋移動與固定終端的音/視頻會議群組通信等都是即時通信所關注的重要內容。多媒體的融合應用已成為即時通信發(fā)展的方向。據國外互聯網市場研究公司RadicatiGroup的統(tǒng)計數據顯示:2006年全球即時通信用戶數量已經達到4.32億,到2010年預計全球將有6.5億即時通信用戶。據CNNIC統(tǒng)計,2006年中國即時通信用戶數量達到1.16億,即時通信軟件在互聯網用戶中的滲透率達到86%。隨著網絡接入的寬帶化和終端智能化程度的提高,即時通信正向集呈現、即時消息、語音、視頻、會議、應用共享為一體的融合通信方向發(fā)展?!盁o縫溝通、多媒體交流”已成為即時通信的特征。即時通信從個人向企業(yè)通信滲透,對于企業(yè)來說,即時通信相對于傳統(tǒng)的電話、手機、傳真和郵件等溝通方式,無疑在溝通和協(xié)作等方面具備快捷和實時等優(yōu)勢。企業(yè)通信與企業(yè)的運作流程密切相關,即時通信的引入,大大提高了企業(yè)的綜合通信能力。例如:由企業(yè)管理員維護的企業(yè)通信錄,可即時看到員工的呈現狀態(tài);群發(fā)的即時消息,是企業(yè)發(fā)布公告或會議通知的理想方式;即時發(fā)起的音/視頻會議以及應用協(xié)同,為在異地辦公的人員實時溝通提供了便捷的手段等等。本系統(tǒng)就是針對當前市場的需求和技術的不斷發(fā)展、企業(yè)對即時通信的需求日益增加,同時由于個人即時通信軟件存在著安全性和可管理性差等明顯的問題和不足,所以具有“無縫溝通、多媒體交流”特征的企業(yè)即時通訊系統(tǒng)應運而生。2研究綜述2.1Internet通信概述Internet通信目前已經成為人們生活的一個基本部分。“溝通無極限”,移動通訊的廣告語其實更適合即時聊天。即時聊天使親友的溝通突破時空使辦公室的溝通突破上下級極限,使陌生人的溝通突破環(huán)境極限,使自我與的溝通突破心理極限。如果說互聯網創(chuàng)造了新生活,那么讓新生活變得更暢快的就是即時通訊(InstantMessagingSoftware,以下簡稱IM)。早期在互聯網上,人們只能E-Mail、新聞組、BBS等“原始”方式交流,往往不能夠及時把消息傳遞給甚至不知道對方什么時候能夠看到,或有誰能看到誰又會回應。作為使用頻率最高的網絡軟件即時聊天已經突破了作為技術工具的極認為是現代交流方式的象征,并構建起一種新的社會關系。它是迄今為止對社會生活改變最為深刻的一種網絡新形態(tài),沒有極限的溝通將帶來沒有極限活。據統(tǒng)計,迄今為止,全球約有一億多人使用即時通訊軟件在網上交流網民慣用的即時通訊軟件——“騰訊QQ”從1999年2月誕生到現在,注戶已超過1.6億,2004年12月4日最高同時在線人數突破900萬人,而每立上線人數更是達到一千二百多萬,擁有活躍用戶5500萬,幾乎覆蓋所有網民。行業(yè)研究機構RadicatiGroup公司一項題為《2003--2007間的即時通存在市場趨勢》的預測報告稱,全球的即時通信服務賬戶將由去年的5.9億增長到2007年的14.39億美元,而即時通訊軟件市場將由2003年底時的美元大幅成長至2007年的2570萬美元。其中企業(yè)領域增長顯著,賬戶數量去年的6000萬增長到2007年的3.49億,增長幅度高達600%。即時通訊軟件的互動性高于BBS和E-mail,它比電話嚴肅,比E-mail利用它可以實時傳送文字信息、語音信息和發(fā)送文件。另外,它還可以作為內部聯絡的一種方式,可以用來召開網絡會議,比起實地的會議來,不僅而且節(jié)省開支。就像現代社會的電話一樣,目前即時通訊軟件的確做到了這一點。2.2目前流行的即時通訊軟件簡介目前市面上流行的即時通訊軟件主要有:ICQ、“騰迅QQ”、MSN、YAHOOMESSENGER以及UC等等。2.2.1ICQ原是以色列的幾名學生開發(fā)出來的一款即時通訊工具軟件。它利用點的方式通訊,任何登錄ICQ服務器的用戶,盡管國籍、膚色、文化背景教信仰不同,都能夠在網上即時溝通。任何人只要擁有ICQ號碼,就可以界各地的人做朋友,它的互動性是Web網頁、虛擬社區(qū)和電子郵件所無法的。在辦公室中,同事之間透過ICQ聯絡事宜,就算近在咫尺,也無須起談;與遠方的親朋好友交談,也只是輕輕敲幾下鍵盤就可以解決問題,這種在過去幾乎是無法想象的。但ICQ對中文的支持比較差,不適于中國企業(yè)用。2.2.2騰訊OICQ,簡稱QQ,是國內最時髦的即時通訊工具,其用戶的年齡層次從剛開中小學生族,發(fā)展到現在的幾乎所有上網者。每當看到連到網上的一臺臺電屏幕上跳躍著一個個各式各樣“小人頭兒”,就知道QQ上的好友來信了。目迅QQ”開展了大量的網絡增值服務,如為其用戶提供網上尋呼、視頻聊天音聊天、網絡硬盤、動態(tài)新聞等信息,開通手機上的移動QQ服務,并且于年5月中旬推出了QQ2004版軟件,同時為每一個QQ賬號送一個5M的免箱。2.2.3MSN軟件巨頭微軟開發(fā)了MSNMessenger,把MSNMessenger嵌WindowsXP操作系統(tǒng)里。MSNMessenger有近30種語言的不同版本。您還使用此免費程序撥打電話,用交談取代輸入,向手機發(fā)送消息,監(jiān)視新的電件,共享圖片或其他任何文件,邀請朋友玩DirectPlay兼容游戲等等。目前Messenger已經推出ver6.2,在功能和外觀上都有很大的變化,在外觀界面也比以前的版本更加生動。2.2.4雅虎通Yahoo!Messenger(雅虎通)是由美國著名綜合門戶類網站Yahoo!推出的聊天軟件。Yahoo!Messenger的功能側重點似乎并不在它的聊天功能上,它更像一個免息提供器。Yahoo!Messenger支持多種操作系統(tǒng),并支持其它便攜式無線具有與其它即時通訊軟件所不同的商業(yè)價值。你不僅可以隨時查看新聞和天報,甚至可以隨時查閱股票行情。你還能利用Yahoo!Messenger安排自己的行程計劃,隨時收發(fā)新郵件。2.2.5朗瑪UC朗瑪UC是2002年里新涌現的即時通訊軟件代表,它的開發(fā)者想通過電子科技大學碩士學位論文:企業(yè)即時通訊系統(tǒng)服務器的設計。UC給大家?guī)磉@樣一個全新的聊天理念:新一代開放式即時通訊娛樂平臺瑪UC也的確給了我們一種前所未有的聊天新感覺:網上聊天,也可以情景它采用自由變換場景、個性在線心情等人性化設計,配合視頻電話、信息文件互傳、在線游戲等使您在聊天的同時能邊說、邊看、邊玩。2.3即時通訊軟件在企業(yè)中的運用情況簡介目前流行的即時通訊軟件都有其各自的特點,但它們多是針對的是個人用戶,而不是大企業(yè)用戶。目前,即時通訊件從開始的單一的信息實時交流,發(fā)展到如今的集即時在線娛樂、視頻會議以及手機短信等諸多功能于一體。如此迅猛的發(fā)展多企業(yè)用戶考慮使用即時通訊來提高內部交流的質量,理順內部交流渠道內部交流成本。尤其對跨國的大公司大集團更是有迫切的需要。事實上,企時通信工具在國外一些企業(yè)已經被廣泛應用,比如IBM通過使用即時通信所節(jié)省下來的國際電話費及差旅費,每年就可節(jié)省四億美元。然而即時通訊軟件也給企業(yè)用戶帶來了一定的尷尬和困難。目前,尤其是大型企業(yè),大都有自己的Intranet網絡,其大多的工作流或內流都可以通過內部的Intranet完成。如果企業(yè)中員工都使用目前免費的幾種通訊軟件,則必須對這些使用進行嚴格的審計和管理,這無疑給IT部門的帶來了一定的麻煩。加之,由于網絡的虛擬性,即時通訊軟件均允許自己任意命名,這更給用戶的管理帶來了不便。綜合分析以上原因,本文認為,有必要自主開發(fā)應用于企業(yè)的即時通訊系統(tǒng)軟件。從調研結果來看,盡管目前有多種即時通訊產品的問世,有的產品有良好的客戶群體,但商業(yè)機構的實踐活動由于其實用化的取向,所以在即時通訊研究工作方面并不活躍。同時,出于商業(yè)機密的考慮,根本就沒有公開論著學術化的即時通訊研究,國外公開發(fā)表的論文也非常少。通訊基本服務元素的定義方面。還有部分關于安全性的討論從“中國期刊網”和“萬方數字化期刊”等國內論文調研的情況看來,部分文章是商業(yè)即時通訊工具的使用介紹。雖然有少數幾篇討論“網絡傳呼編程技巧的論文,但普遍存在一些誤解,如把即時通訊系統(tǒng)等同于聊天甚至還把即時通訊系統(tǒng)混淆成網絡聊天室,而后者事實上是采用網絡中轉聊議[9](InternetRelayChatProtocol,IRCP)的網站服務??偟恼f來,國內外關于即時通訊的研究還不夠系統(tǒng)和深入。本系統(tǒng)就是在此時企業(yè)即時通信市場日益高漲的時候,采用先進的JavaSocket技術,開發(fā)出一個C/S模式的基于TCP/UDP協(xié)議的網絡通信系統(tǒng).該系統(tǒng)充分利用了Java的跨平臺性,結合目前已有的典型通訊軟件BBS和OICQ的某些技術,采用TCP/UDP協(xié)議與服務器轉發(fā)的技術,擴展了文件發(fā)送的功能,使得客戶間發(fā)送文件不受防火墻限制.同時在時間允許的情況下增加語音、視頻以及網絡電視等功能。3相關技術簡介該即時通信系統(tǒng)是在客戶端/服務器程序設計范式基礎上按照軟件工程設計思想,采用大量的計算機程序設計技術和網絡通信技術設計并實現的。本章將介紹主流的網絡通信模型、網絡通信技術、密碼學相關知識和程序設計主要采用的Windows編程技術。3.1主流的網絡通信模型3.1.1C/S(Client/Server,客戶/服務器)模型,該模型可以合理利用兩端硬件環(huán)境優(yōu)勢,將任務合理分配到客戶端和服務器,降低系統(tǒng)通信開銷[7]。在這種結構中,服務器處于系統(tǒng)的中心地位。服務器是一個擁有強大處理能力和很大帶寬的高性能計算機,數據和信息都保存在服務器上。服務器始終處于工作狀態(tài),它被動地接受客戶連接,根據客戶的請求提供相應的服務。體系結構如圖2.1所示。C/S結構可分為傳統(tǒng)的兩層結構和新型的三層結構。二層結構出現在20世紀80年代后期。在這種結構中,服務器只負責各種數據的處理和維護,為各個客戶機應用程序管理數據;客戶機中有文檔處理軟件、決策支持工具、數據查詢等應用邏輯程序,采用SQL語句發(fā)送請求和分析從服務器接收的數據。這是一種“胖客戶機(FatClient)”、“瘦服務器(ThinServer)”的網絡結構模式。其軟件模型如圖2.2所示。隨著其應用范圍的不斷擴大,兩層結構帶來的系統(tǒng)可靠性低、缺乏靈活性、資源浪費嚴重以及維護費用較高等問題日益明顯,網絡計算模式逐漸從兩層模式擴展到三層模式。在三層結構中,應用邏輯程序從客戶機上分離出來,進而發(fā)展為應用服務器或Web服務器。這是一種“瘦客戶機”網絡結構模式,客戶端只有界面顯示程序,只需在服務器端隨機增加應用服務即可滿足系統(tǒng)的需要,可以用較少的資源建立起具有很強伸縮性的系統(tǒng),這也是當前Internet上最先進的技術之一。其軟件模型如圖2.3所示。3.1.2B/S模型B/S(Browser/Server,瀏覽器/服務器)模型,是隨著Internet技術的興起,對C/S結構的一種變化和改進的結構。該結構使用瀏覽器通過HTTP協(xié)議訪問Web服務器。B/S三層結構如圖2.4所示。在B/S三層結構中,數據庫服務器(DBServer)使用關系數據庫存儲系統(tǒng)中所有的數據,WebServer處理客戶端的請求??蛻舳耸褂脼g覽器訪問WebServer,功能更加簡單,它只顯示數據和提供用戶輸入界面的功能,絕大多數的計算都在WebServer上。這種“瘦客戶”的思想非常適于系統(tǒng)部署。3.1.3P2P模型P2P(PeertoPeer,對等連接或對等網絡)模型,是指網絡中的物理節(jié)點在邏輯上以相同的地位進行通信的模型,而不是處理能力的對等[8]。相對于傳統(tǒng)的集中式C/S模型,其弱化了服務器的概念,系統(tǒng)中的各個節(jié)點不再區(qū)分服務器和客戶端的角色關系,每個節(jié)點既可請求服務,也可提供服務,節(jié)點之間可以直接交換資源和服務而不必通過服務器[9]。P2P的最大特點就是用戶之間直接共享資源,使得PC不再是被動的客戶端,而成為具有服務器和客戶端雙重特征的設備。目前P2P的構架手段主要有集中目錄式P2P、純P2P和混合P2P模式三種,如圖2.5從左至右所示。集中目錄式P2P是最早出現的P2P應用模式,也稱為非純粹的P2P結構,仍然具有中心化的特點,用于共享MP3音樂文件的Napster是最典型的代表。在這種模型中,所有的節(jié)點都和中心目錄服務器建立連接,中心目錄服務器負責所有節(jié)點的內容,當節(jié)點發(fā)出請求時,中心目錄服務器會根據節(jié)點的請求找出符合該節(jié)點要求的節(jié)點,然后文件交換就直接在這兩個節(jié)點之間進行。純P2P模型完全沒有了索引的概念,資源隨機地分布在系統(tǒng)中所有的節(jié)點中,每個節(jié)點的請求都會廣播給所有和它直接相連的節(jié)點,如果這些節(jié)點中都沒有所請求的文件,這些節(jié)點會把這個請求繼續(xù)廣播給所有和他們直接相連的節(jié)點,直到找到所請求的文件或者廣播的次數超過了某個值?;旌鲜絇2P吸取了中心化P2P和純P2P的優(yōu)點,選擇性能(處理、存儲、帶寬等方面)較高的節(jié)點作為超級節(jié)點,在各個超級節(jié)點上存儲了系統(tǒng)中其他部分結點的信息。混合式P2P中,搜索數據包僅在超級節(jié)點之間轉發(fā),由超級節(jié)點將搜索請求轉發(fā)給適當的葉子節(jié)點。3.2TCP/IP協(xié)議和OSI模型3.2.1OSI模型OSI(OpenSystemsInterconnection),即開放式通信系統(tǒng)互聯參考模型,是國際標準化組織(ISO)提出的一個試圖使各種計算機在世界范圍內互連為網絡的標準框架。OSI定義了開放系統(tǒng)的層次結構、層次之間的相互關系以及各層所包括的可能的任務,它本身并不是一個標準,而是一個在制定標準時使用的概念性框架,是作為一個框架來協(xié)調和組織各層所提供的服務的[10]。OSI模型由7個層組成,每一層都處理特定的通信任務。如圖2.6所示。在單臺機器中,每一層通過兩層間的層間接口調用下一層的服務,取出對該層有意義的數據;機器之間則是使用某個給定層的協(xié)議的對等進程進行通信[11]。這種通信由一些協(xié)議來控制,協(xié)議就是實現雙方都同意的一組規(guī)則和約定。對等進程是指每一個機器的某個給定層上進行通信的進程。3.2.2TCP/IP協(xié)議TCP/IP(TransmissionControlProtocol/InternetProtocol),即傳輸控制協(xié)議/互聯網絡協(xié)議,是美國的國防部高級計劃研究局DARPA為實現ARPANET(后來發(fā)展為Internet)互連網而開發(fā)的。該協(xié)議是Internet國際互聯網絡的基礎和事實上的標準,其規(guī)范了網絡上的所有通信設備,尤其是兩臺主機之間的數據往來格式以及傳送方式[12]。TCP/IP協(xié)議由應用層、傳輸層(TCP)、網絡層(IP)和數據鏈路層(包括物理層)四層組成,與OSI模型的對應關系如圖2.7所示。在物理和數據鏈路層中TCP/IP并沒有定義任何特定的協(xié)議,它支持所有標準的和專用的協(xié)議。網絡層提供主機到主機的通信服務,負責將分組從發(fā)送主機送到接收主機。網絡層通過選路算法和協(xié)議為分組選擇通過通信子網最適當的路徑,并通過路由器的將數據報從源主機轉發(fā)到目的地主機。傳輸層的作用是將兩個端系統(tǒng)間的IP交付服務擴展為運行在兩個端系統(tǒng)上的進程之間的交付服務,提供進程邏輯通信功能[13]。傳輸層協(xié)議是在端系統(tǒng)而不是在路由器中實現的,其中包括UDP和TCP。應用層為不同的端系統(tǒng)提供通過計算機網絡交換報文互相通信的功能。應用層協(xié)議定義了進程間交換的報文格式和順序,以及傳輸和接收到報文時采取的動作,其中包括交換的報文類型、報文類型的語法、字段的語義、報文響應規(guī)則等[14]。3.2.3套接字WinSock是一套開放的、支持多種協(xié)議的Windows網絡編程接口,是Windows網絡編程事實上的標準。應用程序通過WinSockAPI設計通信程序,WinSock利用網絡通信協(xié)議和操作系統(tǒng)調用完成實際的通信工作。(1)套接字基本概念套接字(socket)是內核對象中的一種通信結構,它提供網絡進程間的數據通信功能。形象上說套接字就是進程的門戶[15]。套接字地址是套接字通信結構的描述和定義。套接字描述符就是一個整數類型的值,在Windows中的類型是SOCKET。套接字描述符實質是某套接字內核對象的一個“句柄”,套接字描述符所在的進程則通過該“句柄”訪問和操作該套接字。每個進程的進程空間里都有一個套接字描述符表,該表中存放著套接字描述符和套接字數據結構的對應關系。該表中有一個字段存放新創(chuàng)建的套接字的描述符,另一個字段存放套接字數據結構的地址。因此根據套接字描述符就可以找到其對應的套接字數據結構。每個進程在自己的進程空間里都有一個套接字描述符表,但是套接字數據結構都是在操作系統(tǒng)的內核緩沖里,可供多個進程使用。(2)套接字通信模式和I/O模式Windows套接字執(zhí)行I/O操作可以設定為鎖定或非鎖定模式。在鎖定模式下,在I/O操作完成前執(zhí)行操作的Winsock函數(如send和racy)會一直等待下去,而不會返回并將控制權交給程序。在非鎖定模式下無論結果如何,Winsock函數的調用都會立即返回。因此,這種套接字需要選擇一種I/O模型來幫助應用程序判斷一個套接字何時可供讀寫。Windows操作系統(tǒng)提供了五種套接字I/O模型,分別為選擇(Select)、異步消息(WSAAsyncSelect)、事件通知(WSAEventSelect)、重疊I/O(OverlappedI/O)和完成端口(CompletionPort)模型[16][17]。Select模型是Winsock中最常見的I/O模型。通過調用Select函數可確定一個或多個套接字的狀態(tài),判斷套接字上是否存在數據,或者能否向一個套接字寫入數據。它既能防止應用程序在套接字處于阻塞模式時,在一次I/O操作后被阻塞,同時也防止在套接字處于非鎖定模式時,產生WSAEWOULDBLOCK錯誤,提示請求的操作在調用期間沒有時間完成。WSAAsyncSelect模型也是一個常用的異步I/O模型。利用這個模型,應用程序可在一個套接字上接受以Windows消息為基礎的網絡事件通知。該模型的實現方法是通過調用WSAAsyncSelect函數自動將套接字設置為非阻塞模式,并向WinsockDLL注冊一個或多個感興趣的網絡事件,并提供一個通知時使用的窗口句柄,當網絡事件發(fā)生時,對應的窗口將收到一個基于消息的通知。WSAEventSelect模型是Winsock提供的另一個有用的異步I/O模型,它允許應用程序在一個或多個套接字上,接收以事件為基礎的網絡事件通知。該模型的關鍵是網絡事件會被發(fā)送到一個事件句柄,而不是發(fā)送到一個窗口。OverlappedI/O模型可以使應用程序達到更佳的性能。它的基本原理是讓應用程序使用一個重疊的數據結構,一次投遞一個或多個WinsockI/O請求,針對那些提交的請求,在它們完成之后,應用程序可為他們提供服務。CompletionPort模型是迄今為止最為復雜的一種I/O模型。假如要為WindowsNT或Windows2000開發(fā)高性能的服務器應用,希望同時為數百乃至上千個套接字I/O請求提供服務(如Web服務器),那么I/O完成端口模型便是最佳選擇,其可以達到最佳的系統(tǒng)性能!隨著系統(tǒng)內安裝的CPU數量的增多,應用程序的性能也可以線性提升。(3)I/O模型的選擇和性能提高開發(fā)服務器應用時,一般需要同時管理多個套接字,因此采取重疊I/O模型是比較符合需求的;若需要同時管理成百上千的套接字,則需要考慮采用完成端口模型,以獲得更好的性能[16]。開發(fā)客戶機應用時,一般只需同時管理一個或幾個套接字,采用事件通知模型即可。若開發(fā)的是基于Windows窗口例程的程序,那么采用異步消息模型應該是更好的選擇,該程序已經具備了處理消息的能力。3.3程序采用的主要技術3.3.1線程由線程的內核對象和線程堆棧兩部分組成。操作系統(tǒng)通過內核對象對線程實施管理,其中存放了系統(tǒng)關于線程的統(tǒng)計信息。線程堆棧用于維護線程在執(zhí)行代碼時需要的所有函數參數和局部變量[21]。線程只有一個內核對象和一個堆棧,保留的記錄很少,也只需很少的內存,因此創(chuàng)建線程的開銷遠比創(chuàng)建進程少。在實際編程過程中應根據實際情況設法通過增加線程來解決編程問題,而要盡量避免創(chuàng)建新的進程。線程分為兩種:用戶接口線程和輔助線程。用戶接口線程常用于接收用戶的輸入,處理相應的事件和消息。輔助線程編程較為簡單,一個基本函數代表一個線程,創(chuàng)建并啟動線程后,則線程進入運行狀態(tài)。進程的主線程在任何時候都可以創(chuàng)建新的線程,當線程執(zhí)行完成任務后,自動中止線程;當進程結束后,所有的線程都中止[22]。所有活動的線程共享進程的資源。3.3.2客戶/服務器程序設計范式是在設計C/S網絡通信控制或者數據交互的應用中總結出來的一些具有代表性的、可以給其它程序設計提供范例的程序設計框架,在實際應用中具有指導和規(guī)范作用。該類程序的客戶程序的編寫通常比服務器程序容易些,因為客戶中進程或者線程的控制要少得多。因此,設計范式主要也是針對服務器程序的設計,主要分為迭代服務器和并發(fā)服務器兩大類[24][25]。(1)迭代服務器迭代服務器(IterativeServer)的工作模式是在一個循環(huán)中依次完成每個客戶的請求完成后再執(zhí)行一個循環(huán)的工作過程。該模式總是在處理完某個客戶的請求之后才轉向下一個客戶,在執(zhí)行某任務期間不會偵聽和處理其它任何任務。其依次執(zhí)行接受連接、處理請求、關閉連接、等待下一個連接四個循環(huán)步驟。這樣的服務器程序比較少見,其中沒有進行任何的進程或線程控制。(2)并發(fā)服務器,每個客戶一個進程該并發(fā)服務器(ConcurrentServer)直接派生子進程來處理每個客戶,服務器通過多個子進程同時為多個客戶服務??蛻魯的康奈ㄒ幌拗剖遣僮飨到y(tǒng)對于以其名義運行服務器的用戶ID能夠同時擁有多少子進程的限制。其缺點是該并發(fā)服務器需要耗費大量CPU時間為每個客戶現場派生一個子進程。隨著網絡應用的爆發(fā)式增長,這種模式的服務器顯得無法適應現代的需要。該模式的增強模式就是采取預先派生子進程技術,在啟動階段就派生一定數量的子進程,當每個客戶連接到達時,這些子進程立即就能提供服務。這種技術的優(yōu)點在于無須引入父進程執(zhí)行派生進程的開銷就能處理新到的客戶,缺點是父進程必須在服務器啟動階段猜測需要預先派生多少子進程,以避免造成子進程數量過多造成計算機資源浪費或者數量不夠導致后續(xù)連接的客戶端無法正常工作。(3)并發(fā)服務器,每個客戶一個線程該類服務器為每個客戶創(chuàng)建一個線程,以減少為每個客戶派生子進程的第二章系統(tǒng)程序設計思想和方法15資源消耗,因為一個線程占用的資源遠比一個子進程占用的資源要少得多。程序設計中也可以在服務器啟動階段預先創(chuàng)建一個線程池以取代為每個客戶現場創(chuàng)建一個線程的做法以提高性能加速。在等待客戶端連接時則可以每個線程各自accept,其中采用互斥鎖保護,也可以由主線程統(tǒng)一accept。本程序的設計是采取由主線程統(tǒng)一accept并創(chuàng)建工作線程的。在并發(fā)服務器中選擇進程還是線程來設計需要根據實際的情況決定。進程是一種代價昂貴的東西,它們在啟動、清除、被操作系統(tǒng)追蹤記錄等方面都需要消耗大量的CPU時間。進程和線程之間的代價幾乎相差2~3個數量級。系統(tǒng)同時存在500個線程猶有可能,但同時存在500個進程絕無可能。每秒鐘產生和摧毀許多個線程是可能的,每秒鐘產生和摧毀許多個進程則是不可能的。但是進程的安全性和穩(wěn)定性更強,子進程崩潰并不影響主進程的正常運行,而進程中的一個線程出現問題則就會導致該進程的垮掉[26]。3.4MySQL簡介MySQL是最流行的開放源碼SQL數據庫管理系統(tǒng),它是由MySQLAB公司開發(fā)、發(fā)布并支持的。MySQLAB是由多名MySQL開發(fā)人創(chuàng)辦的一家商業(yè)公司。它是一家第二代開放源碼公司,結合了開放源碼價值取向、方法和成功的商業(yè)模型。在MySQL的網站(/)上,給出了關于MySQL和MySQL的最新信息。(1)MySQL是一種數據庫管理系統(tǒng)。數據庫是數據的結構化集合。它可以是任何東西,從簡單的購物清單到畫展,或企業(yè)網絡中的海量信息。要想將數據添加到數據庫,或訪問、處理計算機數據庫中保存的數據,需要使用數據庫管理系統(tǒng),如MySQL服務器。計算機是處理大量數據的理想工具,因此,數據庫管理系統(tǒng)在計算方面扮演著關鍵的中心角色,或是作為獨立的實用工具,或是作為其他應用程序的組成部分。(2)MySQL是一種關聯數據庫管理系統(tǒng)。關聯數據庫將數據保存在不同的表中,而不是將所有數據放在一個大的倉庫內。這樣就增加了速度并提高了靈活性。MySQL的SQL指得是“結構化查詢語言”。SQL是用于訪問數據庫的最常用標準化語言,它是由ANSI/ISOSQL標準定義的。SQL標準自1986年以來不斷演化發(fā)展,有數種版本。在本手冊中,“SQL-92”指得是1992年發(fā)布的標準,“SQL:1999”指得是1999年發(fā)布的標準,“SQL:2003”指得是標準的當前版本。我們采用術語“SQL標準”標示SQL標準的當前版本。(3)MySQL軟件是一種開放源碼軟件?!伴_放源碼”意味著任何人都能使用和改變軟件。任何人都能從Internet下載MySQL軟件,而無需支付任何費用。如果愿意,你可以研究源碼并進行恰當的更改,以滿足你自己的需求。MySQL軟件采用了GPL(GNU通用公共許可證),/licenses/,定義了在不同情況下可以用軟件作的事和不可作的事。如果你對GPL不滿意,或需要在商業(yè)應用程序中嵌入MySQL代碼,可從我方購買商業(yè)許可版本。更多信息,請參見MySQL許可概述(/company/legal/licensing/)。(4)MySQL數據庫服務器具有快速、可靠和易于使用的特點。如果它正是你所尋找的,不妨一試。MySQL服務器還有一套實用的特性集合,這些特性是通過與我們用戶的密切合作而開發(fā)的。在我們的基準測試主頁上,給出了MySQL服務器和其他數據庫管理器的比較結果。請參見\o"7.1.4.
TheMySQLBenchmarkSuite"7.1.4“MySQL基準套件”。MySQL服務器最初是為處理大型數據庫而開發(fā)的,與已有的解決方案相比,它的速度更快,多年以來,它已成功用于眾多要求很高的生產環(huán)境。盡管MySQL始終在不斷發(fā)展,但目前MySQL服務器已能提供豐富和有用的功能。它具有良好的連通性、速度和安全性,這使的MySQL十分適合于訪問Internet上的數據庫。(5)MySQL服務器工作在客戶端/服務器模式下,或嵌入式系統(tǒng)中。MySQL數據庫軟件是一種客戶端/服務器系統(tǒng),由支持不同后端的1個多線程SQL服務器,數種不同的客戶端程序和庫,眾多管理工具和廣泛的應用編程接口API組成。我們還能以嵌入式多線程庫的形式提供MySQL服務器,你可以將其鏈接到你的應用程序,從而獲得更小、更快、和更易管理的產品。4系統(tǒng)設計4.1總體設計本系統(tǒng)主要是模仿QQ聊天系統(tǒng)設計的一個基于C/S結構的簡單的聊天系統(tǒng)。系統(tǒng)采用的客戶/服務器摸式其基本結構如圖所示:4.2系統(tǒng)功能設計本系統(tǒng)實現了簡單的新用戶注冊,用戶登陸,用戶直接根據號碼查找添加好友和根據在線的用戶信息查找來添加好友,同時可以查看在線的用戶信息,向在線的用戶發(fā)送消息,用戶接收消息等。系統(tǒng)功能圖如下所示:即時聊天系統(tǒng)即時聊天系統(tǒng)用戶登陸用戶注冊直接查找好友好友查找更新用戶信息更新用戶刪除好友信息查看發(fā)送信息接收信息4.3數據庫設計系統(tǒng)可以采用任何一種流行的Java支持的數據庫。本系統(tǒng)采用了MySQL作為后臺數據庫。通過對現在流行的聊天軟件ICQ進行參考,建立數據庫,名為javaicq。數據庫共建立兩個表,一個是用戶的基本信息,包括呢稱及Jicq號碼等。一個是用戶的好友列表,包括用戶自己的號碼和好友的號碼。(1)用戶的基本信息表(表名icq)序號 字段名 含義 數據類型 NULL1 Icqno 用戶的號碼 int No2 Nickname 用戶的呢稱 Char No3 Password 用戶的密碼 Char No4 Status 用戶在線否 Bit No5 Ip 用戶的IP地址 Char Yes6 Info 用戶的資料 Varchar Yes7 Pic 用戶的頭像號 Int Yes8 Sex 用戶性別 Char Yes9 Email 用戶的email Char Yes10 Place 用戶的籍貫 Char yes其中Icqno字段為自動增加。(其他還可以添加諸如電話號碼等字段作為更多選擇)(2)用戶的好友表(表名friend)序號 字段名 含義 數據類型 NULL1 Icqno 用戶的號碼 Int No2 Friend 好友的號碼 Int No5詳細的設計與實現5.1服務器程序服務器與客戶間通過套接口Socket(TCP)連接。在java中使用套接口相當簡單,JavaAPI為處理套接口的通信提供了一個類.Socket.,使得編寫網絡應用程序相對容易.服務器采用多線程以滿足多用戶的請求,通過JDBC與后臺數據庫連接,并通過創(chuàng)建一個ServerSocket對象來監(jiān)聽來自客戶的連接請求,默認端口為8080,然后無限循環(huán)調用accept()方法接受客戶程序的連接。具體實現代碼如下所示:classServerThreadextendsThread{//繼承線程privateSocketsocket;//定義套接口privateBufferedReaderin;//定義輸入流privatePrintWriterout;//定義輸出流intno;//定義申請的jicq號碼intnumber;publicServerThread(Sockets,intnum)throwsIOException{//線程構造函數number=num; socket=s;//取得傳遞參數in=newBufferedReader(newInputStreamReader(socket.getInputStream()));//創(chuàng)建輸入流out=newPrintWriter(newBufferedWriter(newOutputStreamWriter(socket.getOutputStream())),true);//創(chuàng)建輸出流start();//啟動線程}publicvoidrun(){ //線程監(jiān)聽函數try{ while(true){Stringstr=in.readLine();//取得輸入字符串if(str.equals("end"))break;//如果是結束就關閉連接elseif(str.equals("login")){//如果是登錄 try{ Class.forName("com.mysql.jdbc.Driver"); Connectionc=DriverManager.getConnection("jdbc:mysql://localhost/javaicq","root","");Stringicqno=in.readLine();intg=Integer.parseInt(icqno);//取得輸入的jicq號碼Stringpasswd=in.readLine().trim();//取得輸入的密碼Stringsql="selectnickname,passwordfromicqwhereicqno='"+icqno+"'";Statementprepare=c.createStatement();ResultSetr=prepare.executeQuery(sql);//執(zhí)行數據庫查尋if(r.next()){//以下比較輸入的號碼于密碼是否相同Stringpass=r.getString("password").trim();//System.out.println(pass);if(passwd.regionMatches(0,pass,0,pass.length())){out.println("ok");Stringip=socket.getInetAddress().getHostAddress();Stringsetip="updateicqsetip='"+ip+"'whereicqno='"+icqno+"'";Statementprest=c.createStatement();intset=prest.executeUpdate(setip);Stringstatus="updateicqsetstatus=1whereicqno='"+icqno+"'";Statementset2=c.createStatement();set2.executeUpdate(status);System.out.println(set2);//setonline}//否者告訴客戶失敗elseout.println("false");r.close();c.close();}else{out.println("false");System.out.println("false");r.close();c.close();}}catch(Exceptione){e.printStackTrace();}socket.close();}//endlogin//登錄結束//以下為處理客戶的新建請求elseif(str.equals("new")){ number=number+1; try{ Class.forName("com.mysql.jdbc.Driver"); Connectionc2=DriverManager.getConnection("jdbc:mysql://localhost/javaicq","root","");//準備接受用戶的呢稱,密碼,email,個人資料,籍貫,頭像等信息//PreparedStatementprepare2=c2.prepareCall(newsql);Stringnickname=in.readLine().trim();Stringpassword=in.readLine().trim();Stringemail=in.readLine().trim();Stringinfo=in.readLine().trim();Stringplace=in.readLine().trim();intpicindex=Integer.parseInt(in.readLine());Stringnewsql="insertintoicq(icqno,nickname,password,email,info,place,pic)values('"+number+"','"+nickname+"','"+password+"','"+email+"','"+info+"','"+place+"','"+picindex+"')";//intr3=prepare2.executeUpdate();//執(zhí)行數據庫添加Statementpre2=c2.createStatement();pre2.executeUpdate(newsql);Stringsql2="selecticqnofromicqwherenickname='"+nickname+"'";//以下告訴客戶其注冊的號碼Statementpre3=c2.createStatement();ResultSetr2=pre3.executeQuery(sql2);while(r2.next()){//out.println(r2.getInt(1));no=r2.getInt(1);System.out.println(no);}out.println(no);out.println("ok");c2.close();//完畢}catch(Exceptione){e.printStackTrace();out.println("false");}socket.close();}//endnew//新建用戶結束//以下處理用戶查找好友elseif(str.equals("find")){ try{ Class.forName("com.mysql.jdbc.Driver"); Connectionc3=DriverManager.getConnection("jdbc:mysql://localhost/javaicq","root",""); //以下連接數據庫,并且返回其他用戶的呢稱,性別,籍貫,個人資料等信息 Stringfind="selectnickname,sex,place,ip,email,infofromicq";Statementst=c3.createStatement();ResultSetresult=st.executeQuery(find);while(result.next()){out.println(result.getString("nickname"));out.println(result.getString("sex"));out.println(result.getString("place"));out.println(result.getString("ip"));out.println(result.getString("email"));out.println(result.getString("info"));}//whileendout.println("over");intd,x;booleany;//以下返回用戶的jicq號碼,頭像號,及是否在線ResultSetiset=st.executeQuery("selecticqno,pic,statusfromicq");while(iset.next()){d=iset.getInt("icqno");out.println(d);x=iset.getInt("pic");//picinfoout.println(x);y=iset.getBoolean("status");if(y){out.println("1");}else{out.println("0");}//System.out.println(d);}iset.close();c3.close();result.close();}catch(Exceptione){e.printStackTrace();System.out.println("false");}//socket.close();}//endfind//查找好友結束//以下處理用戶登錄時讀取其好友資料elseif(str.equals("friend")){ try{ Class.forName("com.mysql.jdbc.Driver"); Connectionc4=DriverManager.getConnection("jdbc:mysql://localhost/javaicq","root",""); //以下連接好友表,返回用戶的好友名單inticqno=Integer.parseInt(in.readLine());System.out.println(icqno);//prepare4.setInt(1,icqno);Stringfriend="selectfriendfromfriendwhereicqno='"+icqno+"'";Statementpre4=c4.createStatement();ResultSetr4=pre4.executeQuery(friend);Vectorfriendno=newVector();//該矢量保存好友號碼while(r4.next()){friendno.add(newInteger(r4.getInt(1)));}//以下告訴客戶其好友的呢稱,號碼,ip地址,狀態(tài),頭像,個人資料等信息out.println(friendno.size());for(inti=0;i<friendno.size();i++){Stringfriendinfo="selectnickname,icqno,ip,status,pic,email,infofromicqwhereicqno='"+friendno.get(i)+"'";Statementpre5=c4.createStatement();ResultSetr5=pre5.executeQuery(friendinfo);booleanstatus;while(r5.next()){out.println(r5.getString("nickname"));out.println(r5.getInt("icqno"));out.println(r5.getString("ip"));status=r5.getBoolean("status");if(status)out.println("1");else{out.println("0");}out.println(r5.getInt("pic"));out.println(r5.getString("email"));out.println(r5.getString("info"));}//whiler5.close();}//for//發(fā)送完畢out.println("over");System.out.println("over");c4.close();r4.close();}catch(Exceptione){e.printStackTrace();System.out.println("false");}//socket.close();}//endfriend//讀取好友信息完畢//以下處理用戶添加好友elseif(str.equals("addfriend")){System.out.println("add");try{ Class.forName("com.mysql.jdbc.Driver"); Connectionc6=DriverManager.getConnection("jdbc:mysql://localhost/javaicq","root","");//連接數據庫,根據接受的用戶號碼及好友號碼向好友表添加記錄intfriendicqno=Integer.parseInt(in.readLine());System.out.println(friendicqno);intmyicqno=Integer.parseInt(in.readLine());System.out.println(myicqno);Stringaddfriend="insertintofriendvalues('"+myicqno+"','"+friendicqno+"')";Statementpre6=c6.createStatement();intr6=0;//r6=prepare6.executeUpdate();r6=pre6.executeUpdate(addfriend);if(r6==1)System.out.println("okaddfrien");elseSystem.out.println("falseaddfriend");}catch(Exceptione){e.printStackTrace();System.out.println("false");}//socket.close();System.out.println("overaddfriend");}//endaddfriend//用戶添加好友結束//addnewfriendwhoaddme//以下處理其他用戶如果加我,我就加他elseif(str.equals("addnewfriend")){System.out.println("add");try{ Class.forName("com.mysql.jdbc.Driver"); Connectionc6=DriverManager.getConnection("jdbc:mysql://localhost/javaicq","root",""); //連接數據庫,根據接受的用戶號碼及好友號碼向好友表添加記錄intfriendicqno=Integer.parseInt(in.readLine());System.out.println(friendicqno);intmyicqno=Integer.parseInt(in.readLine());System.out.println(myicqno);Stringaddfriend="insertintofriendvalues('"+myicqno+"','"+friendicqno+"')";Statementpre6=c6.createStatement();intr6=0;r6=pre6.executeUpdate(addfriend);if(r6==1)System.out.println("okaddfriend");elseSystem.out.println("falseaddfriend");Stringfriendinfo="selectnickname,icqno,ip,status,pic,email,infofromicqwhereicqno='"+friendicqno+"'";//如果成功,就向用戶傳遞好友的基本信息,比如呢稱等Statementpre5=c6.createStatement();ResultSetr5=pre5.executeQuery(friendinfo);booleanstatus;while(r5.next()){System.out.println("dsf");out.println(r5.getString("nickname"));out.println(r5.getInt("icqno"));out.println(r5.getString("ip"));status=r5.getBoolean("status");if(status)out.println("1");else{out.println("0");}out.println(r5.getInt("pic"));out.println(r5.getString("email"));out.println(r5.getString("info"));}//whileout.println("over");r5.close();c6.close();}catch(Exceptione){e.printStackTrace();System.out.println("false");}System.out.println("overaddnewfriend");}//endaddfriend友elseif(str.equals("delfriend")){System.out.println("del");try{ Class.forName("com.mysql.jdbc.Driver"); Connectionc7=DriverManager.getConnection("jdbc:mysql://localhost/javaicq","root","");//連接數據庫,根據接受的用戶號碼及好友號碼向好友表刪除記錄intfriendicqno=Integer.parseInt(in.readLine());System.out.println(friendicqno);intmyicqno=Integer.parseInt(in.readLine());System.out.println(myicqno);Stringaddfriend="deletefromfriendwhereicqno='"+myicqno+"'andfriend='"+friendicqno+"'";Statementpre7=c7.createStatement();intr7=0;r7=pre7.executeUpdate(addfriend);if(r7==1)System.out.println("okdelfrien");//成功elseSystem.out.println("falsedelfriend");//失敗}catch(Exceptione){e.printStackTrace();System.out.println("delfalse");}}//enddeletefriend//執(zhí)行用戶刪除好友結束elseif(str.equals("logout")){ try{Class.forName("com.mysql.jdbc.Driver"); Connectionc8=DriverManager.getConnection("jdbc:mysql:
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 船舶貨運技術課程設計
- 二零二五年度高空作業(yè)風險評估免責協(xié)議3篇
- 2025年度生態(tài)停車車庫租賃與綠化養(yǎng)護協(xié)議3篇
- 二零二五年度民間借貸債權債務轉讓授權委托合同4篇
- 2024影視作品攝制及發(fā)行權轉讓合同
- 2024鋪面裝修與電子商務平臺接入合同3篇
- 2025年建筑用石材雕刻及供應合同范本3篇
- 2025年度旅游景區(qū)旅游信息化建設與運維合同4篇
- 2025年度個人購置山地別墅及生態(tài)園林維護協(xié)議4篇
- 2024童鞋銷售網絡建設與運營合同范本3篇
- 全國醫(yī)學博士英語統(tǒng)一考試詞匯表(10000詞全) - 打印版
- 最新《會計職業(yè)道德》課件
- 廣東省湛江市各縣區(qū)鄉(xiāng)鎮(zhèn)行政村村莊村名明細
- DB64∕T 1776-2021 水土保持生態(tài)監(jiān)測站點建設與監(jiān)測技術規(guī)范
- ?中醫(yī)院醫(yī)院等級復評實施方案
- 數學-九宮數獨100題(附答案)
- 理正深基坑之鋼板樁受力計算
- 學校年級組管理經驗
- 10KV高壓環(huán)網柜(交接)試驗
- 未來水電工程建設抽水蓄能電站BIM項目解決方案
- 房屋出租家具電器清單
評論
0/150
提交評論