版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p><b> 課程設(shè)計(jì)報(bào)告</b></p><p> ( 2014-- 2015年度第二學(xué)期)</p><p> 科目面向?qū)ο笳n程設(shè)計(jì)</p><p><b> 目 錄</b></p><p> 1 概 述..............................
2、..............3</p><p> 1.1課程設(shè)計(jì)目的....................................3</p><p> 1.2預(yù)備知識(shí)........................................3</p><p> 1.3課程設(shè)計(jì)內(nèi)容和要求..............................
3、3</p><p> 2 需求分析...........................................4</p><p> 2.1 系統(tǒng)目標(biāo).......................................4</p><p> 2.2 主體功能.......................................4<
4、/p><p> 2.3 開(kāi)發(fā)環(huán)境.......................................4</p><p> 2.4 概念設(shè)計(jì).......................................4</p><p> 3 系統(tǒng)總體設(shè)計(jì).......................................5</p>
5、<p> 3.1 系統(tǒng)的功能模塊劃分.............................5</p><p> 3.2 系統(tǒng)流程圖.....................................6</p><p> 4系統(tǒng)詳細(xì)設(shè)計(jì).......................................7</p><p> 4.
6、1 代碼實(shí)現(xiàn)情況...................................7</p><p> 4.1.1 server 包 chessServer類...................7</p><p> 4..1.2 client包 chessClient類..................7</p><p> 4.1.3 chessfac
7、e 包 chatPad類....................8</p><p> 4.1.4 chessface 包 chessPad類...................8</p><p> 4.1.5 chessface包c(diǎn)hessthread類.................8</p><p> 4.1.6 chessface 包 control
8、pad類.................8</p><p> 4.1.7 chessface 包 inputpad類...................8</p><p> 4.1.8 chessface 包userPad 類....................9</p><p> 4.1測(cè)試分析............................
9、............9</p><p> 4.2.1程序運(yùn)行情況................................9</p><p> 4.2.2程序運(yùn)行異常處理...........................12</p><p> 5 小結(jié)...............................................1
10、2</p><p> 參考文獻(xiàn).............................................13</p><p><b> 附 源代碼</b></p><p><b> 1、概述</b></p><p><b> 1.1課程設(shè)計(jì)目的</b>&
11、lt;/p><p> 《JAVA程序設(shè)計(jì)》是計(jì)算機(jī)相關(guān)專業(yè)的必修專業(yè)基礎(chǔ)課程,其實(shí)踐性、應(yīng)用性很強(qiáng)。實(shí)踐教學(xué)環(huán)節(jié)是必不可少的一個(gè)重要環(huán)節(jié)。本課程的程序設(shè)計(jì)專題實(shí)際是計(jì)算機(jī)相關(guān)專業(yè)學(xué)生學(xué)習(xí)完《JAVA程序設(shè)計(jì)》課程后,進(jìn)行的一次全面的綜合訓(xùn)練,JAVA程序設(shè)計(jì)的設(shè)計(jì)目的是加深對(duì)理論教學(xué)內(nèi)容的理解和掌握,使學(xué)生較系統(tǒng)地掌握程序設(shè)計(jì)及其在網(wǎng)絡(luò)開(kāi)發(fā)中的廣泛應(yīng)用,基本方法及技巧,為學(xué)生綜合運(yùn)用所學(xué)知識(shí),利用軟件工程為基礎(chǔ)進(jìn)行
12、軟件開(kāi)發(fā)、并在實(shí)踐應(yīng)用方面打下一定基礎(chǔ)。</p><p><b> 1.2預(yù)備知識(shí)</b></p><p> 熟悉JAVA語(yǔ)言及ECLIPSE開(kāi)發(fā)工具。</p><p> 1.3課程設(shè)計(jì)內(nèi)容和要求</p><p> 按課程設(shè)計(jì)指導(dǎo)書(shū)提供的課題,要求學(xué)生在自行完成各個(gè)操作環(huán)節(jié),并能實(shí)現(xiàn)且達(dá)到舉一反三的目的,完成一個(gè)
13、項(xiàng)目解決一類問(wèn)題。要求學(xué)生能夠全面、深入理解和熟練掌握所學(xué)內(nèi)容,并能夠用其分析、設(shè)計(jì)和解答類似問(wèn)題;對(duì)此能夠較好地理解和掌握,能夠進(jìn)行簡(jiǎn)單分析和判斷;能編寫(xiě)出具有良好風(fēng)格的程序;掌握J(rèn)AVA程序設(shè)計(jì)的基本技能和面向?qū)ο蟮母拍詈头椒?;了解多線程、安全和網(wǎng)絡(luò)等編程技術(shù)。同時(shí)培養(yǎng)學(xué)生進(jìn)行分析問(wèn)題、解決問(wèn)題的能力;培養(yǎng)學(xué)生進(jìn)行設(shè)計(jì)分析、設(shè)計(jì)方法、設(shè)計(jì)操作與測(cè)試、設(shè)計(jì)過(guò)程的觀察、理解和歸納能力的提高。</p><p>
14、五子棋是起源于中國(guó)古代的傳統(tǒng)黑白棋種之一。五子棋不僅能增強(qiáng)思維能力,提高智力,而且富含哲理,有助于修身養(yǎng)性。 經(jīng)過(guò)一個(gè)學(xué)期的學(xué)習(xí),使我對(duì)Java有了一定的了解。但要深入理解Java語(yǔ)言,單靠上課是不夠的。必須通過(guò)課程設(shè)計(jì),設(shè)計(jì)一個(gè)比較大的程序,才能更深一步地理解Java語(yǔ)言。在這次課程中,我選擇了網(wǎng)絡(luò)五子棋作為課題。編寫(xiě)網(wǎng)絡(luò)五子棋游戲要利用到Socket網(wǎng)絡(luò)編程技術(shù)和多線程。通過(guò)這次課程設(shè)計(jì),熟悉Java的GUI圖形界面設(shè)計(jì),網(wǎng)絡(luò)So
15、cket 編程和多線程編程。</p><p><b> 2 需求分析</b></p><p><b> 2.1 系統(tǒng)目標(biāo)</b></p><p> 本系統(tǒng)主要是完成五子棋游戲的基本操作,在玩游戲的過(guò)程中玩家可以放松心情得到娛樂(lè)。 </p><p><b> 2.2 主體功能<
16、/b></p><p> 本程序?qū)崿F(xiàn)了一個(gè)小的五子棋游戲,可以實(shí)現(xiàn)兩個(gè)人在用一臺(tái)機(jī)器上進(jìn)行游戲。程序會(huì)自動(dòng)判斷誰(shuí)輸誰(shuí)贏,在游戲的開(kāi)始,第一個(gè)人可以選擇執(zhí)白棋還是黑棋,之后點(diǎn)擊開(kāi)始進(jìn)行游戲。</p><p><b> 2.3 開(kāi)發(fā)環(huán)境</b></p><p> 硬件要求能運(yùn)行Eclipse的windows xp以上系統(tǒng)。JAVA程序設(shè)
17、計(jì)語(yǔ)言及相應(yīng)的集成開(kāi)發(fā)環(huán)境,SDK和ECLIPSE開(kāi)發(fā)工具。</p><p><b> 2.4概念設(shè)計(jì)</b></p><p> 網(wǎng)絡(luò)五子棋是采用網(wǎng)絡(luò)協(xié)議為TCP/IP的網(wǎng)上對(duì)弈游戲,運(yùn)用“客戶端-服務(wù)器“(c/s)網(wǎng)絡(luò)架構(gòu)模式。實(shí)現(xiàn)用戶通過(guò)Internt連接在任何地方與不同玩家進(jìn)行對(duì)戰(zhàn)。服務(wù)器可以創(chuàng)建任意多局游戲。</p><p> 通
18、過(guò)使用多線程和網(wǎng)絡(luò)套接字SOCKET來(lái)實(shí)現(xiàn)游戲之間的通訊,它是基于點(diǎn)對(duì)點(diǎn)的通訊。開(kāi)始讓服務(wù)器初始化建立服務(wù)器套接字SOCKET,基于某個(gè)端口PORT,服務(wù)器始終處于監(jiān)聽(tīng)狀態(tài)。客戶端是動(dòng)作的發(fā)起者,何時(shí)發(fā)出申請(qǐng)由客戶端決定??蛻舳讼蚍?wù)器發(fā)出申請(qǐng),服務(wù)器給予響應(yīng)。打開(kāi)客戶端套接字SOCKET,連接到服務(wù)器端的地址ADDRESS和端口PORT。連接建立后,創(chuàng)建一個(gè)SOCKET實(shí)例,并開(kāi)始一個(gè)線程,監(jiān)聽(tīng)該客戶端請(qǐng)求。服務(wù)器繼續(xù)監(jiān)聽(tīng)其它用戶的連
19、接。服務(wù)器通過(guò)數(shù)據(jù)輸入流從客戶端接收信息,并且通過(guò)數(shù)據(jù)輸出流把相應(yīng)的信息發(fā)送給客戶端??蛻舳税l(fā)送請(qǐng)求和響應(yīng)接收到的各種信息。</p><p> 在服務(wù)器和客戶端之間傳遞的消息格式是采用“[消息類別]+內(nèi)容“組成的,服務(wù)器和客戶端在傳遞消息的過(guò)程,根據(jù)消息的類別來(lái)進(jìn)行相關(guān)的操作。</p><p><b> 3 系統(tǒng)總體設(shè)計(jì)</b></p><p&
20、gt; 3.1 系統(tǒng)的功能模塊示意圖</p><p><b> 3.2 系統(tǒng)流程圖</b></p><p><b> 4系統(tǒng)詳細(xì)設(shè)計(jì)</b></p><p> 4.1 代碼實(shí)現(xiàn)情況</p><p> 4.1.1 server 包 chessServer類</p><p&
21、gt; class MessageServerPanel extends Panel //主消息窗口</p><p> class ServerThread extends Thread //服務(wù)器線程,主要用于服務(wù)器與客戶端的通信</p><p> public class chessServer extends Frame implements ActionListener
22、 //服務(wù)器端框架類</p><p> 4.1.2 client包 chessClient類</p><p> public class chessClient extends Frame implements ActionListener, KeyListener //五子棋客戶端框架,實(shí)現(xiàn)了動(dòng)作監(jiān)聽(tīng)器和鍵盤監(jiān)聽(tīng)器</p><p> public bool
23、ean connectServer(String serverIP, int serverPort) throws Exception //和服務(wù)器建立連接并通信的函數(shù)。return true 連接成功, false 如果失敗.</p><p> 4.1.3 chessface 包 chatPad類</p><p> public class chatPad extends Pan
24、el //聊天信息Panel。Panel上的文本域可以顯示用戶聊天信息。</p><p> 4.1.4 chessface 包 chessPad類</p><p> public class chessPad extends Panel implements MouseListener //顯示棋盤的Panel。此Panel實(shí)現(xiàn)了鼠標(biāo)監(jiān)聽(tīng)器</p><p&g
25、t; class chessPoint_black extends Canvas //表示黑子的類</p><p> class chessPoint_white extends Canvas //表示白子的類</p><p> 4.1.5 chessface包c(diǎn)hessthread類</p><p> public class chessThre
26、ad extends Thread //一個(gè)客戶端用戶線程. 處理用戶落子的點(diǎn)擊事件處理,及消息發(fā)送.</p><p> 4.1.6 chessface 包 controlpad類</p><p> public class controlPad extends Panel //控制Panel。此Panel上的按鈕如其名,完成相應(yīng)的功能。</p><p&g
27、t; 4.1.7 chessface 包 inputpad類</p><p> public class inputPad extends Panel //輸入信息Panel。Panel左邊的下拉列表中列出了所有用戶的名字。右邊的文本框可以輸入聊天信息,點(diǎn)擊回車信息被發(fā)送。</p><p> 4.1.8 chessface 包userPad 類</p><p
28、> public class userPad extends Panel //用戶列表Panel。此Panel維護(hù)一個(gè)服務(wù)器的當(dāng)前用戶列表, 所有的用戶名都將顯示在列表中。</p><p><b> 4.2 測(cè)試分析</b></p><p> 4.2.1程序運(yùn)行情況</p><p><b> //打開(kāi)服務(wù)端<
29、/b></p><p><b> //打開(kāi)客戶端</b></p><p><b> //落子</b></p><p><b> //判定</b></p><p> 4.2.2程序運(yùn)行異常處理</p><p> 啟動(dòng)游戲時(shí),應(yīng)先啟動(dòng)服務(wù)端,
30、然后打開(kāi)客戶端,連接服務(wù)端,建立游戲,加入游戲,然后落子。</p><p> 在啟動(dòng)客戶端時(shí),若是閃退,請(qǐng)先關(guān)閉服務(wù)端,然后重啟。</p><p><b> 5 小結(jié)</b></p><p> 經(jīng)過(guò)為期二周的課程設(shè)計(jì),感覺(jué)自己所學(xué)遠(yuǎn)遠(yuǎn)不能解決做課設(shè)時(shí)的需求。在熟悉課本和上網(wǎng)搜索后,才算馬馬虎虎的完成了任務(wù)。 在畫(huà)棋盤時(shí),調(diào)用draw方法
31、對(duì)于畫(huà)圖這塊的坐標(biāo)布置,在今后學(xué)畫(huà)其他圖畫(huà)時(shí)能夠得心應(yīng)手。獲取棋子方法的巧妙,注冊(cè)鼠標(biāo),獲取點(diǎn)擊位置,除以棋盤間隔,去掉不為整數(shù)的一塊,再乘以棋盤間隔便獲得最臨近點(diǎn)的下棋坐標(biāo),即所要下棋的位置。用二維數(shù)組模擬棋盤,無(wú)棋子的置為0,黑子置為1,白子置為2,以便在判斷勝負(fù)時(shí)利于同色棋子的查找。整個(gè)棋盤就模擬出來(lái)了,很巧妙,不過(guò)有更好的方法用向量存儲(chǔ)棋子信息,便于悔棋等操作。 實(shí)現(xiàn)多用戶聊天,老師后面講的不是很多,做起來(lái)有點(diǎn)費(fèi)力。參考網(wǎng)上資
32、料,明白Socket原理。開(kāi)始時(shí)照著課本上的例子,不能得出想要的效果,而且只運(yùn)行了一個(gè)程序看不到有通信的效果。后面在運(yùn)行了Server類后,自己嘗試著兩個(gè)Client類,實(shí)現(xiàn)了通話,就像騰訊QQ里面一樣的效果。里面定義了Vector 線程,實(shí)現(xiàn)了多線程用法。 兩個(gè)板塊大體實(shí)現(xiàn),但是后面的要求五,由于數(shù)據(jù)庫(kù)的使用不是太熟悉,不能注冊(cè)用戶,添加好友,查找好友,還有悔棋操作未能實(shí)現(xiàn)。此程序最大的缺點(diǎn)還在于,不能實(shí)現(xiàn)</p>&
33、lt;p><b> 參考文獻(xiàn)</b></p><p> 孫衛(wèi)琴 Java面向?qū)ο蠼坛?電子工業(yè)出版社 2006-03 </p><p> 2.孫衛(wèi)琴 Java網(wǎng)絡(luò)編程精解 電子工業(yè)出版社 2006-03 </p><p> 3.張仕斌 Java程序設(shè)計(jì)與應(yīng)用 清華大學(xué)出版社 2005-06 </p>
34、<p> 4.張孝祥 Java就業(yè)培訓(xùn)程序 清華大學(xué)出版社 2003-06 </p><p> 5.耿祥義 Java課程設(shè)計(jì) 清華大學(xué)出版社 2004-03 </p><p> 6.王路群 Java高級(jí)程序設(shè)計(jì) 中國(guó)水利水電出版社 2006-03 </p><p> 7.丁振凡 Java語(yǔ)言使用教程 北京郵電大學(xué)出版社 200
35、5-06 </p><p> 8.薛為民 Java應(yīng)用教程 清華大學(xué)出版社 2005-06 </p><p> 9.鐘允中 JAVA入門 遼寧科學(xué)技術(shù)出版社 1997-03 </p><p> 10.鄭莉 Java語(yǔ)言程序設(shè)計(jì) 清華大學(xué)出版社 2006-03</p><p><b> 附 源碼</b&
36、gt;</p><p> 1、server包中chessServer類:</p><p> package server;</p><p> import java.io.*;</p><p> import java.net.*;</p><p> import java.awt.*;</p>
37、<p> import java.util.*;</p><p> import java.awt.event.*;</p><p><b> /**</b></p><p> * 顯示服務(wù)器及用戶信息的Panel類</p><p><b> */</b></p>
38、<p> class MessageServerPanel extends Panel {</p><p><b> // 主消息窗口</b></p><p> TextArea messageBoard = new TextArea("", 22, 50, TextArea.SCROLLBARS_VERTICAL_ONLY);&
39、lt;/p><p> Label statusLabel = new Label("當(dāng)前連接數(shù):", Label.LEFT);</p><p> Panel boardPanel = new Panel();// 主顯示區(qū)Panel</p><p> Panel statusPanel = new Panel();// 連接狀態(tài)Panel<
40、;/p><p> MessageServerPanel() {</p><p> setSize(350, 300);</p><p> setBackground(new Color(204, 204, 204));</p><p> setLayout(new BorderLayout());</p><p>
41、 boardPanel.setLayout(new FlowLayout());</p><p> boardPanel.setSize(210, 210);</p><p> statusPanel.setLayout(new BorderLayout());</p><p> statusPanel.setSize(210, 50);</p>
42、<p> boardPanel.add(messageBoard);</p><p> statusPanel.add(statusLabel, BorderLayout.WEST);</p><p> add(boardPanel, BorderLayout.CENTER);</p><p> add(statusPanel, BorderL
43、ayout.NORTH);</p><p><b> }</b></p><p><b> }</b></p><p><b> /**</b></p><p> * 服務(wù)器線程,主要用于服務(wù)器與客戶端的通信</p><p><b>
44、 */</b></p><p> class ServerThread extends Thread {</p><p> Socket clientSocket;</p><p> Hashtable clientDataHash;// Socket與發(fā)送數(shù)據(jù)的流的映射</p><p> Hashtable client
45、NameHash;// Socket與用戶名的映射</p><p> Hashtable chessPeerHash;// 對(duì)弈的兩個(gè)客戶端用戶名的映射</p><p> MessageServerPanel server;</p><p> boolean isClientClosed = false;</p><p><b&g
46、t; /**</b></p><p> * 服務(wù)器端線程的構(gòu)造函數(shù),用于初始化一些對(duì)象。</p><p><b> */</b></p><p> ServerThread(Socket clientSocket, Hashtable clientDataHash, Hashtable clientNameHash, Has
47、htable chessPeerHash,</p><p> MessageServerPanel server) {</p><p> this.clientSocket = clientSocket;</p><p> this.clientDataHash = clientDataHash;</p><p> this.clie
48、ntNameHash = clientNameHash;</p><p> this.chessPeerHash = chessPeerHash;</p><p> this.server = server;</p><p><b> }</b></p><p><b> /**</b>&l
49、t;/p><p> * 對(duì)客戶端發(fā)來(lái)的消息處理的函數(shù),處理后轉(zhuǎn)發(fā)回客戶端。處理消息的過(guò)程比較復(fù)雜, 要針對(duì)很多種情況分別處理。</p><p><b> */</b></p><p> public void messageTransfer(String message) {</p><p> String clie
50、ntName, peerName;</p><p> /////////////命令處理///////////////////////////////</p><p> // 如果消息以“/”開(kāi)頭,表明是命令消息。</p><p> if (message.startsWith("/")) {</p><p> /
51、/ 如果消息以“/list”開(kāi)頭,則將其回饋到客戶端以更新用戶列表</p><p> if (message.equals("/list")) {</p><p> Feedback(getUserList());</p><p><b> }</b></p><p> // 如果消息以&qu
52、ot;/creatgame [inchess]"開(kāi)頭,則修改clientNameHash映射</p><p> // 和chessPeerHash映射。</p><p> else if (message.startsWith("/creatgame [inchess]")) {</p><p><b> //</
53、b></p><p> String chessServerName = message.substring(20);</p><p> synchronized (clientNameHash) {</p><p> clientNameHash.put(clientSocket, message.substring(11));</p>
54、<p><b> }</b></p><p> synchronized (chessPeerHash) {//剛創(chuàng)建,等待其他人加入</p><p> chessPeerHash.put(chessServerName, "wait");</p><p><b> }</b><
55、/p><p> Feedback("/yourname " + clientNameHash.get(clientSocket));</p><p> chessPeerTalk(chessServerName, "/OK");</p><p> publicTalk(getUserList());</p>&
56、lt;p><b> }</b></p><p> // 如果消息以“/joingame”開(kāi)頭,則將消息的服務(wù)端名字和本地用戶名提取出來(lái),</p><p> // 然后修改clientNameHash表和chessPeerHash表。</p><p> if (message.startsWith("/joingame &
57、quot;)) {</p><p> StringTokenizer userToken = new StringTokenizer(message, " ");</p><p> String getUserToken, serverName, selfName;</p><p> String[] chessNameOpt = {&qu
58、ot;0", "0"};</p><p> int getOptNum = 0;</p><p> // 提取服務(wù)端用戶名和本地用戶名</p><p> while (userToken.hasMoreTokens()) {</p><p> getUserToken = (String) userTok
59、en.nextToken(" ");</p><p> if (getOptNum >= 1 && getOptNum <= 2) {</p><p> chessNameOpt[getOptNum - 1] = getUserToken;</p><p><b> }</b></p&
60、gt;<p> getOptNum++;</p><p><b> }</b></p><p> serverName = chessNameOpt[0];</p><p> selfName = chessNameOpt[1];</p><p> // 如果有服務(wù)端在等待開(kāi)始棋局</p&g
61、t;<p> if (chessPeerHash.containsKey(serverName) && chessPeerHash.get(serverName).equals("wait")) {</p><p> // 修改Socket和名字映射</p><p> synchronized (clientNameHash) {&l
62、t;/p><p> clientNameHash.put(clientSocket, ("[inchess]" + selfName));</p><p><b> }</b></p><p> // 修改chessPeerHash映射</p><p> synchronized (chessPe
63、erHash) {</p><p> chessPeerHash.put(serverName, selfName);</p><p><b> }</b></p><p> publicTalk(getUserList());</p><p> chessPeerTalk(selfName, ("/p
64、eer " + "[inchess]" + serverName));</p><p> chessPeerTalk(serverName, ("/peer " + "[inchess]" + selfName));</p><p><b> } else {</b></p>&l
65、t;p> chessPeerTalk(selfName, "/reject");</p><p><b> try {</b></p><p> clientClose();</p><p> } catch (Exception ez) {</p><p><b> }&l
66、t;/b></p><p><b> }</b></p><p><b> }</b></p><p> // 如果消息以“/[inchess]”開(kāi)頭,則獲取要發(fā)送消息的用戶名和發(fā)送的消息</p><p> // 然后發(fā)送出去。</p><p> else i
67、f (message.startsWith("/[inchess]")) {</p><p> int firstLocation = 0, lastLocation;</p><p> lastLocation = message.indexOf(" ", 0);</p><p> peerName = message
68、.substring((firstLocation + 1), lastLocation);</p><p> message = message.substring((lastLocation + 1));</p><p> if (chessPeerTalk(peerName, message)) {</p><p> Feedback("/er
69、ror");</p><p><b> }</b></p><p><b> }</b></p><p> // 如果消息以“/giveup”開(kāi)頭,則判斷是對(duì)弈雙方哪方放棄了。</p><p> else if (message.startsWith("/giveup &
70、quot;)) {</p><p> String chessClientName = message.substring(8);</p><p> if (chessPeerHash.containsKey(chessClientName)</p><p> && !((String) chessPeerHash.get(chessClien
71、tName)).equals("wait")) {</p><p> // 如果服務(wù)方放棄,則發(fā)送消息“/youwin”表明對(duì)方獲勝</p><p> chessPeerTalk((String) chessPeerHash.get(chessClientName), "/youwin");</p><p> //剔除這
72、對(duì)對(duì)弈的人。。</p><p> synchronized (chessPeerHash) {</p><p> chessPeerHash.remove(chessClientName);</p><p><b> }</b></p><p><b> }</b></p>&
73、lt;p> if (chessPeerHash.containsValue(chessClientName)) {</p><p> // 如果客戶方放棄,也發(fā)送消息“/youwin”表明對(duì)方獲勝</p><p> chessPeerTalk((String) getHashKey(chessPeerHash, chessClientName), "/youwin&q
74、uot;);</p><p> synchronized (chessPeerHash) {</p><p> chessPeerHash.remove((String) getHashKey(chessPeerHash, chessClientName));</p><p><b> }</b></p><p>
75、<b> }</b></p><p><b> }</b></p><p> // 如果找不到發(fā)送消息的用戶,則輸出消息說(shuō)“沒(méi)有這個(gè)用戶”</p><p><b> else {</b></p><p> int firstLocation = 0, lastLoca
76、tion;</p><p> lastLocation = message.indexOf(" ", 0);</p><p> if (lastLocation == -1) {</p><p> Feedback("無(wú)效命令");</p><p><b> return;</b
77、></p><p><b> } else {</b></p><p> peerName = message.substring((firstLocation + 1), lastLocation);</p><p> message = message.substring((lastLocation + 1));</p&g
78、t;<p> message = (String) clientNameHash.get(clientSocket) + ">" + message;</p><p> if (peerTalk(peerName, message)) {</p><p> Feedback("沒(méi)有這個(gè)用戶:" + peerName + &q
79、uot;\n");</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p> // ////////
80、//////////////////////////////////////</p><p> // 如果不以“/”開(kāi)頭,表明是普通消息,直接發(fā)送</p><p><b> else {</b></p><p> message = clientNameHash.get(clientSocket) + ">" +
81、 message;</p><p> server.messageBoard.append(message + "\n");</p><p> publicTalk(message);</p><p> server.messageBoard.setCaretPosition(server.messageBoard.getText().le
82、ngth());</p><p><b> }</b></p><p><b> }</b></p><p><b> /**</b></p><p> * 發(fā)送公共消息的函數(shù),將消息向每個(gè)客戶端都發(fā)送一份</p><p><b>
83、*/</b></p><p> public void publicTalk(String publicTalkMessage) {</p><p> synchronized (clientDataHash) {</p><p> //枚舉遍歷所有客戶端輸出流。。</p><p> for (Enumeration en
84、u = clientDataHash.elements(); enu.hasMoreElements();) {</p><p> DataOutputStream outData = (DataOutputStream) enu.nextElement();</p><p><b> try {</b></p><p> //輸出信息。
85、。這里會(huì)阻塞</p><p> outData.writeUTF(publicTalkMessage);</p><p> } catch (IOException es) {</p><p> //打印異常堆棧。。。終止程序。。</p><p> es.printStackTrace();</p><p>&
86、lt;b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><b> /**</b></p><p> *
87、選擇對(duì)象發(fā)送消息,參數(shù)peerTalk為發(fā)送的用戶名,后面的參數(shù)為發(fā)送的消息</p><p><b> */</b></p><p> public boolean peerTalk(String peerTalk, String talkMessage) {</p><p><b> //</b></p>
88、;<p> for (Enumeration enu = clientDataHash.keys(); enu.hasMoreElements();) {</p><p> Socket userClient = (Socket) enu.nextElement();</p><p> // 找到發(fā)送消息的對(duì)象,獲取它的輸出流以發(fā)送消息</p><p
89、> if (peerTalk.equals((String) clientNameHash.get(userClient))</p><p> && !peerTalk.equals((String) clientNameHash.get(clientSocket))) {</p><p> synchronized (clientDataHash) {<
90、/p><p> DataOutputStream peerOutData = (DataOutputStream) clientDataHash.get(userClient);</p><p><b> try {</b></p><p> peerOutData.writeUTF(talkMessage);</p><
91、p> } catch (IOException es) {</p><p> es.printStackTrace();</p><p><b> }</b></p><p><b> }</b></p><p> Feedback(talkMessage);</p>
92、<p> return (false);</p><p><b> }</b></p><p> // 如果是發(fā)給自己的,直接回饋</p><p> else if (peerTalk.equals((String) clientNameHash.get(clientSocket))) {</p><p&g
93、t; Feedback(talkMessage);</p><p> return (false);</p><p><b> }</b></p><p><b> }</b></p><p> return (true);</p><p><b> }
94、</b></p><p><b> /**</b></p><p> * 此函數(shù)也用于選擇發(fā)送消息,但不能發(fā)送給自己。</p><p><b> */</b></p><p> public boolean chessPeerTalk(String chessPeerTalk,
95、String chessTalkMessage) {</p><p> for (Enumeration enu = clientDataHash.keys(); enu.hasMoreElements();) {</p><p> Socket userClient = (Socket) enu.nextElement();</p><p> if (che
96、ssPeerTalk.equals((String) clientNameHash.get(userClient))</p><p> && !chessPeerTalk.equals((String) clientNameHash.get(clientSocket))) {</p><p> synchronized (clientDataHash) {</p&
97、gt;<p> DataOutputStream peerOutData = (DataOutputStream) clientDataHash.get(userClient);</p><p><b> try {</b></p><p> peerOutData.writeUTF(chessTalkMessage);</p>&l
98、t;p> } catch (IOException es) {</p><p> es.printStackTrace();</p><p><b> }</b></p><p><b> }</b></p><p> return (false);</p><p
99、><b> }</b></p><p><b> }</b></p><p> return (true);</p><p><b> }</b></p><p><b> /**</b></p><p> * 用
100、于處理消息回饋的函數(shù)</p><p><b> */</b></p><p> public void Feedback(String feedbackString) {</p><p> synchronized (clientDataHash) {</p><p> //得到輸出流。。。</p>
101、<p> DataOutputStream outData = (DataOutputStream) clientDataHash.get(clientSocket);</p><p><b> try {</b></p><p><b> //輸出信息。。。</b></p><p> outData.
102、writeUTF(feedbackString);</p><p> } catch (Exception eb) {</p><p> //打印堆棧軌跡,程序終止。。</p><p> eb.printStackTrace();</p><p><b> }</b></p><p>&l
103、t;b> }</b></p><p><b> }</b></p><p><b> /**</b></p><p> * 獲取用戶列表的函數(shù),此函數(shù)讀取clientNameHash獲取用戶列表, 然后將其保存在一個(gè)字符串userList中。</p><p><b&g
104、t; */</b></p><p> public String getUserList() {</p><p> String userList = "/userlist";</p><p> //遍歷hashtable中的values,以空格分割連接起來(lái)</p><p> for (Enumera
105、tion enu = clientNameHash.elements(); enu.hasMoreElements();) {</p><p> userList = userList + " " + (String) enu.nextElement();</p><p><b> }</b></p><p> ret
106、urn userList;</p><p><b> }</b></p><p><b> /**</b></p><p> * 給出HashTable和值對(duì)象,獲取相對(duì)應(yīng)得鍵值的函數(shù)。</p><p><b> */</b></p><p>
107、 public Object getHashKey(Hashtable targetHash, Object hashValue) {</p><p> Object hashKey;</p><p> for (Enumeration enu = targetHash.keys(); enu.hasMoreElements();) {</p><p> ha
108、shKey = (Object) enu.nextElement();</p><p> //如果鍵對(duì)應(yīng)的值與hashValue相等,則返回這個(gè)key</p><p> if (hashValue.equals((Object) targetHash.get(hashKey)))</p><p> return (hashKey);</p>&l
109、t;p><b> }</b></p><p> return (null);</p><p><b> }</b></p><p> public void firstCome() {</p><p> //新用戶第一次加入、廣播用戶列表。。</p><p>
110、 publicTalk(getUserList());</p><p> //反饋給這個(gè)用戶,以修改相應(yīng)顯示信息。。</p><p> Feedback("/yourname " + (String) clientNameHash.get(clientSocket));</p><p> Feedback("Java五子棋聊天客
111、戶端");</p><p> Feedback("/changename <你的名字> --更改名字");</p><p> Feedback("/list --更新用戶列表");</p><p> Feedback("/<用戶名> <要說(shuō)的話> --私聊"
112、;);</p><p> Feedback("注意:用命令的時(shí)候,先把談話的對(duì)象定為所有人");</p><p><b> }</b></p><p><b> /**</b></p><p> * 用于和客戶端斷開(kāi)的函數(shù)。</p><p><
113、;b> */</b></p><p> public void clientClose() {</p><p> server.messageBoard.append("用戶斷開(kāi):" + clientSocket + "\n");</p><p> // 如果是游戲客戶端主機(jī)</p>&
114、lt;p> synchronized (chessPeerHash) {</p><p> if (chessPeerHash.containsKey(clientNameHash.get(clientSocket))) {</p><p> chessPeerHash.remove((String) clientNameHash.get(clientSocket));<
115、/p><p><b> }</b></p><p> if (chessPeerHash.containsValue(clientNameHash.get(clientSocket))) {</p><p> chessPeerHash.put((String) getHashKey(chessPeerHash, (String) clien
116、tNameHash.get(clientSocket)),</p><p> "tobeclosed");</p><p><b> }</b></p><p><b> }</b></p><p> // 將保留的HashTable里的數(shù)據(jù)清除</p>&
117、lt;p> synchronized (clientDataHash) {</p><p> clientDataHash.remove(clientSocket);</p><p><b> }</b></p><p> synchronized (clientNameHash) {</p><p>
118、clientNameHash.remove(clientSocket);</p><p><b> }</b></p><p> //廣播更新用戶列表。。。</p><p> publicTalk(getUserList());</p><p> // 計(jì)算當(dāng)前連接數(shù),并顯示在狀態(tài)框中</p>&l
119、t;p> server.statusLabel.setText("當(dāng)前連接數(shù):" + clientDataHash.size());</p><p><b> try {</b></p><p> clientSocket.close();</p><p> } catch (IOException exx)
120、{</p><p><b> }</b></p><p> isClientClosed = true;</p><p><b> }</b></p><p> public void run() {</p><p> DataInputStream inData;
121、</p><p> synchronized (clientDataHash) {</p><p> server.statusLabel.setText("當(dāng)前連接數(shù):" + clientDataHash.size());</p><p><b> }</b></p><p><b>
122、; try {</b></p><p> inData = new DataInputStream(clientSocket.getInputStream());</p><p> firstCome();</p><p> while (true) {</p><p> String message = inData.
123、readUTF();</p><p> messageTransfer(message);</p><p><b> }</b></p><p> } catch (IOException esx) {</p><p> } finally {</p><p> if (!isClien
124、tClosed) {</p><p> clientClose();</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><b> }</b>&
125、lt;/p><p><b> /**</b></p><p> * @author wufenghanren 服務(wù)器端框架類</p><p><b> */</b></p><p> public class chessServer extends Frame implements Action
126、Listener {</p><p> Button messageClearButton = new Button("清除顯示");</p><p> Button serverStatusButton = new Button("服務(wù)器狀態(tài)");</p><p> Button serverOffButton = n
127、ew Button("關(guān)閉服務(wù)器");</p><p> Panel buttonPanel = new Panel();</p><p> MessageServerPanel server = new MessageServerPanel();</p><p> ServerSocket serverSocket;</p>
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- java課程設(shè)計(jì)--五子棋
- 五子棋java課程設(shè)計(jì)
- 五子棋java課程設(shè)計(jì)
- java課程設(shè)計(jì)--五子棋游戲
- java課程設(shè)計(jì)--對(duì)戰(zhàn)五子棋
- java課程設(shè)計(jì)-五子棋游戲
- java課程設(shè)計(jì)報(bào)告-五子棋
- java課程設(shè)計(jì)--人機(jī)對(duì)弈五子棋
- 五子棋java語(yǔ)言課程設(shè)計(jì)報(bào)告
- java課程設(shè)計(jì)報(bào)告---java 五子棋游戲設(shè)計(jì)
- 五子棋課程設(shè)計(jì)
- java課程設(shè)計(jì)五子棋(附源代碼)
- java_五子棋小游戲課程設(shè)計(jì)
- 五子棋-課程設(shè)計(jì)報(bào)告
- java課程設(shè)計(jì)報(bào)告---單機(jī)版五子棋
- 面向?qū)ο蟪绦蛟O(shè)計(jì)---五子棋-java課程設(shè)計(jì)
- 五子棋c++課程設(shè)計(jì)
- 五子棋c++課程設(shè)計(jì)
- 五子棋小游戲課程設(shè)計(jì)
- 《java程序設(shè)計(jì)》課程設(shè)計(jì)-五子棋小游戲
評(píng)論
0/150
提交評(píng)論