操作系統(tǒng)課程設(shè)計(jì)聊天室系統(tǒng)設(shè)計(jì)報(bào)告_第1頁
操作系統(tǒng)課程設(shè)計(jì)聊天室系統(tǒng)設(shè)計(jì)報(bào)告_第2頁
操作系統(tǒng)課程設(shè)計(jì)聊天室系統(tǒng)設(shè)計(jì)報(bào)告_第3頁
操作系統(tǒng)課程設(shè)計(jì)聊天室系統(tǒng)設(shè)計(jì)報(bào)告_第4頁
操作系統(tǒng)課程設(shè)計(jì)聊天室系統(tǒng)設(shè)計(jì)報(bào)告_第5頁
已閱讀5頁,還剩26頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、青島科技丸學(xué)操作系統(tǒng)課 程設(shè)計(jì)學(xué)生班級計(jì)算機(jī)132班學(xué)生學(xué)號1308010204學(xué)生姓名2016 年 5 月 180目錄設(shè)計(jì)題目:聊天室系統(tǒng)3一、設(shè)計(jì)目的及要求31.1設(shè)計(jì)目的31.2設(shè)計(jì)要求:3二、技術(shù)背景32.1網(wǎng)絡(luò)編程32.2網(wǎng)絡(luò)通信32.3 socket32.4 tcp 傳輸42.5 java的多線程機(jī)制4三、需求分析43.1客戶端43.1.1 登錄43.1.2多人聊天43.1.3單人聊天53.2服務(wù)器端5四、總體設(shè)計(jì)54.1設(shè)計(jì)思想流程圖54.2設(shè)計(jì)思想分析6五、詳細(xì)設(shè)計(jì)65客戶端設(shè)計(jì)75.1.1登錄界面75.1.2聊天室界面75.1.3單人聊天界面75.2服務(wù)器端設(shè)計(jì)8六、系統(tǒng)測試

2、86.1登錄測試86.1.1用戶名為英文字母86.1.2用戶名為中文96.1.3用戶名為標(biāo)點(diǎn)符號96.1.4多個(gè)用戶有重名106.1.5服務(wù)器地址不合法116.1.6端口號不合法126.1.7服務(wù)器未開啟126.2群發(fā)消息測試136.3私聊測試156.4用戶列表顯示測試16七、心得體會16八、參考資料16九、程序清單16設(shè)計(jì)題目:聊天室系統(tǒng)一、設(shè)計(jì)目的及要求1.1設(shè)計(jì)目的通過該聊天室系統(tǒng),掌握網(wǎng)絡(luò)編程的概念及基于網(wǎng)絡(luò)的c/s模式軟件系統(tǒng)開發(fā),掌握基于tcp 協(xié)議的socket編程,掌握java的多線程機(jī)制。1.2設(shè)計(jì)要求:實(shí)現(xiàn)多個(gè)用戶之間類似于qq的聊天程序,有聊天界面,多用戶之間既可以實(shí)現(xiàn)群

3、聊,也可以 單獨(dú)聊天。二、技術(shù)背景2.1網(wǎng)絡(luò)編程就是用來實(shí)現(xiàn)網(wǎng)絡(luò)互連的不同計(jì)算機(jī)上運(yùn)行的程序間可以進(jìn)行數(shù)據(jù)交換。2.2網(wǎng)絡(luò)通信(1) ip地址:網(wǎng)絡(luò)中設(shè)備的標(biāo)識,不易記憶,可用主機(jī)名要想讓網(wǎng)絡(luò)中的計(jì)算機(jī)能夠互相通信,必須為每臺計(jì)算機(jī)指定一個(gè)標(biāo)識號,通過這個(gè)標(biāo)識號來指定 要接受數(shù)據(jù)的計(jì)算機(jī)和識別發(fā)送的計(jì)算機(jī),在tcp/ip協(xié)議中,這個(gè)標(biāo)識號就是ip地址。(2) 端口號:用于標(biāo)識進(jìn)程的邏輯地址物理端口網(wǎng)卡口邏輯端口我們指的就是邏輯端口a:每個(gè)網(wǎng)絡(luò)程序都會至少有一個(gè)邏輯端口b:用于標(biāo)識進(jìn)程的邏輯地址,不同進(jìn)程的標(biāo)識c:有效端口: 065535,其中0-1024系統(tǒng)使用或保留端口。(3) 傳輸協(xié)議:通

