




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、內(nèi)容: 消息系統(tǒng)的建立 服務(wù)器的結(jié)構(gòu) 端口監(jiān)聽線程類PORTListenThread 單個客戶端在連接池中的映像類ClientSingle 分組轉(zhuǎn)發(fā)的實現(xiàn)類Group 主服務(wù)器類Server 總結(jié) 關(guān)于作者 侯光敏 (wearebug 2002 年 7 月 本文詳細(xì)的介紹了使用Java語言建立一套多線程服務(wù)器的過程,該服務(wù)器使用對象傳遞消息,在線程中使用隊列機(jī)制,使服務(wù)器的性能大大提高了。這套服務(wù)器可以被用于各種C/S或B/S結(jié)構(gòu)的應(yīng)用程序中。 Java語言是完全面向?qū)ο蟮?,它的線程機(jī)制和對象序列化特別容易使用,使用Java來建立一套多線程服務(wù)器要比使用其它語言方便的多,如果你再把它的異常處理
2、機(jī)制利用好,那么你就可以建立一個商業(yè)級的多線程服務(wù)器了。由于采用了消息隊列和Socket傳輸方式,所以不會出現(xiàn)丟消息的問題。這套服務(wù)器可以作為實時聊天服務(wù)器、多人協(xié)同的協(xié)作服務(wù)器等等。 消息系統(tǒng)的建立 這套服務(wù)器的消息系統(tǒng)采用的是對象傳輸?shù)臋C(jī)制,而不是以前常常使用的字符串傳輸。采用對象傳輸?shù)暮锰幨菙U(kuò)展方便,如需要建立一個新的消息只需要從一個統(tǒng)一的基類繼承下來,然后再寫自己實現(xiàn)的方法就行了。這樣也符合面向?qū)ο箢I(lǐng)域里一條重要的原則:OCP(open_closed Principle,即一個好的設(shè)計應(yīng)該能夠容納新的功能的增加,但是增加的方式不是修改原有的類,而是添加新的類。 首先建立一個基類:Msg
3、,該抽象類中有兩個域sender和receiver分別紀(jì)錄消息的發(fā)送者和接收者。這兩個域是在構(gòu)造消息類時就填寫的,receiver域可以為空,空表示發(fā)給誰都可以,由轉(zhuǎn)發(fā)服務(wù)器來決定。該類的方法包括取得這兩個域的值和消息的處理函數(shù)。消息的處理函數(shù)process(是空函數(shù),供繼承者重載。 建立了這個抽象基類后,你就可以繼承它完成你自己的類。舉個例子,假如我要建立一個分組協(xié)同工作的繪圖系統(tǒng),而且支持組員之間的對話,那么我可以建立如下的類集合: SendTextMsg(String sender,String receiver,String info/向指定的人發(fā)送對話。 AddLineMsg(Str
4、ing sender,Point a,Point b/在指定的點之間繪制一條直線 AddRectangle(String sender,point start,Point end/建立指定的矩形 AddRotundaMsg(String sender,Point center,int radius/建立指定的圓 RemoveObjectMsg(String sender,int ID/刪除指定編號的圖形對象 以此類推,可以建立很多的消息類。在每個類的內(nèi)部都由一個處理該類的方法process(,填寫該方法就可以實現(xiàn)對消息類的處理,而服務(wù)器只負(fù)責(zé)完成消息的轉(zhuǎn)發(fā)功能。這樣,一套消息系統(tǒng)就建立了。 服
5、務(wù)器的結(jié)構(gòu) 如果要服務(wù)器實現(xiàn)同時為每個客戶端服務(wù),就要使用多線程,建立一個線程池,當(dāng)有客戶端連接時就在池中開辟一個線程為它服務(wù)。同樣,要避免大量消息到達(dá)時處理不過來而導(dǎo)致丟失的情況,就要使用消息隊列。這個服務(wù)器是分層的處理的。 類關(guān)系圖如下所示: 服務(wù)器的工作過程是這樣的,建立了一個Server類作為主類,它含有程序的入口函數(shù)main(。在構(gòu)造函數(shù)中初始化一個數(shù)組存放ClientSingle類,它其實就是單獨處理一個連接用戶的類。然后啟動一個線程PORTListenThread,該線程的作用就是監(jiān)聽端口上有沒有人登陸,當(dāng)有人連接時交給Server的addClient(處理。Server的add
6、Client(方法會在剛才那個數(shù)組中建立一個ClientSingle對象,然后把剩下的事都交給它做。 端口監(jiān)聽線程類PORTListenThread 該線程類在run(函數(shù)的開始部分首先要檢查serverScoket是否為空,保證循環(huán)開始時不要出錯。然后進(jìn)入一個死循環(huán)的監(jiān)聽: while(true /死循環(huán)監(jiān) trySocket clientSocket=null; clientSocket=serverSocket.accept(; server.addClient(clientSocket;/轉(zhuǎn)交Server處理 catch (IOException eSystem.out.println
7、("監(jiān)聽端口時出錯"+e;/顯示錯誤 單個客戶端在連接池中的映像類ClientSingle 每一個客戶端連接到服務(wù)器后,服務(wù)器會自動在連接池中建立該客戶端的一個映像,所有的操作都交給這個映像去具體執(zhí)行,所以ClientSingle中一定要包含客戶端的一些基本的信息。比如客戶端的名稱、登陸時間等等。在該類中有兩個消息隊列sendQueue(發(fā)送隊列)和receiveQueue(接收隊列)緩存消息。 ClientSingle類是繼承自Thread的,它還是一個調(diào)用者。在初始化的時候啟動兩個子線程類SingleSender和SingleListener運(yùn)行。SingleSende
8、r負(fù)責(zé)監(jiān)聽指令發(fā)送隊列中有沒有指令,有則發(fā)送;SingleListener負(fù)責(zé)監(jiān)聽有沒有消息到達(dá),有則把這些消息加入到接收隊列中去,由ClientSingle處理。所以ClientSingle的主要任務(wù)就是對這兩個隊列的處理。這兩個隊列可以用Vector實現(xiàn),非常地簡單。 /-將消息加入發(fā)送隊列中- synchronized void send(Object o sendQueue.add(o; 為了穩(wěn)定控制子線程的運(yùn)行,并不鼓勵在run(方法的死循環(huán)標(biāo)志都用true,而是使用了一個布爾型的變量finish。外部可以通過把這個標(biāo)志置為假而停止線程的運(yùn)行。 發(fā)送子線程類啟動后執(zhí)行run(中的循環(huán)
9、(以finish為結(jié)束標(biāo)志),在該循環(huán)內(nèi)首先判斷ClientSingle中的發(fā)送隊列是否為空,為空時睡眠一定的時間再重新判斷,這也是一個while循環(huán)。不為空則開始處理隊列中的消息,把它取出后放入輸出流中發(fā)送。 public void run( while (!father.finish /循環(huán)監(jiān)聽 while(father.v.isEmpty( /當(dāng)發(fā)送隊列為空的時候線程睡眠500毫秒 tryThread.sleep(500; catch(InterruptedException eSystem.out.println(e; if (!father.v.isEmpty( /發(fā)送隊列不為空時
10、try Object a=father.v.firstElement(;/取出隊列中的第一個消息 father.v.removeElementAt(0;/從隊列中刪除 oos.writeObject(a;/發(fā)送該消息 oos.flush(; catch(IOException e displayMessage(" 傳輸失敗 !" father.finish=false; 接收子線程SingleListener類和發(fā)送子線程是類似的,它們的run(方法都差不多。不同的是接收子線程把收到的消息加入到ClientSingle的接收隊列中去,由它處理。 ClientSingle類的
11、run(方法就在循環(huán)地讀取接收隊列receiveQueue中的內(nèi)容,為空時等待;不為空時依次取出處理和轉(zhuǎn)發(fā)。處理消息的函數(shù)是processMsg(),它只是執(zhí)行消息類自己的process(方法罷了。在處理完后,會調(diào)用Server類的方法進(jìn)行各種類型的轉(zhuǎn)發(fā)。 分組轉(zhuǎn)發(fā)的實現(xiàn)類Group 為了實現(xiàn)對客戶端分組,我建立了Group類。在這個類中有一個列表存放已經(jīng)存在于連接池中的那些ClientSingle類的引址。只要遍歷整個列表就能訪問所有組中的成員。這個列表可以用Vector實現(xiàn),也可以用哈希表,我推薦后者,主要是為了能夠按名字存取。 組對象本身也是可以存在Server類的組列表中的。 分組功能
12、對多人的協(xié)同系統(tǒng)來說是非常重要的,特別是分組對某一個共享空間操作的時候。就以上面的協(xié)同繪圖系統(tǒng)為例,如果10個人里有三個人要另起爐灶,那么他們?nèi)齻€的畫板就不能讓其他人看到,這就必須有"組"個劃分。 主服務(wù)器類Server Server類是最核心的類,它在這個框架中起到調(diào)度全局的作用,上面介紹的那些類都由它來統(tǒng)一的構(gòu)造和調(diào)用。 Server類的域包括一個定長的數(shù)組存放ClientSingle實例,它就是連接池的實現(xiàn)。還要有一個哈希表存放Group實例。Server類的方法都是對這兩個類的操作。 建立ClientSingle數(shù)組的目的是保證服務(wù)器的穩(wěn)定性。其實,你也可以選擇不建
13、立它,只是動態(tài)地構(gòu)造對象,但是那樣不好管理連接的用戶,而且由于各種操作系統(tǒng)對進(jìn)程的處理不同,動態(tài)建立服務(wù)線程會很不穩(wěn)定。所以我先建立一個數(shù)組作為這些對象的容器,在開始時就估計好連接者的最大數(shù)量。Server類的addClient(函數(shù): void addClient(Socket socket int c=0; trywhile (schc!=null C+;/搜索數(shù)組中的空余空間 catch(ArrayIndexOutOfBoundsException e try socket.close(;/出現(xiàn)異常關(guān)閉槽連接 catch(IOException ee System.out.println("數(shù)組溢出" return; schc=new ClientSingle(c,socket,father,this;/在搜索到的位置建立ClientSingle對象 Server類中轉(zhuǎn)發(fā)的方法有:sendToAll()、sendToOne()、sendToGroup()等等。這些方法都是對線程池中的方法的操作,比較簡單,不外乎都是
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 【正版授權(quán)】 IEC 60364-4-44:2024 RLV EN Low-voltage electrical installations - Part 4-44: Protection for safety - Protection against voltage disturbances and electromagnetic disturbances
- 2025-2030年中國采鹽行業(yè)市場運(yùn)營狀況及發(fā)展趨勢分析報告
- 2025-2030年中國酒店用品行業(yè)運(yùn)行態(tài)勢及發(fā)展前景分析報告
- 2025-2030年中國過硫酸鹽行業(yè)運(yùn)行狀況及發(fā)展前景分析報告
- 2025-2030年中國輕質(zhì)碳酸鈣行業(yè)競爭態(tài)勢與營銷策略研究報告
- 2025-2030年中國車輛專用照明及電氣信號設(shè)備制造市場十三五規(guī)劃與發(fā)展策略分析報告
- 2025-2030年中國螺絲刀行業(yè)運(yùn)行狀況及前景趨勢分析報告
- 2025-2030年中國船舶租賃市場運(yùn)行現(xiàn)狀及發(fā)展趨勢預(yù)測報告
- 2025-2030年中國膨化食品市場運(yùn)營狀況與發(fā)展策略分析報告
- 2025-2030年中國紙漿產(chǎn)業(yè)運(yùn)行狀況與前景趨勢分析報告
- 醫(yī)院CT機(jī)房裝飾改造工程施工組織設(shè)計
- 基坑監(jiān)測總結(jié)報告
- 2024年華師大版九年級數(shù)學(xué)下冊全冊教案
- 合肥市廬陽區(qū)雙崗街道社區(qū)工作者招聘考試試題及答案2024
- JBT 106-2024 閥門的標(biāo)志和涂裝(正式版)
- 煤礦技術(shù)員必須會的知識
- (高清版)JTGT 3650-01-2022 公路橋梁施工監(jiān)控技術(shù)規(guī)程
- 2024年黑龍江建筑職業(yè)技術(shù)學(xué)院單招職業(yè)適應(yīng)性測試題庫全面
- 北京市2024小升初數(shù)學(xué)模擬試卷一
- 一年級口算題100以內(nèi)比大小
- 《提案與方案優(yōu)化設(shè)計》課件-第一部分 常見戶型問題解析及平面布局優(yōu)化
評論
0/150
提交評論