java專業(yè)課程設(shè)計(jì)方案報(bào)告java聊天室_第1頁
java專業(yè)課程設(shè)計(jì)方案報(bào)告java聊天室_第2頁
java專業(yè)課程設(shè)計(jì)方案報(bào)告java聊天室_第3頁
java專業(yè)課程設(shè)計(jì)方案報(bào)告java聊天室_第4頁
java專業(yè)課程設(shè)計(jì)方案報(bào)告java聊天室_第5頁
已閱讀5頁,還剩53頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

Java聊天室課程設(shè)計(jì)需求分析1.1開發(fā)背景在信息化社會(huì)今天,網(wǎng)絡(luò)飛速發(fā)展,大家對(duì)網(wǎng)絡(luò)依靠越來越多,越來越離不開網(wǎng)絡(luò),由此而產(chǎn)生聊天工具越來越多,類似MSN、QQ,網(wǎng)絡(luò)聊天時(shí)一類聊天系統(tǒng)發(fā)展日新月異,所以產(chǎn)生了制作一個(gè)類似QQ網(wǎng)絡(luò)聊天工具想法,且經(jīng)過制作該程序還能愈加好學(xué)習(xí)網(wǎng)絡(luò)軟件編程知識(shí)。網(wǎng)絡(luò)編程目標(biāo)就是指直接或間接地經(jīng)過網(wǎng)絡(luò)協(xié)議和其它計(jì)算機(jī)進(jìn)行通訊。網(wǎng)編程中有兩個(gè)關(guān)鍵問題,一個(gè)是怎樣正確定位網(wǎng)絡(luò)上一臺(tái)或多臺(tái)主機(jī),另一個(gè)就是找到主機(jī)后怎樣可靠高效進(jìn)行數(shù)據(jù)傳輸。在TCP/IP協(xié)議中IP層關(guān)鍵負(fù)責(zé)網(wǎng)絡(luò)主機(jī)定位,數(shù)據(jù)傳輸路由,由IP地址能夠唯一地確定Internet上一臺(tái)主機(jī)。而TCP層則提供面向應(yīng)用可靠或非可靠數(shù)據(jù)傳輸機(jī)制,這是網(wǎng)絡(luò)編程關(guān)鍵對(duì)象,通常不需要關(guān)心IP層是怎樣處理數(shù)據(jù)?,F(xiàn)在較為流行網(wǎng)絡(luò)編程模型是用戶機(jī)/服務(wù)器(C/S)結(jié)構(gòu)。即通信雙方一方作為服務(wù)器等候用戶提出請(qǐng)求并給予響應(yīng)。用戶則在需要服務(wù)時(shí)向服務(wù)器提出申請(qǐng)。服務(wù)器通常作為守護(hù)進(jìn)程一直運(yùn)行,監(jiān)聽網(wǎng)絡(luò)端口,一旦有用戶請(qǐng)求,就會(huì)開啟一個(gè)服務(wù)進(jìn)程來響應(yīng)該用戶,同時(shí)自己繼續(xù)監(jiān)聽服務(wù)端口,使以后用戶也得到響應(yīng)服務(wù)。1.2設(shè)計(jì)要求本課程設(shè)計(jì)目標(biāo)是利用套接字socket()設(shè)計(jì)一個(gè)聊天程序,該程序基于C/S模式,用戶機(jī)器向服務(wù)器發(fā)聊天請(qǐng)求,服務(wù)器應(yīng)答并能顯示用戶機(jī)發(fā)過來信息。1.3設(shè)計(jì)目標(biāo)經(jīng)過設(shè)計(jì)一個(gè)網(wǎng)絡(luò)聊天程序,對(duì)套接字、數(shù)據(jù)報(bào)通訊、URL、和URLConnectiom相關(guān)知識(shí)有具體了解和充足認(rèn)識(shí)。能將相關(guān)只是利用到相關(guān)實(shí)踐中去。1.4功效實(shí)現(xiàn)聊天室共分為用戶端和服務(wù)端兩部分,服務(wù)器程序關(guān)鍵負(fù)責(zé)偵聽用戶端發(fā)來消息,用戶端需要登錄到對(duì)應(yīng)服務(wù)器才能夠?qū)崿F(xiàn)正常聊天功效。服務(wù)器關(guān)鍵功效有在特定端口上進(jìn)行偵聽,等候用戶連接用戶能夠配置服務(wù)器真挺端口向已經(jīng)連接服務(wù)器用戶發(fā)送系統(tǒng)消息統(tǒng)計(jì)在線人數(shù)當(dāng)停止服務(wù)時(shí),斷開全部用戶連接用戶端關(guān)鍵功效連接到已經(jīng)開啟聊天服務(wù)服務(wù)端用戶能夠配置要連接服務(wù)器端ip地址和端口號(hào)用戶能夠配置連接后顯示用戶名當(dāng)服務(wù)器開啟時(shí)。用戶能夠隨時(shí)登陸和注銷用戶能夠向全部些人或一個(gè)人發(fā)送消息總體設(shè)計(jì)2.1設(shè)計(jì)思想套接字對(duì)象在網(wǎng)絡(luò)編程中飾演者關(guān)鍵角色,能夠用套接字技術(shù)編寫一個(gè)聊天室,服務(wù)器為每個(gè)用戶開啟一個(gè)線程。在該線程中經(jīng)過套接字和用戶交流信息,當(dāng)用戶向服務(wù)器發(fā)送一條聊天信息“大家好”時(shí),服務(wù)器要讓全部這些線程中輸入流寫入信息大家好,這么全部用戶套接字輸入流就全部讀取到了這一條信息。假如把信息“你好”發(fā)送給特定用戶,服務(wù)器就讓特定線程中輸出流寫入信息“你好”,那么只有特定用戶套機(jī)字輸入流能夠讀取到這條信息。在聊天室中需要對(duì)用戶上線下線狀態(tài)進(jìn)行修改,進(jìn)而統(tǒng)計(jì)在線人數(shù)、查找某用戶等。所以需要用到j(luò)ava鏈表來實(shí)現(xiàn)。因?yàn)镴ava語言不像c或c++一樣能夠利用線性表鏈?zhǔn)酱娣沤Y(jié)構(gòu),用節(jié)點(diǎn)和指針來表示,在Java中是沒有指針,不過能夠經(jīng)過使用對(duì)象引用來實(shí)現(xiàn)鏈表。鏈表結(jié)點(diǎn)個(gè)數(shù)稱為鏈表長度。所以在Java中能夠定義兩個(gè)類來實(shí)現(xiàn)鏈表操作,分別為節(jié)點(diǎn)類和鏈表類。在本設(shè)計(jì)中對(duì)用戶存放就是利用鏈表來實(shí)現(xiàn)。2.2基礎(chǔ)設(shè)計(jì)概念和處理步驟本系統(tǒng)運(yùn)行用JAVA開發(fā),采取C\S結(jié)構(gòu),系統(tǒng)分為客服端和服務(wù)端兩大模塊,使用Socket類建立套接字實(shí)現(xiàn)客服端和服務(wù)端得通訊。處理步驟用戶端用戶端服務(wù)端發(fā)送請(qǐng)求處理請(qǐng)求服務(wù)端用戶端一個(gè)ServerSocket對(duì)象和一個(gè)Socket對(duì)象一個(gè)Socketd對(duì)象ServerSocket(port)創(chuàng)建ServerSocket對(duì)象提供TCP連接服務(wù)ServerSocket(port)創(chuàng)建ServerSocket對(duì)象提供TCP連接服務(wù)Accept()在指定端口等候用戶端連接請(qǐng)求連接成功,取得一個(gè)已連接socket對(duì)象InputStream讀取Socket對(duì)象輸入流OutputStream寫入Socket對(duì)象輸出流InputStream讀取Socket對(duì)象輸入流OutputStream寫入Socket對(duì)象輸出流Socket(host,port)創(chuàng)建Socket對(duì)象,向指定主機(jī)端口發(fā)出連接請(qǐng)求Socket.close()關(guān)閉TCP連接ServerSocket.close()停止提供TCP連接服務(wù)Socket.close()關(guān)閉TCP連接建立Socket連接申請(qǐng)連接經(jīng)過流傳送數(shù)據(jù)TCPSocket通信步驟2.3總體結(jié)構(gòu)網(wǎng)絡(luò)聊天室網(wǎng)絡(luò)聊天室服務(wù)端客服端2.4功效分配用戶端向全部些人或一個(gè)人發(fā)送消息用戶端向全部些人或一個(gè)人發(fā)送消息用戶端連接服務(wù)端配置服務(wù)端登錄和注銷服務(wù)端服務(wù)端服務(wù)端等候用戶連接配置服務(wù)器偵聽端口向用戶發(fā)送系統(tǒng)消息統(tǒng)計(jì)在線人數(shù)、斷開連接等2.5接口設(shè)計(jì)2.5.1用戶接口提供一個(gè)用戶操作界面:包含用戶能夠再界面中登錄聊天室、輸入消息、瀏覽聊天內(nèi)容和聊天對(duì)象。同時(shí)提供一個(gè)服務(wù)器操作界面,經(jīng)過服務(wù)器操作界面能夠修改服務(wù)器配置,知道用戶目前狀態(tài),并能夠給用戶發(fā)送指定系統(tǒng)信息。2.5Socket(stringhont,intport);用戶端使用Socket類建立和服務(wù)器套接字連接。ServerSocket(intport);建立接收用戶套接字服務(wù)器套接字。2.6關(guān)鍵模塊2.6聊天室服務(wù)器端模塊關(guān)鍵有以下幾部分組成主框架類(ChatServer.java)該文件包含名為ChatServerpublic類,其關(guān)鍵功效是定義服務(wù)器界面,添加事件偵聽魚事件處理。ChatServer類調(diào)用ServerListen類來實(shí)現(xiàn)服務(wù)端用戶上線和下線偵聽,調(diào)用ServerReceive類來實(shí)現(xiàn)服務(wù)器端消息轉(zhuǎn)發(fā)。服務(wù)器用戶上線和下線偵聽類。該類對(duì)用戶上線和下線偵聽是經(jīng)過調(diào)用用戶鏈表類來實(shí)現(xiàn),當(dāng)用戶上線和下線情況發(fā)生改變時(shí),該類會(huì)對(duì)主類界面進(jìn)行對(duì)應(yīng)修改。服務(wù)器消息收發(fā)類該類分別定義了向某用戶及向全部些人發(fā)送消息方法,發(fā)送消息會(huì)顯示在主界面類界面上。4用戶修改配置類。該類繼承自JDialog。使用戶對(duì)服務(wù)器端口進(jìn)行修改配置類。5節(jié)點(diǎn)類定義了鏈表中用戶6鏈表類該類經(jīng)過結(jié)構(gòu)函數(shù)結(jié)構(gòu)用戶鏈表,定義了添加用戶、刪除用戶、返回用戶數(shù)、依據(jù)用戶名查找用戶和各依據(jù)索引查找用戶等方法。7服務(wù)器幫助類、2.6ActionListenerActionListenerChatServer-port:publicstaticin-serverSocket:ServerSocket-messageShow:JTextArea-userLinkList:UserLinkList-showStatus:JTextField+ChatServer():public+init():publicvoid+startService():publicvoid+stopService():publicvoid+sendStopToAll():publicvoid+sendMsgToAll(String):publicvoid+sendSystemMessage():publicvoidJFrameThreadServerListen-server:ServerSocket-userLinkList:UserLinkList -isStop:publicBoolean+ServerListen(ServerSocket,JComboBox,JTextArea,JTextField,UserLinkList)ServerReceive-textarea:JTextArea-userLinkList:UserLinkList -isStop:publicBoolean+ServerListen(ServerSocket,JComboBox,JTextArea,JTextField,UserLinkList)服務(wù)器端ChatServer類繼承自JFrame并實(shí)現(xiàn)對(duì)應(yīng)事件監(jiān)聽接口,所以它定義了服務(wù)器主框架,及各個(gè)按鈕事件監(jiān)聽。它分別調(diào)用ServerListen類來實(shí)現(xiàn)服務(wù)端用戶上線和下線偵聽,調(diào)用ServerReceive類來實(shí)現(xiàn)服務(wù)器端消息轉(zhuǎn)發(fā)。同時(shí)服務(wù)器能夠響應(yīng)多個(gè)用戶請(qǐng)求,當(dāng)一個(gè)用戶發(fā)送請(qǐng)求時(shí),服務(wù)器就為它增加一個(gè)線程,同時(shí)服務(wù)器利用UserLinkList類為用戶端設(shè)置一個(gè)請(qǐng)求隊(duì)列,假如服務(wù)器不能立即響應(yīng)用戶端請(qǐng)求,就要把這個(gè)請(qǐng)求放到請(qǐng)求隊(duì)列在中,,等服務(wù)器將目前請(qǐng)求處理完,會(huì)自動(dòng)到請(qǐng)求隊(duì)列中根據(jù)前后次序取出請(qǐng)求進(jìn)行處理。2.6用戶端關(guān)鍵有以下多個(gè)文件,功效以下:1用戶端主框架類該類關(guān)鍵定義用戶端界面,添加事件偵聽和事件處理。該類定義了和服務(wù)器實(shí)現(xiàn)連接和斷開連接方法。當(dāng)用戶登錄到指定服務(wù)器上時(shí),該類條用用戶端實(shí)現(xiàn)消息收發(fā)類實(shí)現(xiàn)消息收發(fā)。同時(shí)該類定義了向全部用戶發(fā)送消息方法。2用戶端消息收發(fā)類該類實(shí)現(xiàn)了服務(wù)器和用戶端消息收發(fā)3用戶修改配置類該類繼承自JDialog,是用戶對(duì)要連接服務(wù)器IP及偵聽端口進(jìn)行修改配置類。4幫助類用戶端用戶程序幫助類2.6ActionListenerChatClient-port:publicstaticin-serverSocket:ServerSocketActionListenerChatClient-port:publicstaticin-serverSocket:ServerSocket-messageShow:JTextArea-userLinkList:UserLinkList-showStatus:JTextField+ChatClient():public+init():publicvoid+Connect():publicvoid+DisConnect():publicvoid+SendMessage():publicvoidJFrameThreadClientReceiveClientReceive-socket:Socket-output:ObjectOutputStream-input:ObjectInputStream+ClientReceive(Socket,ObjectOutputStream,ObjectInJComboBox,JTextArea,JTextField) 用戶端ChatClient類繼承了JFrame并實(shí)現(xiàn)對(duì)應(yīng)事件監(jiān)聽接口。它實(shí)現(xiàn)了用戶端主界面及對(duì)應(yīng)按鈕事件偵聽。該類調(diào)用ClientReceive類實(shí)現(xiàn)消息收發(fā)。同時(shí)該類定義了向全部用戶發(fā)送消息方法。經(jīng)過對(duì)應(yīng)輸入輸出流和服務(wù)器進(jìn)行數(shù)據(jù)傳輸和交流。關(guān)鍵代碼實(shí)現(xiàn)3.1服務(wù)器關(guān)鍵代碼實(shí)現(xiàn)1、Chatserver類:包含名為ChatServerpublic類,其關(guān)鍵功效為定義服務(wù)器端界面,添加事件偵聽和事件處理。調(diào)用ServerListen類來實(shí)現(xiàn)服務(wù)端用戶上線和下線偵聽,調(diào)用ServerReceive類來實(shí)現(xiàn)服務(wù)器端消息收發(fā)。importjava.awt.*;importjava.awt.event.*;importjavax.swing.*;importjavax.swing.event.*;import.*;importjava.io.*;/**聊天服務(wù)端主框架類*/publicclassChatServerextendsJFrameimplementsActionListener{ publicstaticintport=8888;//服務(wù)端偵聽端口 ServerSocketserverSocket;//服務(wù)端Socket Imageicon;//程序圖標(biāo) JComboBoxcombobox;//選擇發(fā)送消息接收者 JTextAreamessageShow;//服務(wù)端信息顯示 JScrollPanemessageScrollPane;//信息顯示滾動(dòng)條 JTextFieldshowStatus;//顯示用戶連接狀態(tài) JLabelsendToLabel,messageLabel; JTextFieldsysMessage;//服務(wù)端消息發(fā)送 JButtonsysMessageButton;//服務(wù)端消息發(fā)送按鈕 UserLinkListuserLinkList;//用戶鏈表 //建立菜單欄 JMenuBarjMenuBar=newJMenuBar(); //建立菜單組 JMenuserviceMenu=newJMenu("服務(wù)(V)"); //建立菜單項(xiàng) JMenuItemportItem=newJMenuItem("端口設(shè)置(P)"); JMenuItemstartItem=newJMenuItem("開啟服務(wù)(S)"); JMenuItemstopItem=newJMenuItem("停止服務(wù)(T)"); JMenuItemexitItem=newJMenuItem("退出(X)"); JMenuhelpMenu=newJMenu("幫助(H)"); JMenuItemhelpItem=newJMenuItem("幫助(H)"); //建立工具欄 JToolBartoolBar=newJToolBar(); //建立工具欄中按鈕組件 JButtonportSet;//開啟服務(wù)端偵聽 JButtonstartServer;//開啟服務(wù)端偵聽 JButtonstopServer;//關(guān)閉服務(wù)端偵聽 JButtonexitButton;//退出按鈕 //框架大小 DimensionfaceSize=newDimension(400,600); ServerListenlistenThread; JPaneldownPanel; GridBagLayoutgirdBag; GridBagConstraintsgirdBagCon; /** *服務(wù)端結(jié)構(gòu)函數(shù) */ publicChatServer(){ init();//初始化程序 //添加框架關(guān)閉事件處理 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.pack(); //設(shè)置框架大小 this.setSize(faceSize); //設(shè)置運(yùn)行時(shí)窗口位置 DimensionscreenSize=Toolkit.getDefaultToolkit().getScreenSize(); this.setLocation((int)(screenSize.width-faceSize.getWidth())/2, (int)(screenSize.height-faceSize.getHeight())/2); this.setResizable(false); this.setTitle("聊天室服務(wù)端");//設(shè)置標(biāo)題 //程序圖標(biāo) icon=getImage("icon.gif"); this.setIconImage(icon);//設(shè)置程序圖標(biāo) show(); //為服務(wù)菜單欄設(shè)置熱鍵'V' serviceMenu.setMnemonic('V'); //為端口設(shè)置快捷鍵為ctrl+p portItem.setMnemonic('P'); portItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P,InputEvent.CTRL_MASK)); //為開啟服務(wù)快捷鍵為ctrl+s startItem.setMnemonic('S'); startItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,InputEvent.CTRL_MASK)); //為端口設(shè)置快捷鍵為ctrl+T stopItem.setMnemonic('T'); stopItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T,InputEvent.CTRL_MASK)); //為退出設(shè)置快捷鍵為ctrl+x exitItem.setMnemonic('X'); exitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,InputEvent.CTRL_MASK)); //為幫助菜單欄設(shè)置熱鍵'H' helpMenu.setMnemonic('H'); //為幫助設(shè)置快捷鍵為ctrl+p helpItem.setMnemonic('H'); helpItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_H,InputEvent.CTRL_MASK)); } /** *程序初始化函數(shù) */ publicvoidinit(){ ContainercontentPane=getContentPane(); contentPane.setLayout(newBorderLayout()); //添加菜單欄 serviceMenu.add(portItem); serviceMenu.add(startItem); serviceMenu.add(stopItem); serviceMenu.add(exitItem); jMenuBar.add(serviceMenu); helpMenu.add(helpItem); jMenuBar.add(helpMenu); setJMenuBar(jMenuBar); //初始化按鈕 portSet=newJButton("端口設(shè)置"); startServer=newJButton("開啟服務(wù)"); stopServer=newJButton("停止服務(wù)"); exitButton=newJButton("退出"); //將按鈕添加到工具欄 toolBar.add(portSet); toolBar.addSeparator();//添加分隔欄 toolBar.add(startServer); toolBar.add(stopServer); toolBar.addSeparator();//添加分隔欄 toolBar.add(exitButton); contentPane.add(toolBar,BorderLayout.NORTH); //初始時(shí),令停止服務(wù)按鈕不可用 stopServer.setEnabled(false); stopItem.setEnabled(false); //為菜單欄添加事件監(jiān)聽 portItem.addActionListener(this); startItem.addActionListener(this); stopItem.addActionListener(this); exitItem.addActionListener(this); helpItem.addActionListener(this); //添加按鈕事件偵聽 portSet.addActionListener(this); startServer.addActionListener(this); stopServer.addActionListener(this); exitButton.addActionListener(this); combobox=newJComboBox(); combobox.insertItemAt("全部些人",0); combobox.setSelectedIndex(0); messageShow=newJTextArea(); messageShow.setEditable(false); //添加滾動(dòng)條 messageScrollPane=newJScrollPane(messageShow, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); messageScrollPane.setPreferredSize(newDimension(400,400)); messageScrollPane.revalidate(); showStatus=newJTextField(35); showStatus.setEditable(false) sysMessage=newJTextField(24); sysMessage.setEnabled(false); sysMessageButton=newJButton(); sysMessageButton.setText("發(fā)送"); //添加系統(tǒng)消息事件偵聽 sysMessage.addActionListener(this); sysMessageButton.addActionListener(this); sendToLabel=newJLabel("發(fā)送至:"); messageLabel=newJLabel("發(fā)送消息:"); downPanel=newJPanel(); girdBag=newGridBagLayout(); downPanel.setLayout(girdBag); girdBagCon=newGridBagConstraints(); girdBagCon.gridx=0; girdBagCon.gridy=0; girdBagCon.gridwidth=3; girdBagCon.gridheight=2; girdBagCon.ipadx=5; girdBagCon.ipady=5; JLabelnone=newJLabel(""); girdBag.setConstraints(none,girdBagCon); downPanel.add(none); girdBagCon=newGridBagConstraints(); girdBagCon.gridx=0; girdBagCon.gridy=2; girdBagCon.insets=newInsets(1,0,0,0); girdBagCon.ipadx=5; girdBagCon.ipady=5; girdBag.setConstraints(sendToLabel,girdBagCon); downPanel.add(sendToLabel); girdBagCon=newGridBagConstraints(); girdBagCon.gridx=1; girdBagCon.gridy=2; girdBagCon.anchor=GridBagConstraints.LINE_START; girdBag.setConstraints(combobox,girdBagCon); downPanel.add(combobox); girdBagCon=newGridBagConstraints(); girdBagCon.gridx=0; girdBagCon.gridy=3; girdBag.setConstraints(messageLabel,girdBagCon); downPanel.add(messageLabel); girdBagCon=newGridBagConstraints(); girdBagCon.gridx=1; girdBagCon.gridy=3; girdBag.setConstraints(sysMessage,girdBagCon); downPanel.add(sysMessage); girdBagCon=newGridBagConstraints(); girdBagCon.gridx=2; girdBagCon.gridy=3; girdBag.setConstraints(sysMessageButton,girdBagCon); downPanel.add(sysMessageButton); girdBagCon=newGridBagConstraints(); girdBagCon.gridx=0; girdBagCon.gridy=4; girdBagCon.gridwidth=3; girdBag.setConstraints(showStatus,girdBagCon); downPanel.add(showStatus); contentPane.add(messageScrollPane,BorderLayout.CENTER); contentPane.add(downPanel,BorderLayout.SOUTH); //關(guān)閉程序時(shí)操作 this.addWindowListener( newWindowAdapter(){ publicvoidwindowClosing(WindowEvente){ stopService(); System.exit(0); }}}} /** *事件處理 */ publicvoidactionPerformed(ActionEvente){ Objectobj=e.getSource(); if(obj==startServer||obj==startItem){//開啟服務(wù)端 startService(); } elseif(obj==stopServer||obj==stopItem){//停止服務(wù)端 intj=JOptionPane.showConfirmDialog( this,"真停止服務(wù)嗎?","停止服務(wù)", JOptionPane.YES_OPTION,JOptionPane.QUESTION_MESSAGE); if(j==JOptionPane.YES_OPTION){ stopService(); } } elseif(obj==portSet||obj==portItem){//端口設(shè)置 //調(diào)出端口設(shè)置對(duì)話框 PortConfportConf=newPortConf(this); portConf.show(); } elseif(obj==exitButton||obj==exitItem){//退出程序 intj=JOptionPane.showConfirmDialog( this,"真要退出嗎?","退出", JOptionPane.YES_OPTION,JOptionPane.QUESTION_MESSAGE); if(j==JOptionPane.YES_OPTION){ stopService(); System.exit(0); } } elseif(obj==helpItem){//菜單欄中幫助 //調(diào)出幫助對(duì)話框 HelphelpDialog=newHelp(this); helpDialog.show(); } elseif(obj==sysMessage||obj==sysMessageButton){//發(fā)送系統(tǒng)消息 sendSystemMessage(); } } /** *開啟服務(wù)端 */ publicvoidstartService(){ try{ serverSocket=newServerSocket(port,10); messageShow.append("服務(wù)端已經(jīng)開啟,在"+port+"端口偵聽...\n"); startServer.setEnabled(false); startItem.setEnabled(false); portSet.setEnabled(false); portItem.setEnabled(false); stopServer.setEnabled(true); stopItem.setEnabled(true); sysMessage.setEnabled(true); } catch(Exceptione){ //System.out.println(e); } userLinkList=newUserLinkList(); listenThread=newServerListen(serverSocket,combobox, messageShow,showStatus,userLinkList); listenThread.start(); } /** *關(guān)閉服務(wù)端 */ publicvoidstopService(){ try{ //向全部些人發(fā)送服務(wù)器關(guān)閉消息 sendStopToAll(); listenThread.isStop=true; serverSocket.close(); intcount=userLinkList.getCount(); inti=0; while(i<count){ Nodenode=userLinkList.findUser(i); node.input.close(); node.output.close(); node.socket.close(); i++; } stopServer.setEnabled(false); stopItem.setEnabled(false); startServer.setEnabled(true); startItem.setEnabled(true); portSet.setEnabled(true); portItem.setEnabled(true); sysMessage.setEnabled(false); messageShow.append("服務(wù)端已經(jīng)關(guān)閉\n"); combobox.removeAllItems(); combobox.addItem("全部些人"); } catch(Exceptione){ //System.out.println(e); } } /** *向全部些人發(fā)送服務(wù)器關(guān)閉消息 */ publicvoidsendStopToAll(){ intcount=userLinkList.getCount(); inti=0; while(i<count){ Nodenode=userLinkList.findUser(i); if(node==null){ i++; continue; } try{ node.output.writeObject("服務(wù)關(guān)閉"); node.output.flush(); } catch(Exceptione){ //System.out.println("$$$"+e); } i++; } } /** *向全部些人發(fā)送消息 */ publicvoidsendMsgToAll(Stringmsg){ intcount=userLinkList.getCount();//用戶總數(shù) inti=0; while(i<count){ Nodenode=userLinkList.findUser(i); if(node==null){ i++; continue; } try{ node.output.writeObject("系統(tǒng)信息"); node.output.flush(); node.output.writeObject(msg); node.output.flush(); } catch(Exceptione){ //System.out.println("@@@"+e); } i++; } sysMessage.setText(""); } /** *向用戶端用戶發(fā)送消息 */ publicvoidsendSystemMessage(){ StringtoSomebody=combobox.getSelectedItem().toString(); Stringmessage=sysMessage.getText()+"\n"; messageShow.append(message); //向全部些人發(fā)送消息 if(toSomebody.equalsIgnoreCase("全部些人")){ sendMsgToAll(message); } else{ //向某個(gè)用戶發(fā)送消息 Nodenode=userLinkList.findUser(toSomebody); try{ node.output.writeObject("系統(tǒng)信息"); node.output.flush(); node.output.writeObject(message); node.output.flush(); } catch(Exceptione){ //System.out.println("!!!"+e); } sysMessage.setText("");//將發(fā)送消息欄消息清空 } /** *經(jīng)過給定文件名取得圖像 */ ImagegetImage(Stringfilename){ URLClassLoaderurlLoader=(URLClassLoader)this.getClass(). getClassLoader(); URLurl=null; Imageimage=null; url=urlLoader.findResource(filename); image=Toolkit.getDefaultToolkit().getImage(url); MediaTrackermediatracker=newMediaTracker(this); try{ mediatracker.addImage(image,0); mediatracker.waitForID(0); } catch(InterruptedException_ex){ image=null; } if(mediatracker.isErrorID(0)){ image=null; } returnimage; } publicstaticvoidmain(String[]args){ ChatServerapp=newChatServer(); }}(2)ServerListen.java:該類實(shí)現(xiàn)服務(wù)端用戶上線和下線偵聽。該類對(duì)用戶上線下線偵聽是經(jīng)過調(diào)用用戶鏈表類(UserLinkList)來實(shí)現(xiàn),當(dāng)用戶上線和下線情況發(fā)生改變時(shí),該類會(huì)對(duì)主類界面進(jìn)行對(duì)應(yīng)修改。importjava.awt.*;importjava.awt.event.*;importjavax.swing.*;importjavax.swing.event.*;importjava.io.*;import.*;/**服務(wù)端偵聽類*/publicclassServerListenextendsThread{ ServerSocketserver; JComboBoxcombobox; JTextAreatextarea; JTextFieldtextfield; UserLinkListuserLinkList;//用戶鏈表 Nodeclient; ServerReceiverecvThread; publicbooleanisStop; /* *聊天服務(wù)端用戶上線于下線偵聽類 */ publicServerListen(ServerSocketserver,JComboBoxcombobox, JTextAreatextarea,JTextFieldtextfield,UserLinkListuserLinkList){ this.server=server; bobox=combobox; this.textarea=textarea; this.textfield=textfield; this.userLinkList=userLinkList; isStop=false; } publicvoidrun(){ while(!isStop&&!server.isClosed()){ try{ client=newNode(); client.socket=server.accept(); client.output=newObjectOutputStream(client.socket.getOutputStream()); client.output.flush(); client.input=newObjectInputStream(client.socket.getInputStream()); client.username=(String)client.input.readObject(); //顯示提醒信息 combobox.addItem(client.username); userLinkList.addUser(client); textarea.append("用戶"+client.username+"上線"+"\n"); textfield.setText("在線用戶"+userLinkList.getCount()+"人\n"); recvThread=newServerReceive(textarea,textfield, combobox,client,userLinkList); recvThread.start(); } catch(Exceptione){ } } }}(3)ServerReceive.java:該類是實(shí)現(xiàn)服務(wù)器端消息收發(fā)類。該類分別定義了向某用戶及全部些人發(fā)送消息方法,發(fā)送消息會(huì)顯示在主界面類界面上。importjavax.swing.*;importjava.io.*;import.*;/**服務(wù)器收發(fā)消息類*/publicclassServerReceiveextendsThread{ JTextAreatextarea; JTextFieldtextfield; JComboBoxcombobox; Nodeclient; UserLinkListuserLinkList;//用戶鏈表 publicbooleanisStop; publicServerReceive(JTextAreatextarea,JTextFieldtextfield, JComboBoxcombobox,Nodeclient,UserLinkListuserLinkList){ this.textarea=textarea; this.textfield=textfield; this.client=client; this.userLinkList=userLinkList; bobox=combobox; isStop=false; } publicvoidrun(){ //向全部些人發(fā)送用戶列表 sendUserList(); while(!isStop&&!client.socket.isClosed()){ try{ Stringtype=(String)client.input.readObject(); if(type.equalsIgnoreCase("聊天信息")){ StringtoSomebody=(String)client.input.readObject(); Stringstatus=(String)client.input.readObject(); Stringaction=(String)client.input.readObject(); Stringmessage=(String)client.input.readObject(); Stringmsg=client.username +""+action +"對(duì)" +toSomebody +"說:" +message +"\n"; if(status.equalsIgnoreCase("悄悄話")){ msg="[悄悄話]"+msg; } textarea.append(msg); if(toSomebody.equalsIgnoreCase("全部些人")){ sendToAll(msg);//向全部些人發(fā)送消息 } else{ try{ client.output.writeObject("聊天信息"); client.output.flush(); client.output.writeObject(msg); client.output.flush(); } catch(Exceptione){ //System.out.println("###"+e); } Nodenode=userLinkList.findUser(toSomebody); if(node!=null){ node.output.writeObject("聊天信息"); node.output.flush(); node.output.writeObject(msg); node.output.flush(); } } } elseif(type.equalsIgnoreCase("用戶下線")){ Nodenode=userLinkList.findUser(client.username); userLinkList.delUser(node); Stringmsg="用戶"+client.username+"下線\n"; intcount=userLinkList.getCount(); combobox.removeAllItems(); combobox.addItem("全部些人"); inti=0; while(i<count){ node=userLinkList.findUser(i); if(node==null){ i++; continue; } combobox.addItem(node.username); i++; } combobox.setSelectedIndex(0); textarea.append(msg); textfield.setText("在線用戶"+userLinkList.getCount()+"人\n"); sendToAll(msg);//向全部些人發(fā)送消息 sendUserList();//重新發(fā)送用戶列表,刷新 break; } } catch(Exceptione){ //System.out.println(e); } } } /* *向全部些人發(fā)送消息 */ publicvoidsendToAll(Stringmsg){ intcount=userLinkList.getCount(); inti=0; while(i<count){ Nodenode=userLinkList.findUser(i); if(node==null){ i++; continue; } try{ node.output.writeObject("聊天信息"); node.output.flush(); node.output.writeObject(msg); node.output.flush(); } catch(Exceptione){ //System.out.println(e); } i++; } } /* *向全部些人發(fā)送用戶列表 */ publicvoidsendUserList(){ Stringuserlist=""; intcount=userLinkList.getCount(); inti=0; while(i<count){ Nodenode=userLinkList.findUser(i); if(node==null){ i++; continue; } userlist+=node.username; userlist+='\n'; i++; } i=0; while(i<count){ Nodenode=userLinkList.findUser(i); if(node==null){ i++; continue; } try{ node.output.writeObject("用戶列表"); node.output.flush(); node.output.writeObject(userlist); node.output.flush(); } catch(Exceptione){ //System.out.println(e); } i++; } }}(4)Node.java:用戶鏈表節(jié)點(diǎn)類,定義了鏈表中用戶。該類和前面所講鏈表節(jié)點(diǎn)Node類功效相當(dāng)。import.*;importjava.io.*;/***用戶鏈表結(jié)點(diǎn)類*/publicclassNode{ Stringusername=null; Socketsocket=null; ObjectOutputStreamoutput=null; ObjectInputStreaminput=null; Nodenext=null;}(6)UserLinkList.java:用戶鏈表節(jié)點(diǎn)具體實(shí)現(xiàn)類。該類經(jīng)過結(jié)構(gòu)函數(shù)結(jié)構(gòu)用戶鏈表,定義了添加用戶,刪除用戶、返回用戶數(shù)、依據(jù)用戶名查找用戶、依據(jù)索引查找用戶這5個(gè)方法。/***用戶鏈表*/publicclassUserLinkList{ Noderoot; Nodepointer; intcount; /** *結(jié)構(gòu)用戶鏈表 */ publicUserLinkList(){ root=newNode(); root.next=null; pointer=null; count=0; } /** *添加用戶 */ publicvoidaddUser(Noden){ pointer=root; while(pointer.next!=null){ pointer=pointer.next; } pointer.next=n; n.next=null; count++; } /** *刪除用戶 */ publicvoiddelUser(Noden){ pointer=root; while(pointer.next!=null){if(pointer.next==n){ pointer.next=n.next; count--; break; } pointer=pointer.next; } } /** *返回用戶數(shù) */ publicintgetCount(){ returncount; } /** *依據(jù)用戶名查找用戶 */ publicNodefindUser(Stringusername){ if(count==0)returnnull; pointer=root; while(pointer.next!=null){ pointer=pointer.next; if(pointer.username.equalsIgnoreCase(username)){ returnpointer; } } returnnull; } /** *依據(jù)索引查找用戶 */ publicNodefindUser(intindex){ if(count==0){ returnnull; } if(index<0){ returnnull; } pointer=root; inti=0; while(i<index+1){ if(pointer.next!=null){ pointer=pointer.next; } else{ returnnull; } i++; } returnpointer; }}3.2用戶端代碼實(shí)現(xiàn)(1)ChatClient.java:包含名為ChatClientpublic類,其關(guān)鍵功效為定義用戶端界面,添加事件偵聽和事件處理。該類定義了Connect()和DisConnect()方法實(shí)現(xiàn)和服務(wù)器連接和斷開連接。當(dāng)?shù)卿浀街付ǚ?wù)器時(shí),調(diào)用ClientReceive類實(shí)現(xiàn)消息收發(fā),同時(shí)該類還定義了SendMessage()方法來向其它用戶發(fā)送帶有表情消息或悄悄話。//packageClient;importjava.awt.*;importjava.awt.event.*;importjavax.swing.*;importjava.io.*;import.*;/**聊天用戶端主框架類*/publicclassChatClientextendsJFrameimplementsActionListener{ privatestaticfinallongserialVersionUID=1L; Stringip="";//連接到服務(wù)端ip地址 intport=8888;//連接到服務(wù)端端口號(hào) StringuserName="急忙過客";//用戶名 inttype=0;//0表示未連接,1表示已連接 JComboBoxcombobox;//選擇發(fā)送消息接收者 JTextAreamessageShow;//用戶端信息顯示 JScrollPanemessageScrollPane;//信息顯示滾動(dòng)條 JLabelexpress,sendToLabel,messageLabel; JTextFieldclientMessage;//用戶端消息發(fā)送 JCheckBoxcheckbox;//悄悄話 JComboBoxactionlist;//表情選擇 JButtonclientMessageButton;//發(fā)送消息 JTextFieldshowStatus;//顯示用戶連接狀態(tài) Socketsocket; ObjectOutputStreamoutput;//網(wǎng)絡(luò)套接字輸出流 ObjectInputStreaminput;//網(wǎng)絡(luò)套接字輸入流 ClientReceiverecvThread; //建立菜單欄 JMenuBarjMenuBar=newJMenuBar(); //建立菜單組 JMenuoperateMenu=newJMenu("操作(O)"); //建立菜單項(xiàng) JMenuItemloginItem=newJMenuItem("用戶登錄(I)",newImageIcon("face/98.gif")); JMenuItemlogoffItem=newJMenuItem("用戶注銷(L)",newImageIcon("face/icon.gif")); JMenuItemexitItem=newJMenuItem("退出(X)",newImageIcon("face/smile.gif")); JMenuconMenu=newJMenu("設(shè)置(C)"); JMenuItemuserItem=newJMenuItem("用戶設(shè)置(U)",newImageIcon("face/messenger_big.gif")); JMenuItemconnectItem=newJMenuItem("連接設(shè)置(C)",newImageIcon("face/Uabrand.gif")); JMenuhelpMenu=newJMenu("幫助(H)"); JMenuItemhelpItem=newJMenuItem("幫助(H)",newImageIcon("face/HelpCenter.gif")); //建立工具欄 JToolBartoolBar=newJToolBar(); //建立工具欄中按鈕組件 JButtonloginButton;//用戶登錄 JButtonlogoffButton;//用戶注銷 JButtonuserButton;//用戶信息設(shè)置 JButtonconnectButton;//連接設(shè)置 JButtonexitButton;//退出按鈕 //框架大小 DimensionfaceSize=newDimension(400,600); JPaneldownPanel; GridBagLayoutgirdBag; GridBagConstraintsgirdBagCon; publicChatClient(){ init();//初始化程序 //添加框架關(guān)閉事件處理 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.pack(); //設(shè)置框架大小 this.setSize(faceSize); this.setVisible(true); setIconImage(getToolkit().getImage("face/love.gif")); //設(shè)置運(yùn)行時(shí)窗口位置 DimensionscreenSize=Toolkit.getDefaultToolkit().getScreenSize(); this.setLocation((int)(screenSize.width-faceSize.getWidth())/2, (int)(screenSize.height-faceSize.getHeight())/2); this.setResizable(false); this.setTitle("聊天室用戶端");//設(shè)置標(biāo)題 //為操作菜單欄設(shè)置熱鍵'V' operateMenu.setMnemonic('O'); //為用戶登錄設(shè)置快捷鍵為ctrl+i loginItem.setMnemonic('I'); loginItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_I,InputEvent.CTRL_MASK)); //為用戶注銷快捷鍵為ctrl+l logoffItem.setMnemonic('L'); logoffItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L,InputEvent.CTRL_MASK)); //為退出快捷鍵為ctrl+x exitItem.setMnemonic('X'); exitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,InputEvent.CTRL_MASK)); //為設(shè)置菜單欄設(shè)置熱鍵'C' conMenu.setMnemonic('C'); //為用戶設(shè)置設(shè)置快捷鍵為ctrl+u userItem.setMnemonic('U'); userItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_U,InputEvent.CTRL_MASK)); //為連接設(shè)置設(shè)置快捷鍵為ctrl+c connectItem.setMnemonic('C'); connectItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,InputEvent.CTRL_MASK)); //為幫助菜單欄設(shè)置熱鍵'H' helpMenu.setMnemonic('H'); //為幫助設(shè)置快捷鍵為ctrl+p helpItem.setMnemonic('H'); helpItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_H,InputEvent.CTRL_MASK)); } /** *程序初始化函數(shù) */ publicvoidinit(){ ContainercontentPane=getContentPane(); contentPane.setLayout(newBorderLayout()); //添加菜單欄 operateMenu.add(loginItem); operateMenu.add(logoffItem); operateMenu.addSeparator(); operateMenu.add(exitItem); jMenuBar.add(operateMenu); conMenu.add(userItem); conMenu.addSeparator(); conMenu.add(connectItem); jMenuBar.add(conMenu); helpMenu.add(helpItem); jMenuBar.add(helpMenu); setJMenuBar(jMenuBar); //初始化按鈕 loginButton=newJButton("登錄"); logoffButton=newJButton("注銷"); userButton=newJButton("用戶設(shè)置"); connectButton=newJButton("連接設(shè)置"); exitButton=newJButton("退出"); //當(dāng)鼠標(biāo)放上顯示信息 loginButton.setToolTipText("連接到指定服務(wù)器"); logoffButton.setToolTipText("和服務(wù)器斷開連接"); userButton.setToolTipText("設(shè)置用戶信息"); connectButton.setToolTipText("設(shè)置所要連接到服務(wù)器信息"); //將按鈕添加到工具欄 toolBar.add(userButton); toolBar.add(connectButton); toolBar.addSeparator();//添加分隔欄 toolBar.add(loginButton); toolBar.add(logoffButton); toolBar.addSeparator();//添加分隔欄 toolBar.add(exitButton); contentPane.add(toolBar,BorderLayout.NORTH); checkbox=newJCheckBox("悄悄話"); checkbox.setSelected(false); actionlist=newJComboBox(); actionlist.addItem("微笑地"); actionlist.addItem("快樂地"); actionlist.addItem("輕輕地"); actionlist.addItem("生氣地"); actionlist.setSelectedIndex(0); //初始時(shí) loginButton.setEnabled(true); logoffButton.setEnabled(false); //為菜單欄添加事件監(jiān)聽 loginItem.addActionListener(this); logoffItem.addActionListener(this); exitItem.addActionListener(this); userItem.addActionListener(this); connectItem.addActionListener(this); helpItem.addActionListener(this); //添加按鈕事件偵聽 loginButton.addActionListener(this); logoffButton.addActionListener(this); userButton.addActionListener(this); connectButton.addActionListener(this); exitButton.addActionListener(this); combobox=newJComboBox(); c

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論