4、信的規(guī)則,常見的有udp, tcpudp:將數(shù)據(jù)源和li的封裝成數(shù)據(jù)包中,不需要建立連接;每個(gè)數(shù)據(jù)報(bào)的大小在限制在64k;因無 連接,是不可靠協(xié)議;不需要建立連接,速度快。tcp:建立連接,形成傳輸數(shù)據(jù)的通道;在連接屮進(jìn)行大數(shù)據(jù)量傳輸;通過三次握手完成連接,是 可靠協(xié)議;必須建立連接,效率會稍低。2.3 socket(1) socket套接字網(wǎng)絡(luò)上具有唯一標(biāo)識的ip地址和端口號組合在一起才能構(gòu)成唯一能識別的標(biāo)識符套接字。(2) socket原理機(jī)制a:通信的兩端都有socketcb:網(wǎng)絡(luò)通信其實(shí)就是socket間的通信。c:數(shù)據(jù)在兩個(gè)socket間通過io傳輸。2.4 tcp傳輸(1) 客戶端

5、思路a建立客戶端的socket服務(wù),并明確要連接的服務(wù)器。b如果連接建立成功,就表明,已經(jīng)建立了數(shù)據(jù)傳輸?shù)耐ǖ?就可以在該通道通過10進(jìn)行數(shù)據(jù)的讀取和 寫入該通道稱為socket流,socket流中既有讀取流,也有寫入流.c通過socket對象的方法,可以獲取這兩個(gè)流d通過流的對象可以對數(shù)據(jù)進(jìn)行傳輸e如果傳輸數(shù)據(jù)完畢,關(guān)閉資源(2) 服務(wù)器端思路a建立服務(wù)器端的socket服務(wù),需要一個(gè)端口b服務(wù)端沒有直接流的操作,而是通過accept方法獲取客戶端對象,在通過獲取到的客戶端對象的流 和客戶端進(jìn)行通信c通過客戶端的獲取流對象的方法,讀取數(shù)據(jù)或者寫入數(shù)據(jù)d如果服務(wù)完成,需要關(guān)閉客戶端,然后關(guān)閉服

6、務(wù)器,但是,一般會關(guān)閉客戶端,不會關(guān)閉服務(wù)器,因?yàn)榉?務(wù)端是一直提供服務(wù)的2.5 java的多線程機(jī)制進(jìn)程:每個(gè)進(jìn)程都有獨(dú)立的代碼和數(shù)據(jù)空i'可(進(jìn)程上下文),進(jìn)程i'可的切換會有較大的開銷,一個(gè)進(jìn) 程包含ln個(gè)線程。線程:同一類線程共亨代碼和數(shù)據(jù)空間,每個(gè)線程有獨(dú)立的運(yùn)行棧和程序計(jì)數(shù)器(pc),線程切換開 銷小。多進(jìn)程是指操作系統(tǒng)能同時(shí)運(yùn)行多個(gè)任務(wù)(程序),多線程是指在同一程序中有多個(gè)順序流在執(zhí) 行。在j“va中,每次程序運(yùn)行至少啟動(dòng)2個(gè)線程。一個(gè)是main線程,一個(gè)是垃圾收集線程。因?yàn)槊?當(dāng)使用java命令執(zhí)行一個(gè)類的時(shí)候,實(shí)際上都會啟動(dòng)一個(gè)jvm,啟動(dòng)jvm實(shí)際上就是在操

7、作系統(tǒng) 中啟動(dòng)了一個(gè)進(jìn)程。在java中所有的線程都是同時(shí)啟動(dòng)的,至于什么時(shí)候,哪個(gè)先執(zhí)行,完全看誰 先得到cpu的資源。三、需求分析實(shí)現(xiàn)聊天的功能,采用java socket編程,服務(wù)器與客戶端采用了 tcp/ip連接方式,在設(shè)計(jì)聊 天方案時(shí),可將所有信息發(fā)往服務(wù)器端,再由服務(wù)器進(jìn)行處理,服務(wù)器端是所有信息的中心。3.1客戶端3.1.1登錄用戶需要填寫用戶名、服務(wù)器地址、端口號才可以進(jìn)入聊天室與在線用戶聊天,此外,服務(wù)器 地址默認(rèn)是木機(jī)地址,端口號默認(rèn)是5000o用戶名可以中文,英文字母或標(biāo)點(diǎn)符號,服務(wù)器地址必 須是符合點(diǎn)分十進(jìn)制的合法地址,端口號可以修改,但服務(wù)器端程序內(nèi)默認(rèn)端口號也必須修改

