付費(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é)生姓名王永遠(yuǎn)2016年 5月18日目錄設(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 Socket 32.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.1 客戶端設(shè)計(jì)75.1.1 登錄界面75.1.2 聊天室界面75.1.3 單
2、人聊天界面75.2 服務(wù)器端設(shè)計(jì)8六、系統(tǒng)測試 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編程,掌握J(rèn)ava的多線程機(jī)制。1.2
3、設(shè)計(jì)要求:實(shí)現(xiàn)多個(gè)用戶之間類似于 QQ的聊天程序,有聊天界面,多用戶之間既可以實(shí)現(xiàn)群聊,也可以單獨(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ī)和識另IJ發(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)
4、識C:有效端口: 065535,其中01024系統(tǒng)使用或保留端口。(3)傳輸協(xié)議:通信的規(guī)則,常見的有UDP, TCPUDP :將數(shù)據(jù)源和目的封裝成數(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:通信的兩端都有 Socket。B:網(wǎng)絡(luò)通信其實(shí)就是 Soc
5、ket間的通信。C:數(shù)據(jù)在兩個(gè)Socket間通過IO傳輸。2.4 TCP傳輸(1)客戶端思路A建立客戶端的Socket服務(wù),并明確要連接的服務(wù)器。B如果連接建立成功,就表明,已經(jīng)建立了數(shù)據(jù)傳輸?shù)耐ǖ?就可以在該通道通過IO進(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通過
6、客戶端的獲取流對象的方法,讀取數(shù)據(jù)或者寫入數(shù)據(jù)D如果服務(wù)完成,需要關(guān)閉客戶端,然后關(guān)閉服務(wù)器,但是,一般會關(guān)閉客戶端,不會關(guān)閉服務(wù)器,因?yàn)榉?務(wù)端是一直提供服務(wù)的2.5 Java的多線程機(jī)制進(jìn)程:每個(gè)進(jìn)程都有獨(dú)立的代碼和數(shù)據(jù)空間(進(jìn)程上下文),進(jìn)程間的切換會有較大的開銷,一個(gè)進(jìn)程包含1-n個(gè)線程。線程:同一類線程共享代碼和數(shù)據(jù)空間,每個(gè)線程有獨(dú)立的運(yùn)行棧和程序計(jì)數(shù)器(PC),線程切換開銷小。多進(jìn)程是指操作系統(tǒng)能同時(shí)運(yùn)行多個(gè)任務(wù)(程序),多線程是指在同一程序中有多個(gè)順序流在執(zhí)行。在java中,每次程序運(yùn)行至少啟動2個(gè)線程。一個(gè)是 main線程,一個(gè)是垃圾收集線程。因?yàn)槊慨?dāng)使用java命令執(zhí)行一個(gè)
7、類的時(shí)候,實(shí)際上都會啟動一個(gè)JVM ,啟動JVM實(shí)際上就是在操作系統(tǒng)中啟動了一個(gè)進(jìn)程。在 java中所有的線程都是同時(shí)啟動的,至于什么時(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)是5000。用戶名可以中文,英文字母或標(biāo)點(diǎn)符號,服務(wù)器地址必須是符合點(diǎn)分十進(jìn)制的合法
8、地址,端口號可以修改,但服務(wù)器端程序內(nèi)默認(rèn)端口號也必須修改。該 聊天室不需要注冊,直接登錄即可聊天,退出后,系統(tǒng)不保留用戶任何信息。若新登錄用戶與在線用戶的用戶名重名,則系統(tǒ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í)間(yyy
9、y-MM-dd HH:mm )聊天信息3.2 服務(wù)器端服務(wù)器端主要處理客戶端的請求,包括用戶的登錄,發(fā)送多人聊天信息,退出聊天室,單人聊 天請求,發(fā)送單人聊天信息,并且隨時(shí)更新在線用戶列表。四、總體設(shè)計(jì)4.1 設(shè)計(jì)思想流程圖4.2 設(shè)計(jì)思想分析首先啟動服務(wù)器,它會建立一個(gè)專門用于接收客戶端連接請求的“傾聽Socket”,然后等待客戶的連接請求。當(dāng)用戶登錄輸入信息后,與服務(wù)器建立Socket連接,服務(wù)器端的“傾聽Socket”收到連接請求后,會接受連接請求,并生成一個(gè)服務(wù)器端socket,專門負(fù)責(zé)與此客戶端socket的通信。一旦連接請求成功,客戶端將信息及請求通過本方socket的輸出流發(fā)送給
10、服務(wù)器端相應(yīng)的socket,服務(wù)端則通過服務(wù)器端Socket的輸入流接受客戶端傳輸過來的信息及請求,分析是何請求,然后根據(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)容就是“ login”,而對于私聊中的消息,消息中添加的內(nèi)容就是“ single”淇他的 同理都添加了相應(yīng)內(nèi)
11、容。當(dāng)然,對于客戶端來說,這些都是透明的,用戶的操作并沒有受到任何影 響。在服務(wù)器端,消息被檢測分析后,變回根據(jù)具體的目的進(jìn)行處理,比如是私聊消息,服務(wù)器便 會根據(jù)其內(nèi)部添加的信息,向目標(biāo)端轉(zhuǎn)發(fā)該條消息,當(dāng)目標(biāo)端接收到連接請求后,會主動建立一個(gè) 私聊窗口,從而實(shí)現(xiàn)私聊。服務(wù)器端需要能同時(shí)接受多個(gè)用戶的請求,為了實(shí)現(xiàn)這一點(diǎn),一般使用多線程機(jī)制來處理,對 每一個(gè)客戶端連接通信,服務(wù)器端都有一個(gè)線程專門負(fù)責(zé)處理。對于客戶端的各種請求,內(nèi)部添加的信息分別如下:clientThread客戶端線程啟動messages.add(clientThread.getId() + ”clientThread&quo
12、t;); 客戶端線程IDlogin登錄客戶端username+"login"+getThreadID()+”login" 用戶名+客戶端線程IDuserlist用戶列表serverThread.users.get(new Integer(threadlD) + ”userlist"+threadID + ”userlist" 用戶名+客戶端線程IDchat群聊username + "chat" + getThreadID() + ”chat"+ mess + "chat" 用戶名+客戶端線程ID
13、+聊天信息serverexit服務(wù)器退出serverThread.messages+"serverexit"single 單聊client.username + "single" + client.getThreadID() + ”single" +(int)client.clientuserid.get(index) + ”single" + mess + "single"用戶名+客戶端線程ID+客戶端線程ID+聊天信息exit退出群聊username + "exit" + getThread
14、ID() + "exit" 用戶名+客戶端線程ID五、詳細(xì)設(shè)計(jì)5.1 客戶端設(shè)計(jì)5.1.1 登錄界面5.1.2聊天室界面5.1.3單人聊天界面5.2服務(wù)器端設(shè)計(jì)六、系統(tǒng)測試6.1 登錄測試6.1.1 用戶名為英文字母6.1.2用戶名為中文6.1.3用戶名為標(biāo)點(diǎn)符號6.1.4多個(gè)用戶有重名6.1.5服務(wù)器地址不合法6.1.6端口號不合法6.2群發(fā)消息測試發(fā)送消息(1) 私聊測試聊天消息zhang 2015-05-15 11;34我是工hangwarg 2015*05-15 11:34在是*獨(dú)£R zhang 聊天消息 zhang 2015-05-15 11:34 和
15、是工hang vang 2016C5-15 11;34 我是wan g發(fā)送消息(2) 用戶列表顯7K測試無論已經(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ú)立思考能力。通過這次的課程設(shè)計(jì),我將自己所學(xué)的Jav
16、a語言得到了實(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è)出版社九、程序清單(3) Client.javapublic class Client extends Threadpublic Socket c_
17、socket ;/ 套接字private Client_chatFrame c_chatFrame;/ 聊天室聊天界面private Client_enterFrame c_enterFrame;/ 客戶端登錄界面private Client_singleFrame c_singleFrame;/ 單人聊天界面public DataInputStream dis = null;/IO 輸入public DataOutputStream dos = null;/IO 輸出private boolean flag_exit = false;/ 客戶端未啟動標(biāo)t己private int thread
18、ID;/聊天室客戶端線程標(biāo)記public Map<String, Client_singleFrame> c_singleFrames;/ 單人聊天,用戶名為鍵,單聊客戶端為 值public List<String> username_online;/ 在線用戶public List<Integer> clientuserid;/ 用戶 IDpublic String username = null;/ 用戶名public String chat_re;/ 通道內(nèi)相關(guān)信息/getter, setter 方法public Client_chatFrame ge
19、tC_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 Client_ente
20、rFrame 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 HashMap<Stri
21、ng, 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 Client_en
22、terFrame(client);client.setC_enterFrame(c_enterFrame);c_enterFrame.setVisible(true);登錄客戶端public String login(String username, String hostIp, String hostPort) this.username = username;用戶名String login_mess = null;/ 錯(cuò)誤信息或 true try c_socket = new Socket(hostIp, Integer.parseInt(hostPort); catch (NumberF
23、ormatException e) login_mess ="連接的服務(wù)器端口號port為整數(shù),取值范圍為:1024<port<65535”;return login_mess; catch (UnknownHostException e) login_mess ="主機(jī)地址錯(cuò)誤" return login_mess; catch (lOException e) login_mess ="連接服務(wù)器失敗,請稍后再試"return login_mess; return "true"創(chuàng)建一個(gè)客戶端聊天界面,啟動一個(gè)線
24、程public void showChatFrame(String username) getDataInit();c_chatFrame = new Client_chatFrame(this,username);c_chatFrame.setVisible(true);flag_exit = true;/客戶端已啟動 this.start();/ 啟動線程初始化,建立連接通道private void getDataInit() try dis = new DataInputStream(c_socket.getInputStream();dos = new DataOutputStream
25、(c_socket.getOutputStream(); catch (IOException e) e.printStackTrace();/該類聲明為 Thread的子類,重寫 Thread類的run方法 public void run() while(flag_exit)客戶端已啟動 try /readUTF():讀入一個(gè)已使用UTF-8修改版格式編碼的字符串。chat_re = dis.readUTF(); catch (IOException e) flag_exit = false;if(!chat_re.contains("serverexit") chat_
26、re = null; if(chat_re != null) if(chat_re.contains("clientThread")int local = chat_re.indexOf("clientThread");setThreadID(Integer.parseInt(chat_re.substring(0, local);/ 啟動客戶端線程,設(shè) 置 ThreadIDtry dos.writeUTF(username + "login" + getThreadID() + "login"); catch (
27、lOException e) e.printStackTrace();elseif(chat_re.contains("userlist")c_chatFrame.setDisUsers(chat_re);elseif(chat_re.contains("chat")c_chatFrame.setDisMess(chat_re);elseif(chat_re.contains("serverexit")c_chatFrame.closeClient();elseif(chat_re.contains("single"
28、;) c_chatFrame.setSingleFrame(chat_re);發(fā)送聊天信息public void transMess(String mess) try dos.writeUTF(username + "chat" + getThreadID() + ”chat"+ mess + "chat"); catch (IOException e) e.printStackTrace();聊天室中退出聊天public void exitChat() try dos.writeUTF(username + "exit"
29、+ getThreadID() + "exit");flag_exit = false;System.exit(0); catch (IOException e) e.printStackTrace();登錄之前退出public void exitLogin() System.exit(0);服務(wù)器關(guān)閉,退出聊天室客戶端,在 Client_chatFrame中調(diào)用public void exitClient() flag_exit = false;System.exit(O); (4) WinCenter.javapublic class WinCenter public
30、static void center(Window win)Toolkit tkit = Toolkit.getDefaultToolkit();使用系統(tǒng)工具包Dimension sSize = tkit.getScreenSize();/ 屏幕尺寸Dimension wSize = win.getSize();/ 窗體尺寸if(wSize.height > sSize.height)wSize.height = sSize.height;if(wSize.width > sSize.width)wSize.width = sSize.width;win.setLocation(s
31、Size.width - wSize.width)/ 2, (sSize.height - wSize.height)/ 2);/窗體居屏幕中央(5) Server.javapublic class Server private ServerFrame serverFrame;private ServerThread serverThread;public ServerFrame getServerFrame() return serverFrame; public void setServerFrame(ServerFrame serverFrame) this.serverFrame =
32、serverFrame; public Server()啟動服務(wù)器線程public void startServer() tryserverThread = new ServerThread(serverFrame);catch(Exception e)System.exit(O);serverThread.setFlag_exit(true);serverThread.start();/停止服務(wù)器線程public void stopServer()synchronized (serverThread.messages) 同步代碼塊: synchronized:當(dāng)它用來修飾一個(gè)方法或 者一個(gè)代
33、碼塊的時(shí)候,能夠保證在同一時(shí)刻最多只有一個(gè)線程執(zhí)行該段代碼。String str = "serverexit"serverThread.messages.add(str);serverThread.serverFrame.setDisMess("exit"); 清除聊天信息 serverThread.serverFrame.setDisUsers("exit"); 清除在線用戶 serverThread.stopServer();/ 停止服務(wù)器線程 /main方法public static void main(String口 args
34、) Server server = new Server。;ServerFrame serverFrame = new ServerFrame(server);server.setServerFrame(serverFrame);serverFrame.setVisible(true);/停止服務(wù)器線程并退出public void close() if(serverThread != null)if(serverThread.isAlive() serverThread.stopServer(); System.exit(0);(6) ServerThread.javapublic class
35、 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ù)器套接字public Vector<String> messages;/messages.add(clientThread.getId() + "clientThread")public Vector<ClientThread> cli
36、ents;/ 客戶端線程public Map<Integer, String> users;/ 客戶端線程 ID 和用戶姓名public BroadCast broadcast;public int Port = 5000;public boolean login = true;public ServerFrame serverFrame;private boolean flag_exit = false;/ 服務(wù)器未啟動public ServerThread(ServerFrame serverFrame)this.serverFrame = serverFrame;messag
37、es = new Vector<String>();clients = new Vector<ClientThread>();users = new HashMap<Integer, String>();try serverSocket = new ServerSocket(Port); catch (IOException e) this.serverFrame.setStartAndStopUnable();System.exit(0);broadcast = new BroadCast(this);broadcast.setFlag_exit(true
38、);broadcast.start();/啟動廣播線程Overridepublic void run() Socket socket;while(flag_exit)try if(serverSocket.isClosed() flag_exit = false;elsetrysocket = serverSocket.accept();接收客戶端請求,無請求則阻塞 catch(SocketException e)socket = null;flag_exit = false;if(socket != null)ClientThread clientThread = new ClientThr
39、ead(socket, this);clientThread.setFlag_exit(true);clientThread.start(); 啟動客戶端線程/* synchronized:當(dāng)它用來修飾一個(gè)方法或者一個(gè)代碼塊的時(shí)候,能夠保證在同一時(shí)刻最多只有一個(gè)線程執(zhí)行該段代碼。*同步代碼塊 線程同步(目的是為了保護(hù)多個(gè)線程訪問一個(gè)資源 時(shí)對資源的破壞)*/synchronized (clients) / 客戶端線程clients.addElement(clientThread);synchronized (messages) users.put(int) clientThread.getId
40、(), "login");messages.add(clientThread.getId() + "clientThread"); catch (lOException e) e.printStackTrace();/停止服務(wù)器public void stopServer() try if(this.isAlive()serverSocket.close();setFlag_exit(false); catch (Throwable e) 設(shè)置服務(wù)器啟動標(biāo)志public void setFlag_exit(boolean b) flag_exit = b
41、;(7) ClientThread.javapublic class ClientThread extends Thread public Socket clientSocket;/ 客戶端套接字public ServerThread serverThread;public DataInputStream dis;public DataOutputStream dos;/public String client_userID;private boolean flag_exit = false;/ 客戶端線程啟動標(biāo)t己public ClientThread(Socket socket, Serv
42、erThread serverThread) clientSocket = socket;this.serverThread = serverThread;try dis = new DataInputStream(clientSocket.getInputStream();dos = new DataOutputStream(clientSocket.getOutputStream(); catch (IOException e) e.printStackTrace();Overridepublic void run() while(flag_exit)try 從通道讀出信息String M
43、essage = dis.readUTF();if(Message.contains("login") 有新登錄用戶String 口 userinfo = Message.split("login");int userID = Integer.parseInt(userInfo1);serverThread.users.remove(useriD);if(serverThread.users.containsValue(userInfo0) 新登錄的與原來的有重名for(int i = 0; i < serverThread.clients.siz
44、e(); i+)int id = (int)serverThread.clients.get(i).getId();if(serverThread.users.get(id).equals(userInfo0) 用戶名相同serverThread.users.remove(id);serverThread.users.put(id, userinfo0 + "_" + id);/ 額外添加標(biāo)記(線程ID),更新新登錄的用戶break;serverThread.users.put(Integer.parseInt(userInfo1), userinfo0 + "_
45、" + userInfo1);/更新原來用戶elseserverThread.users.put(userID, userinfo。); 更新服務(wù)器端用戶列表 Message = null;StringBuffer sb = new StringBuffer();synchronized (serverThread.clients) 同步代碼塊:客戶線程for(int i = 0; i < serverThread.clients.size(); i+)int threadID = (int) serverThread.clients.elementAt(i).getId();
46、 客戶線 程IDsb.append(String)serverThread.users.get(new Integer(threadID) + "userlist"); 用戶姓名 + “userlist”sb.append(threadID + "userlist"); 用戶姓名 + “userlist” + 客戶端 線程 ID+ “userlist”String userNames = new String(sb);serverThread.serverFrame.setDisUsers(userNames);更新用戶歹U 表 Message = us
47、erNames;elseif(Message.contains("exit") 有退出,更新用戶列表String userInfo = Message.split("exit");int userID = Integer.parseInt(userInfo1);serverThread.users.remove(userID);客戶端退出,清除用戶 ID Message = null;StringBuffer sb = new StringBuffer();synchronized (serverThread.clients) for(int i = 0
48、; i < serverThread.clients.size(); i+)int threadID = (int) serverThread.clients.elementAt(i).getId();if(userID = threadID)/移除退出客戶端線程 serverThread.clients.removeElementAt(i);i-;else保留未退出客戶端信息sb.append(String)serverThread.users.get(new Integer(threadID) + "userlist");sb.append(threadID +
49、"userlist");String userNames = new String(sb);if(userNames.equals("")serverThread.serverFrame.setDisUsers("userlist");elseserverThread.serverFrame.setDisUsers(userNames);Message = userNames;else群聊展示聊天信息if(Message.contains("chat")String口 chat = Message.split(&q
50、uot;chat");StringBuffer sb = new StringBuffer();SimpleDateFormat form = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String date = form.format(new Date();sb.append(chat0 + "" + date + "n");sb.append(chat2 + "chat");String str = new String(sb);Message = str
51、;serverThread.serverFrame.setDisMess(Message);elseif(Message.contains("single")synchronized (serverThread.messages) if(Message != null)serverThread.messages.addElement(Message);if(Message.contains("exit") this.clientSocket.close(); flag_exit = false; catch (lOException e) 關(guān)閉客戶端線程
52、public void closeClienthread(ClientThread clientThread) if(clientThread.clientSocket != null)try clientThread.clientSocket.close(); catch (IOException e) System.out.println("server's clientSocket is null");try setFlag_exit(false); catch (Throwable e) e.printStackTrace();public void setFlag_exit(boolean b) flag_exit = b;(8) BroadCast.javapublic class BroadCast extends Th
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年生態(tài)濕地公園建設(shè)可行性分析:技術(shù)創(chuàng)新與生態(tài)濕地修復(fù)
- 農(nóng)業(yè)病蟲害防控智能化趨勢:2025年監(jiān)測預(yù)警系統(tǒng)可行性報(bào)告
- 2026年生物科技行業(yè)創(chuàng)新報(bào)告及基因編輯技術(shù)臨床應(yīng)用
- 2025年跨境電商獨(dú)立站品牌忠誠度培養(yǎng)報(bào)告
- 2025年新能源汽車五年市場報(bào)告
- 生態(tài)養(yǎng)殖循環(huán)產(chǎn)業(yè)鏈建設(shè)項(xiàng)目2025年技術(shù)創(chuàng)新與農(nóng)業(yè)產(chǎn)業(yè)鏈優(yōu)化可行性研究
- 冷鏈物流配送路徑優(yōu)化系統(tǒng)開發(fā)可行性研究報(bào)告-2025年行業(yè)挑戰(zhàn)與對策
- 介休教師面試題目及答案
- 前列腺相關(guān)問題解答與護(hù)理
- 2026年生物傳感器技術(shù)報(bào)告
- ISO28000:2022供應(yīng)鏈安全管理體系
- 幼兒園防欺凌治理委員會
- 臨床科室基本醫(yī)療保險(xiǎn)服務(wù)質(zhì)量考核評分標(biāo)準(zhǔn)
- 臺州風(fēng)土人情(共15張PPT)
- CodeSoft 6.0 詳細(xì)使用手冊
- 招投標(biāo)與采購管理-課件
- 教學(xué)查房-子宮內(nèi)膜息肉
- 漢服文化介紹(精選)課件
- 婦產(chǎn)科學(xué)(第9版)第三章 女性生殖系統(tǒng)生理
- GB/T 17626.4-1998電磁兼容試驗(yàn)和測量技術(shù)電快速瞬變脈沖群抗擾度試驗(yàn)
- 深圳大學(xué)圖書城管理中心大樓項(xiàng)目標(biāo)底及投標(biāo)報(bào)價(jià)測算分析報(bào)告4200字
評論
0/150
提交評論