8、。該 聊天室不需要注冊,直接登錄即可聊天,退出后,系統(tǒng)不保留用戶任何信息。若新登錄用戶與在線用戶的用戶名重名,則系統(tǒng)會自動(dòng)修改用戶名。格式為:用戶名客戶 端線程id”。3.1.2多人聊天每個(gè)在線用戶都可以發(fā)送聊天信息,服務(wù)器端會一直監(jiān)聽,并把每一個(gè)在線用戶發(fā)送的聊天信 息轉(zhuǎn)發(fā)到每一個(gè)客戶端。聊天室的聊天信息格式為:用八名 時(shí)間(yyyy-mm-dd hh:mm:ss)聊天信息3.1.3單人聊天用戶可以選擇某一個(gè)在線用戶實(shí)現(xiàn)單人聊天,該聊天信息不會在聊天室顯示,只有單聊的兩個(gè) 人能夠看到。單人聊天的聊天信息格式為:用戶名 時(shí)間(yyyymmdd聊天信息3.2服務(wù)器端服務(wù)器端主要處理客戶端的請求,

9、包括用戶的登錄,發(fā)送多人聊天信息,退出聊天室,單人聊 天請求,發(fā)送單人聊天信息,并且隨時(shí)更新在線用戶列表。四、總體設(shè)計(jì)4.1設(shè)計(jì)思想流程圖4.2設(shè)計(jì)思想分析首先啟動(dòng)服務(wù)器,它會建立一個(gè)專門用于接收客戶端連接請求的“傾聽socket”,然后等待客戶 的連接請求。當(dāng)用戶登錄輸入信息后,與服務(wù)器建立socket連接,服務(wù)器端的“傾聽socket"收到 連接請求后,會接受連接請求,并生成一個(gè)服務(wù)器端socket,專門負(fù)責(zé)與此客戶端socket的通信。 一旦連接請求成功,客戶端將信息及請求通過本方socket的輸出流發(fā)送給服務(wù)器端相應(yīng)的socket, 服務(wù)端則通過服務(wù)器端socket的輸入流接

10、受客戶端傳輸過來的信息及請求,分析是何請求,然后根 據(jù)請求類型,進(jìn)行相應(yīng)的處理(如登錄、私聊等)。服務(wù)器端也可以根據(jù)需要,通過socket的輸出流 發(fā)送信息和請求給客戶端??蛻舳撕头?wù)器端都可以通過關(guān)閉本方的socket而結(jié)束一次通信過程。對于客戶端的各種請求,實(shí)際上都是通過在客戶端發(fā)往服務(wù)器的各種字符流區(qū)分的,具體的方 法就是在消息的內(nèi)部添加特殊字符串,從而實(shí)現(xiàn)服務(wù)器對消息請求的識別。比如對于登陸信息,消 息中添加的內(nèi)容就是“l(fā)ogin”,而對于私聊中的消息,消息中添加的內(nèi)容就是“single”,其他的 同理都添加了相應(yīng)內(nèi)容。當(dāng)然,對于客八端來說,這些都是透明的,用戶的操作并沒有受到任何影

11、響。在服務(wù)器端,消息被檢測分析后,變回根據(jù)具體的目的進(jìn)行處理,比如是私聊消息,服務(wù)器便 會根據(jù)其內(nèi)部添加的信息,向目標(biāo)端轉(zhuǎn)發(fā)該條消息,當(dāng)目標(biāo)端接收到連接請求后,會主動(dòng)建立一個(gè) 私聊窗口,從而實(shí)現(xiàn)私聊。服務(wù)器端需要能同時(shí)接受多個(gè)用戶的請求,為了實(shí)現(xiàn)這一點(diǎn),一般使用多線程機(jī)制來處理,對 每一個(gè)客戶端連接通信,服務(wù)器端都有一個(gè)線程專門負(fù)責(zé)處理。對于客戶端的各種請求,內(nèi)部添加的信息分別如下: clientthread客戶端線程啟動(dòng)messages.add(clientthread.getid() + "clientthread");客戶端線程id login登錄客戶端usernam

12、e+ "login m+getthreadid()+" login" 用戶名+客戶端線程id userlist用戶列表serverthread.users.get(new integer(threadld) + "userlist"+threadid + "userlisi” 用戶名+客戶端線程id chat群聊username + "chat" + getthreadid() + "chat"+ mess + "chat" 用戶名+客戶端線程id+聊天信息 serverex

13、it服務(wù)器退出 serverthread.niessages+"serverexit" single 單聊die nt.user name + nsingle" + client.getthreadid() + "singlem +(in t)clie nt.clie ntu serid.get(index) + "single" + mess + hsingle"用戶名+客戶端線程id+客戶端線程id+聊天信息 exit退出群聊username + "exit" + getthreadid() + &q

14、uot;exit" 用戶名+客戶端線程id五、詳細(xì)設(shè)計(jì)5.1客戶端設(shè)計(jì)5.1.1登錄界面5.1.2聊天室界面5.1.3單人聊天界i». -jb v.fang5.2服務(wù)器端設(shè)計(jì)六、系統(tǒng)測試6.1登錄測試6.1.1用戶名為英文字母r聊天室wang聊天消息在線用戶清除聊天信息退出聊天室發(fā)送6.1.2用戶名為中文6.1.3用戶名為標(biāo)點(diǎn)符號6.1.4多個(gè)用戶有重名6.1.5服務(wù)器地址不合法g販天室人616端口號不合法6.1.7服務(wù)器未開啟6.2群發(fā)消息測試b駆天室zhang呂業(yè)mm11 11聊天消息在線用戶zhang 2016-05-1511:30:41wanghellowang20

15、16-05-1511:31:00你好退出聊天室清除聊天信息發(fā)送單人聊天6.3®z h m n g do6.4用戶列表顯示測試無論已經(jīng)登錄用戶的退出,還是新用戶成功登錄,用戶列表顯示部分都能正確顯示。七、心得體會這段時(shí)間通過不斷的修改,我終于把聊天室系統(tǒng)完成了,雖然它只有簡單的聊天功能,但通過 它,我不但鞏固了以前學(xué)的知識,而且學(xué)到了許多在課堂屮學(xué)不到的知識。通過這次課程設(shè)計(jì),我 更堅(jiān)定了理論與實(shí)際相結(jié)合是十分重要的想法,即使一個(gè)人讀了再多的技術(shù)圖書,但沒有相關(guān)的實(shí) 踐經(jīng)驗(yàn),那么他也不會真正地掌握一門技術(shù)。只有把理論知識與實(shí)踐相結(jié)合,才會深入的了解并提 高自己的獨(dú)立思考能力。通過這次的

16、課程設(shè)計(jì),我將自己所學(xué)的java語言得到了實(shí)際的應(yīng)用,在完成的過程中也遇到了 許多困難,但通過不斷地查閱資料,最終還是解決了,在這個(gè)過程屮,我學(xué)會了獨(dú)立思考,同時(shí)也 讓我明白完成一件事情要不斷開闊視野,拓展知識面,解放自己的思維。總之,在完成課程設(shè)計(jì)的 過程中,我學(xué)會了如何克服開發(fā)中遇到的技術(shù)困難,學(xué)會了獨(dú)立面對并解決問題。八、參考資料葉核亞java程序設(shè)計(jì)實(shí)用教程(第2版)電子工業(yè)出版社朱福喜,路遲java語言與面向?qū)ο蟪绦蛟O(shè)計(jì)武漢大學(xué)出版社沈文炎java高級編程機(jī)械工業(yè)出版社九、程序清單(1) client.javapublic class client extends threadpub

17、lic socket c_socket;套接字private client_chatframe c_chatframe;/聊天室聊天界面private client_enterframe c_enterframe;/客戶端登錄界面private client_singleframe c_singleframe;/單人聊天界面 public datalnputstream dis = null;/io 輸入 public dataoutputstream dos = null;/io 輸出 private boolean flag_exit = false;/客戶端未啟動(dòng)標(biāo)記 private i

18、nt thread id;/聊天室客戶端線程標(biāo)記public map<string, client_singleframe> c_singleframes;/單人聊天,用戶名為鍵,單聊客戶端為 值public list<string> usemame_online;/在線用 戶public list<integer> clientuserid;/用戶 idpublic string username = nidi;/用戶名public string chat_re;/ii!l道內(nèi)相關(guān)信息/getter, setter 方法public client_chat

19、frame getc_chatframe() return c_chatframe;public client_singleframe getc_singlframe() return c_singleframe;public void setc_singlframe(client_singleframe c_singlframe) this.c_singleframe = c_singlframe;public void setc_chatframe(client_chatframe c_chatframe) this.c chatframe = c chatframe;public cli

20、ent_enterframe getc_enterframe() return c_enterframe;public void setc_enterframe(client_enterframe c_enterframe) this.c_enterframe = c_enterframe;public int getthreadid() return threadid;public void setthreadid(int threadid) this<threadid = threadid;客戶端構(gòu)造函數(shù)public client()c_singleframes = new hash

21、map<string, client_singleframe>();username_online = new arraylist<string>();clientuserid = new arraylist<integer>();/signlechatuse = new arraylist<string>();/main方法,設(shè)置進(jìn)入時(shí)登錄界面public static void main(string args) client client = new client();client_enterframe c_enterframe = new

22、 client_enterframe(client); client.setc_enterframe(c_enterframe);c_enterframe.setvisible(true);登錄客戶端public string login(string username, string hostlp, string hostport) this.username = username;/用戶 名string login_mess = null;/錯(cuò)誤信息或 truetry c_socket = new socket(hostlp, integer.parselnt(hostport); cat

23、ch (numberformatexception e) login_mess ="連接的服務(wù)器端口號port為整數(shù),取值范i韋i為:1024<poil<65535”; return login_mess;)catch (unknownhostexception e) login_mess = ”主機(jī)地址錯(cuò)誤”; return login_mess; catch (ioexception e) login.mess = “連接服務(wù)器失敗,請稍后再試”; return login_mess;return htruem;創(chuàng)建一個(gè)客戶端聊天界面,啟動(dòng)一個(gè)線程public voi

24、d showchatframe(string username) getdatainit();c_chatframe = new client_chatframe(this,username);c_chatframe.setvisible(true);flag_exit = true;/客戶端已啟動(dòng)this.start();/jn 動(dòng)線程初始化,建立連接通道private void getdatainit() try dis = new datalnputstream(c_socket.getinputstream();dos = new dataoutputstream(c_socket.g

25、etoutputstream(); catch (ioexception e) e.printstacktrace();該類聲明為thread的子類,重寫thread類的run方法public void run() while(flag_exit)/ 客戶端已啟動(dòng)try /readutfo:讀入一個(gè)已使用utf-8修改版格式編碼的字符串。 chat_re = dis.readutf(); catch (ioexception e) flag_exit = false;if(!chat_re.contains(nserverexitm)chat_re = null;if(chat_re !=nu

26、ll)if(chat_re.contains(,clientthreadm)int local = chat_re.indexof(hclientthreadh); setthreadid(integer.parseint(chat_re.substring(o, local);/啟動(dòng)客戶端線程,設(shè) 置 threadiddos.writeutf(username + nl oginn + getthreadid() + mloginn); catch (ioexception e) e.printstacktrace();elseif(chat_re.contains(,userlistn)

27、c_chatframe.setdisusers(chat_re);else if(chat_re.contains(n chath) c_chatframe.setdismess(chat_re);else if(chat_re.contains(userverexitn) c_chatframe.closeclient();else if(chat_re.contains(nsingleh) c_chatframe.setsingleframe(chat_re);發(fā)送聊天信息public void transmess(string mess) dos.writeutf(username +

28、nchath + getthreadid() + ”cha+ mess + ,rchatu); catch (ioexception e) e.printstacktrace();聊天室屮退出聊天public void exitchat() try dos.writeutf(username + nexith + getthreadid() + "exit"); flag_exit = false;system.exit(o); catch (ioexception e) e.printstacktrace();登錄z前退出public void exitlogin() s

29、ystem.exit(o);服務(wù)器關(guān)閉,退出聊天室客戶端,在client_chatframe屮調(diào)用public void exitclient() flag_exit = false;system.exit(o);(2) wincenter.javapublic class wincenter public static void center(window win)toolkit tkit = toolkit.getdefaulttoolkit();/使用系統(tǒng)工具包dimension ssize = tkit.getscreensize();/屏幕尺寸dimension wsize = wi

30、n.getsize();/窗體尺寸 if(wsize.height > ssize.height)!wsize.height = ssize.height;if(wsize.width > ssize.width)wsize.width = ssize.width;win.setlocation(ssize.width - wsize.width)/ 2, (ssize.height - wsize.height)/ 2);/窗體居屏幕中 央(3) server.javapublic class server private serverframe serverframe;priv

31、ate serverthread serverthread;public serverframe getserverframe() return serverframe;public void setserverframe(serverframe serverframe) this.serverframe = serverframe;public server()啟動(dòng)服務(wù)器線程public void startserver() try!serverthread = new serverthread(serverframe);catch(exception e)system.exit(o);se

32、rverthread.setflag_exit(true); serverthread. start();停止服務(wù)器線程public void stopserver()synchronized (serverthread.messages) /同步代碼塊:synchronized:當(dāng)它用來修飾一個(gè)力法或 者一個(gè)代碼塊的時(shí)候,能夠保證在同一時(shí)刻最多只有一個(gè)線程執(zhí)行該段代碼。string str = "serverexil; serverthread.messages.add(str);serverthread.serverframe.setdismess(nexitm);/j 青除聊天

33、信息serverthread.serverframe.setdisusers(mexitu);/ 清除在線用戶 serverthread .stopserver();停止服務(wù)器線程/main方法public static void main(string args) server server = new server。;serverframe serverframe = new serverframe(server);serve 匚 selserverframe(serverfmme);serverframe.setvisible(true);停止服務(wù)器線程并退出public void cl

34、ose() if(serverthread != null)if(serverthread.isali ve() serverthread.stopserver();system.exit(o);(4) serverthread.javapublic class serverthread extends thread /vector類可以實(shí)現(xiàn)可增長的對象數(shù)組。與數(shù)組一樣,它包含可以使用整數(shù)索引進(jìn)行訪問的組件。 但是,vector的大小可以根據(jù)需要增大或縮小,以適應(yīng)創(chuàng)建vector后進(jìn)行添加或移除項(xiàng)的操 作。public serversocket serversocket;/服務(wù)器套接字publ

35、ic vector<string> messages;/messages.add(clientthread.getid() + "clien(thread")public vector<clientthread> clients;/客戶端線程public map<integer, string> users;/客戶端線程 id 和用戶姓名public broadcast broadcast;public int port = 5000;public boolean login = true;public serverframe serve

36、rframe;private boolean flag_exit = false;/服務(wù)器未啟動(dòng)public serverthread(serverframe serverframe) this.serverframe = serverframe;messages = new vector<string>();clients = new vector<clientthread>();users = new hashmap<integer, string>();try serversocket = new serversocket(port); catch (

37、ioexception e) this.serverframe.setstartandstop un able();system.exit(o);broadcast = new broadcast(this);broadcast.setflag_exit(true);broadcast.start();/ 啟動(dòng)廣播線程overridepublic void run() socket socket;while(flag_exit)try if(serversocketisclosed()flag_exit = false;elsetrysocket = serversocket.accept()

38、;/接收客戶端請求,無請求則阻塞 catch(socketexception e)socket = null;flag_exit = false;貞socket != null)clientthread clientthread = new clientthread(socket, this); clientthread.setflag_exit(true);clientthread.start();/ 啟動(dòng)客戶端線程/* synchronized:當(dāng)它用來修飾一個(gè)方法或者一,個(gè)代碼塊的吋候,能 夠保證在同一時(shí)刻最多只有一個(gè)線程執(zhí)行該段代碼。*同步代碼塊 線程同步(目的是為了保護(hù)多個(gè)線程訪問一

39、個(gè)資源 時(shí)對資源的破壞)*/synchronized (clients) /客戶端線程 clients.addeleme nt(clientthiead);synchronized (messages) users.put(int) clientthread.getld(), "login"); messages.add(clientthread.getid() + "clientthread"); catch (ioexception e) e.pri ntstacktrace();停止服務(wù)器public void stopserver() try i

40、f(this.isalive()serversocket.close(); setflag_exit(false); catch (throwable e) 設(shè)置服務(wù)器啟動(dòng)標(biāo)志public void setflag_exit(boolean b) flag_exit = b;(5) clientthread.javapublic class clientthread extends thread public socket clientsocket;/客戶端套接字public serverthread serverthread;public datalnputstream dis;public

41、 dataoutputstream dos;/public string client_userid;private boolean flag_exit = false;/客戶端線程啟動(dòng)標(biāo)記 public clientthread(socket socket, serverthread serverthread) clientsocket = socket;this.serverthread = serverthread;try dis = new datalnputstream(clientsocket.getinputstream(); dos = new dataoutputstream

42、(clientsocket.getoutputstream(); catch (ioexception e) e.printstacktrace();overridepublic void run() while(flag_exit)try 從通道讀出信息string message = dis.readutf();if(message.contains(nloginm)/ 有新登錄用戶string userinfo = message.split(hloginu);int userid = integer.parselnt(userlnfol 1 );serverthread.users.r

43、emove(userld); if(serverthread.users.containsvalue(userinfofo) 新登錄的與原來的有重名 for(int i = 0; i < serverthread.clients.size(); i+)int id = (int)senerthread-clients.get(i).getid(); if(serverthread.users.get(id).equals(userinfoo)/ 用戶名相同 serverthread.users.remove(id);serverthread.users.put(id, userlnfof

44、o + id);/額外添加標(biāo)記(線程id),更新新登錄的用戶break;serverthread.users.piit(intege匚parselnl(userlnfo 1 ), userlnfofo + n_n + userlnfol);/更新原來用戶)elseserverthread.users.piit(userid, userlnfoloj);更新服務(wù)器端用戶列表message = null;stringbuffer sb = new stringbuffer();synchronized (serverthread.clien/同步代碼塊:客戶線程for(int i = 0; i &

45、lt; serverthread.clients.size(); i+)int threadid = (int) serverthread.clients.elementat(i).getid();/客戶線 程idsb.append(string)serverthread.users.get(new integer(threadld) + nuserlistm);/ 用戶姓名 + “useiiist”sb.append(threadid + "userlist");/ 用戶姓名 + “uschist” + 客戶端 線程 id+ “userlist”string userna

46、mes = new string(sb); serverthread.serverframe.setdisusers(usernaines);/ 更新用戶列表 message = usernames;elseif(message.contains("exit")/ 有退出,更新用戶列表string userinfo = message.split(nexitu);int userid = intege匚parselnt(userlnfo 1);serverthread.users.remove(userid);/客戶端退出,清除用戶 idmessage = null;str

47、ingbuffer sb = new stringbuffer();synchronized (serverthread.clients) for(int i = 0; i < serverthread.clients.size(); i+)int threadid = (int) serverthread.clients.elementat(i).getid(); if(userid = threadid) /移除退出客戶端線程 serverthread.clients.removeelementat(i);else/保留未退出客戶端信息 sb.append(string)server

48、thread.users.get(newinteger( threadid) + huserlisth);sb.append(threadid + muserlistn);string usernames = new string(sb);if(usernames.equals(,tn) serverthread.serverframe.setdisusers(muserlisth);else( serverthread.serverframe.setdisusers(usernames);message = usernames;else群聊展示聊天信息if(message.contains(

49、hchatn)string chat = message>split(mchath);stringbuffer sb = new stringbuffer();simpiedateformat form = new simpledateformat(uyyyy-mm-ddstring date = form.format(new date(); sb.append(chato + '*" + date + "n");sb.append(chat2 + ”chat");string str = new string(sb);message =

50、 str; serverthread.serverframe.setdismess(message);)elseif(message.contains(msinglem)synchronized (serverthread.messages) if(message != null)serverthread.messages.addelement(message); if(message.contains(mexit,r) this.clientsocket.close(); flag_exit = false; catch (ioexception e) 關(guān)閉客戶端線程public void

51、closeclienthread(clientthread clientthread) if(clientthread.clientsocket != null)clientthread.clientsocket.close(); catch (ioexception e) sy stem. out. println( "server's clientsocket is null");try setflag_ex it(fal se);)catch (throwable e) e.pri n tstackt race();public void setflag_exit(boolean b) flag_exit = b;(6) broadcast.

溫馨提示

  • 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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論