版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、<p> 編號: </p><p> 計算機(jī)網(wǎng)絡(luò)課程設(shè)計說明書</p><p> 題 目:網(wǎng)絡(luò)對弈程序設(shè)計 </p><p> 系 別:計算機(jī)科學(xué)與工程學(xué)院 </p><p> 專 業(yè):計算機(jī)科學(xué)與技術(shù) </p><p>
2、 學(xué)生姓名: </p><p> 學(xué) 號: </p><p> 指導(dǎo)教師: </p><p> 2013 年 3 月 20 日</p><p><b> 目 錄</b></p><
3、;p> 1 設(shè)計任務(wù)及目標(biāo)1</p><p> 1.1 開發(fā)背景以及設(shè)計目標(biāo)1</p><p><b> 1.2設(shè)計任務(wù)1</b></p><p><b> 2 需求分析2</b></p><p><b> 2.1系統(tǒng)需求2</b></p>
4、<p><b> 2.2用戶需求2</b></p><p> 2.2.1服務(wù)端需求2</p><p> 2.2.2客戶端需求2</p><p> 2.2.3技術(shù)上可行性分析3</p><p> 2.3.系統(tǒng)運行環(huán)境4</p><p><b> 3 總體
5、設(shè)計4</b></p><p> 3.1系統(tǒng)結(jié)構(gòu)設(shè)計4</p><p> 3.2服務(wù)器設(shè)計5</p><p> 3.3客戶端設(shè)計7</p><p><b> 3.4棋類設(shè)計8</b></p><p><b> 4 詳細(xì)設(shè)計9</b></
6、p><p><b> 4.1 服務(wù)器9</b></p><p> 4.1.1服務(wù)器主類的設(shè)計開發(fā)9</p><p> 4.1.2服務(wù)器線程的設(shè)計開發(fā)13</p><p> 4.2 客戶端23</p><p> 4.3棋盤以及規(guī)則26</p><p> 5
7、軟件實現(xiàn)以及使用說明46</p><p> 5.1服務(wù)器運行使用及測試46</p><p> 5.2 客戶端運行使用及測試49</p><p><b> 6 總結(jié)53</b></p><p> 6.1任務(wù)完成情況53</p><p> 6.2特色與不足53</p>
8、<p> 6.2.1特色53</p><p> 6.2.2不足53</p><p> 6.3所遇到的問題53</p><p><b> 6.4體會54</b></p><p><b> 7 參考文獻(xiàn)55</b></p><p><b&g
9、t; 1 設(shè)計任務(wù)及目標(biāo)</b></p><p> 1.1 開發(fā)背景以及設(shè)計目標(biāo)</p><p> 五子棋有著悠久的歷史,五子棋愛好者更是不計其數(shù),但是由于人們工作地點,時間的限制,生活節(jié)奏的加快,人們之間的交流越來越少,面對面下五子棋的機(jī)會更是少了很多,那種面對面的下棋的方式已經(jīng)不再適應(yīng)人們的生活,但網(wǎng)絡(luò)給了人們一個交流的平臺,因此人們開始轉(zhuǎn)向網(wǎng)絡(luò)五子棋。</p&
10、gt;<p> 網(wǎng)絡(luò)五子棋有很多優(yōu)點,通過網(wǎng)絡(luò)五子棋,對弈雙方可以是網(wǎng)絡(luò)上任意兩個五子棋的愛好者,甚至從不認(rèn)識。網(wǎng)絡(luò)五子棋讓對弈的范圍更加的廣泛,讓玩家可以與更多的五子棋愛好者切磋棋藝。</p><p> 所以我此次網(wǎng)絡(luò)課程設(shè)計綜合運用《計算機(jī)網(wǎng)絡(luò)》、《JAVA語言程序設(shè)計》、《網(wǎng)絡(luò)編程》等課程知識;從需求分析入手,系統(tǒng)地掌握計算機(jī)網(wǎng)絡(luò)編程初級技術(shù),獨立、合理地完成網(wǎng)絡(luò)五子棋對弈程序設(shè)計任務(wù)。設(shè)
11、計目標(biāo)主要包括:</p><p> (1)實現(xiàn)需求分析階段所要求的服務(wù)器端以及客戶端的功能。</p><p> ?。?)游戲界面樸素美觀。</p><p> ?。?)棋子樣式采用傳統(tǒng)樣式,黑色和白色。</p><p> ?。?)客戶端的信息交流完全通過服務(wù)器傳遞完成。</p><p><b> 1.2設(shè)計
12、任務(wù)</b></p><p> 完成一個網(wǎng)絡(luò)五子棋對弈程序設(shè)計工作。</p><p> 根據(jù)自身多年來進(jìn)行網(wǎng)絡(luò)對弈的經(jīng)驗,以及了解,對網(wǎng)絡(luò)五子棋對弈的設(shè)計進(jìn)行需求分析。根根設(shè)計目標(biāo)以及需求分析對五子棋游戲界面總體規(guī)劃和設(shè)計,游戲界面設(shè)計好以后進(jìn)行服務(wù)器端和客戶端的規(guī)劃設(shè)計,最后進(jìn)行棋盤以及棋子的設(shè)計。設(shè)計階段要進(jìn)行服務(wù)器端框架設(shè)計與業(yè)務(wù)代碼開發(fā),客戶端框架設(shè)計與業(yè)務(wù)代碼的開
13、發(fā),棋子以及棋盤類的設(shè)計開發(fā),規(guī)則類的設(shè)計開發(fā)等。</p><p><b> 2 需求分析 </b></p><p><b> 2.1系統(tǒng)需求</b></p><p> 滿足客戶端連接到服務(wù)器的基本要求。</p><p> 服務(wù)器滿足記錄客戶端游戲動作的基本要求。</p>&l
14、t;p> 滿足服務(wù)器實時獲得客戶端游戲狀態(tài)的基本要求。</p><p><b> 2.2用戶需求</b></p><p> 2.2.1服務(wù)端需求</p><p> ?。?)可以有一個顯示服務(wù)器狀態(tài)的界面,用于記錄各個客戶端的連接狀態(tài)。服務(wù)器是用于連接各個客戶端的通信,如果獨立地創(chuàng)建一個直觀的服務(wù)器,將有力地顯示客戶端的每個狀態(tài),直觀
15、地向用戶反應(yīng)各類信息。</p><p> ?。?)可以支持多人同時在線。一個服務(wù)器能夠你能夠接受來自其他多個客戶端的請求,提供相應(yīng)的響應(yīng)服務(wù),是網(wǎng)絡(luò)對弈的基本要求。</p><p> ?。?)可以顯示在線用戶的信息。顯示在線用戶的信息,比如主機(jī)名,IP地址,以及連接斷的狀態(tài),有利于用戶隨時監(jiān)控客戶端的通信狀態(tài)。</p><p> ?。?)不允許玩家同名。不允許客戶端
16、同名即是不允許客戶端的端口號相同,如果相同,將會造成游戲登陸用戶的管理混亂。</p><p> ?。?)服務(wù)器界面節(jié)約大方。服務(wù)器是用于監(jiān)控客戶端的連接情況,沒用必要做得繁雜,用戶只需要直觀的狀態(tài)顯示,所以我們的服務(wù)器不需要設(shè)計太多按鈕,只需要有顯示服務(wù)器狀態(tài),關(guān)閉服務(wù)器,清空列表的按鈕,方便用戶操作。</p><p> 2.2.2客戶端需求 </p><p>
17、 能夠通過主機(jī)IP及端口號登陸到服務(wù)器。 </p><p> 可以顯示當(dāng)前所有用戶。游戲客戶端應(yīng)設(shè)計一個可以顯示當(dāng)前 所有在線用戶的列表,有助于用戶隨意選擇玩家挑戰(zhàn)。</p><p> 可以從在線用戶列表中選擇玩家進(jìn)行挑戰(zhàn)。</p><p> 可以創(chuàng)建以及接受挑戰(zhàn)。</p><p> 如果對方正在與其他玩家對弈,則應(yīng)給出相應(yīng)提示。&
18、lt;/p><p> 五子棋規(guī)則一定要嚴(yán)密。其中五子棋游戲的規(guī)則如下:</p><p><b> 棋盤,棋子:</b></p><p> 棋盤為十五路,正中一點為“天元”,周圍四點為小星。</p><p> 棋子分黑白兩色,黑子113枚,白子112枚,共225枚。</p><p><b&
19、gt; 比賽規(guī)則:</b></p><p> 黑先白后,從天元開始落子。然后執(zhí)白棋的一方在黑棋周圍的交叉點上落子,白第二著棋應(yīng)布在自己河界的一側(cè)。此后,執(zhí)黑方在以天元為中心的25個交叉點的范圍內(nèi)布盤面的第三著棋。</p><p> 最先在橫向,豎向,斜向形成連續(xù)的相同色五個棋子的一方為勝。</p><p> 黑棋禁手判負(fù),白棋無禁手。黑棋禁手包括
20、“三三”,“四四”,“長連”。黑方只能“四三”勝。所謂禁手,是指黑方一子落下同時形成兩個或兩個以上的活三,沖四及長連禁手。長連禁手是指黑方形成六個或六個以上的連續(xù)棋子。</p><p> 雙方均不能形成五連為和棋。</p><p> 對局中拔子,中途退場均判為負(fù)。</p><p> 五連與禁手同時形成,先五為勝。因黑方已形成五連,故禁手失效,黑方勝。</
21、p><p> 黑方禁手形成時,白方應(yīng)立即指出禁手點,黑方即負(fù)。若白方繼續(xù)應(yīng)子,則黑方禁手不成立。</p><p> 高段位職業(yè)比賽的特殊規(guī)定:“三手可交換”:黑下完第2手,執(zhí)白者可提出交換。即執(zhí)白方變?yōu)閳?zhí)黑方?!拔迨謨纱蚍ā保簣?zhí)黑下第五手時,必須下兩手棋,執(zhí)白者從這兩手棋中任選一步。</p><p> 本文所論述的聯(lián)機(jī)五子棋系統(tǒng)就是依照這種方式進(jìn)行的。</p
22、><p> 2.2.3技術(shù)上可行性分析</p><p> 對需求分析階段的結(jié)果進(jìn)行總結(jié),對軟件的可行性分析如下:</p><p> 網(wǎng)絡(luò)對弈需要兩個客戶端進(jìn)行通信,而利用服務(wù)器的線程開發(fā),進(jìn)行中間中介連接正好可以完成。</p><p> 五子棋的規(guī)則雖然嚴(yán)密,但是通過各種情況分析,然后將每個情況分析設(shè)計出來。</p><
23、;p> 本系統(tǒng)的設(shè)計運行環(huán)境只用到MyEclipse的編程軟件,無需借用到其它的軟件,比較容易實現(xiàn)。</p><p> 2.3.系統(tǒng)運行環(huán)境</p><p> 系統(tǒng)運行環(huán)境:MyEclipse 6.6</p><p><b> 3 總體設(shè)計</b></p><p><b> 3.1系統(tǒng)結(jié)構(gòu)設(shè)計&
24、lt;/b></p><p> 該游戲主要分為服務(wù)器端與客戶端兩部分。</p><p> 服務(wù)器端的功能主要是建立與客戶端的連接,監(jiān)控客戶端的連接及斷開的狀態(tài),接收客戶端發(fā)送的信息以及向客戶端發(fā)送信息。</p><p> 客戶端的功能主要是連接服務(wù)器端,創(chuàng)建游戲用戶,創(chuàng)建游戲,加入游戲,選擇玩家挑戰(zhàn),向服務(wù)器發(fā)送信息,接收服務(wù)器端發(fā)送來的信息。其具體的功
25、能模塊如圖所示:</p><p><b> 3.2服務(wù)器設(shè)計</b></p><p> 服務(wù)器的設(shè)計主要分為服務(wù)器主界面,服務(wù)器線程,服務(wù)器主機(jī)面板三個部分。</p><p> 服務(wù)器主界面的設(shè)計主要包括界面大小,界面背景,界面上的按鈕,比如清空列表,服務(wù)器狀態(tài),關(guān)閉服務(wù)器的設(shè)計,以及啟動對客戶端的監(jiān)聽,啟動服務(wù)器線程。</p>
26、;<p> 服務(wù)器線程的設(shè)計主要包括接受多個客戶端的連接,接受客戶端信息,向客戶端發(fā)送信息。</p><p> 服務(wù)器主機(jī)面板的設(shè)計主要包括客戶端信息板的設(shè)計,包括板的大小,背景顏色。其具體的功能模塊如圖所示:</p><p><b> 3.3客戶端設(shè)計</b></p><p> 客戶端的設(shè)計主要分為客戶端界面,客戶端線程
27、兩部分。</p><p> 客戶端界面的設(shè)計主要包括客戶端界面大小,背景顏色,主要按鈕:創(chuàng)建游戲,加入游戲,連接到服務(wù)器,放棄游戲,退出游戲的設(shè)計以及它們對應(yīng)事件的處理。</p><p> 客戶端線程的設(shè)計主要包括連接到服務(wù)器,向服務(wù)器發(fā)送信息,接受服務(wù)器信息的設(shè)計以及它們對應(yīng)的事件處理,比如收到服務(wù)器發(fā)送來的游戲勝利,信息錯誤,信息有效等的處理。其具體功能模塊如圖所示:</p&
28、gt;<p><b> 3.4棋類設(shè)計</b></p><p> 五子棋類的設(shè)計主要分為棋盤,棋子,五子棋動作線程,規(guī)則四部分。</p><p> 棋盤的設(shè)計主要包括畫棋子,捕獲下棋事件,畫網(wǎng)絡(luò)棋盤。棋子的設(shè)計包括黑棋以及白旗的設(shè)計,其中有大小,顏色,所屬棋盤的設(shè)計。</p><p> 五子棋動作線程的設(shè)計包括處理捕獲下
29、棋信息,發(fā)送當(dāng)前下棋信息,這一部分的設(shè)計是五子棋類設(shè)計的重點。</p><p> 規(guī)則的設(shè)包括取得指定棋子的位置,判斷當(dāng)前棋子是否取得勝利,當(dāng)前棋子各個方向的判斷,當(dāng)前所要下的棋子是否越界。</p><p><b> 4 詳細(xì)設(shè)計</b></p><p><b> 4.1 服務(wù)器</b></p><
30、;p> 4.1.1服務(wù)器主類的設(shè)計開發(fā)</p><p> 服務(wù)器主類即服務(wù)器端的運行類,用戶通過運行該類進(jìn)入服務(wù)器的主界面。其中包括創(chuàng)建服務(wù)器端用到的控件以及聲明用到的對象引用,完成對控件的初始化:設(shè)置窗體的標(biāo)題,圖標(biāo),大小以及可見性,將各個控件添加到各面板的相應(yīng)位置</p><p> FIRServer.java類:</p><p><b>
31、 // 服務(wù)器界面類</b></p><p> public class FIRServer extends Frame implements ActionListener</p><p><b> {</b></p><p> JButton clearMsgButton = new JButton("清空列表&
32、quot;);</p><p> JButton serverStatusButton = new JButton("服務(wù)器狀態(tài)");</p><p> JButton closeServerButton = new JButton("關(guān)閉服務(wù)器");</p><p> Panel buttonPanel = new P
33、anel();</p><p> ServerMsgPanel serverMsgPanel = new ServerMsgPanel();</p><p> ServerSocket serverSocket;</p><p> Hashtable clientDataHash = new Hashtable(50); //將客戶端套接口和輸出流綁定<
34、/p><p> Hashtable clientNameHash = new Hashtable(50); //將客戶端套接口和客戶名綁定</p><p> Hashtable chessPeerHash = new Hashtable(50); //將游戲創(chuàng)建者和游戲加入者綁定</p><p> public FIRServer()</p><
35、;p><b> {</b></p><p> super("Java 五子棋服務(wù)器");</p><p> setBackground(Color.LIGHT_GRAY);</p><p> buttonPanel.setLayout(new FlowLayout());</p><p>
36、; clearMsgButton.setSize(60, 25);</p><p> buttonPanel.add(clearMsgButton);</p><p> clearMsgButton.addActionListener(this);</p><p> serverStatusButton.setSize(75, 25);</p>
37、<p> buttonPanel.add(serverStatusButton);</p><p> serverStatusButton.addActionListener(this);</p><p> closeServerButton.setSize(75, 25);</p><p> buttonPanel.add(closeServe
38、rButton);</p><p> closeServerButton.addActionListener(this);</p><p> add(serverMsgPanel, BorderLayout.CENTER);</p><p> add(buttonPanel, BorderLayout.SOUTH);</p><p>
39、 addWindowListener(new WindowAdapter()</p><p><b> {</b></p><p> public void windowClosing(WindowEvent e)</p><p><b> {</b></p><p> System.exi
40、t(0);</p><p><b> }</b></p><p><b> });</b></p><p><b> pack();</b></p><p> setVisible(true);</p><p> setSize(400, 40
41、0);</p><p> setResizable(false);</p><p> validate();</p><p><b> try</b></p><p><b> {</b></p><p> createServer(4331, serverMsgP
42、anel);</p><p><b> }</b></p><p> catch (Exception e)</p><p><b> {</b></p><p> e.printStackTrace();</p><p><b> }</b>
43、</p><p><b> }</b></p><p> // 用指定端口和面板創(chuàng)建服務(wù)器</p><p> public void createServer(int port, ServerMsgPanel serverMsgPanel) throws IOException</p><p><b>
44、 {</b></p><p> Socket clientSocket; // 客戶端套接口</p><p> long clientAccessNumber = 1; // 連接到主機(jī)的客戶數(shù)量</p><p> this.serverMsgPanel = serverMsgPanel; // 設(shè)定當(dāng)前主機(jī)</p><p>
45、;<b> try</b></p><p><b> {</b></p><p> serverSocket = new ServerSocket(port);</p><p> serverMsgPanel.msgTextArea.setText("服務(wù)器啟動于:"</p>&l
46、t;p> + InetAddress.getLocalHost() + ":" //djr</p><p> + serverSocket.getLocalPort() + "\n");</p><p> while (true)</p><p><b> {</b></p>
47、<p> // 監(jiān)聽客戶端套接口的信息</p><p> clientSocket = serverSocket.accept();</p><p> serverMsgPanel.msgTextArea.append("已連接用戶:" + clientSocket + "\n");</p><p> //
48、建立客戶端輸出流</p><p> DataOutputStream outputData = new DataOutputStream(clientSocket</p><p> .getOutputStream());</p><p> // 將客戶端套接口和輸出流綁定</p><p> clientDataHash.put(cl
49、ientSocket, outputData);</p><p> // 將客戶端套接口和客戶名綁定</p><p> clientNameHash</p><p> .put(clientSocket, ("新玩家" + clientAccessNumber++));</p><p> // 創(chuàng)建并運行服務(wù)器端線
50、程</p><p> FIRServerThread thread = new FIRServerThread(clientSocket,</p><p> clientDataHash, clientNameHash, chessPeerHash, serverMsgPanel);</p><p> thread.start();</p>&l
51、t;p><b> }</b></p><p><b> }</b></p><p> catch (IOException ex)</p><p><b> {</b></p><p> ex.printStackTrace();</p><
52、p><b> }</b></p><p><b> }</b></p><p> public void actionPerformed(ActionEvent e)</p><p><b> {</b></p><p> if (e.getSource() =
53、= clearMsgButton)</p><p> { // 清空服務(wù)器信息</p><p> serverMsgPanel.msgTextArea.setText("");</p><p><b> }</b></p><p> if (e.getSource() == serverSta
54、tusButton)</p><p> { // 顯示服務(wù)器信息</p><p><b> try</b></p><p><b> {</b></p><p> serverMsgPanel.msgTextArea.append("服務(wù)器信息:"</p>
55、<p> + InetAddress.getLocalHost() + ":"</p><p> + serverSocket.getLocalPort() + "\n");</p><p><b> }</b></p><p> catch (Exception ee)</p&g
56、t;<p><b> {</b></p><p> ee.printStackTrace();</p><p><b> }</b></p><p><b> }</b></p><p> if (e.getSource() == closeServer
57、Button)</p><p> { // 關(guān)閉服務(wù)器</p><p> System.exit(0);</p><p><b> }</b></p><p><b> }</b></p><p> public static void main(String ar
58、gs[])</p><p><b> {</b></p><p> FIRServer firServer = new FIRServer();</p><p><b> }</b></p><p><b> }</b></p><p> 4.
59、1.2服務(wù)器線程的設(shè)計開發(fā)</p><p> 服務(wù)器線程是服務(wù)器啟動后創(chuàng)建并啟動的第一個線程,該線程主要用于接收客戶端的連接,并未每個連接分配一個服務(wù)器代理線程。服務(wù)器代理線程主要用于接收客戶端傳來的消息,并將該消息轉(zhuǎn)發(fā)給另一個客戶端。服務(wù)器為所有客戶端都分配了一個該類線程實例,單獨為特定客戶端進(jìn)行服務(wù)。同時每一個服務(wù)器代理線程都有能唯一標(biāo)識的名稱。</p><p> FIRServe
60、rThead.java類:</p><p> public class FIRServerThread extends Thread</p><p><b> {</b></p><p> Socket clientSocket; // 保存客戶端套接口信息</p><p> Hashtable clientDa
61、taHash; // 保存客戶端端口與輸出流對應(yīng)的Hash</p><p> Hashtable clientNameHash; // 保存客戶端套接口和客戶名對應(yīng)的Hash</p><p> Hashtable chessPeerHash; // 保存游戲創(chuàng)建者和游戲加入者對應(yīng)的Hash</p><p> ServerMsgPanel serverMsgPa
62、nel;</p><p> boolean isClientClosed = false;</p><p> public FIRServerThread(Socket clientSocket, Hashtable clientDataHash,</p><p> Hashtable clientNameHash, Hashtable chessPeerHa
63、sh,</p><p> ServerMsgPanel server)</p><p><b> {</b></p><p> this.clientSocket = clientSocket;</p><p> this.clientDataHash = clientDataHash;</p>&
64、lt;p> this.clientNameHash = clientNameHash;</p><p> this.chessPeerHash = chessPeerHash;</p><p> this.serverMsgPanel = server;</p><p><b> }</b></p><p>
65、; public void dealWithMsg(String msgReceived)</p><p><b> {</b></p><p> String clientName;</p><p> String peerName;</p><p> if (msgReceived.startsWith(&
66、quot;/"))</p><p><b> {</b></p><p> if (msgReceived.equals("/list"))</p><p> { // 收到的信息為更新用戶列表</p><p> Feedback(getUserList());</p>
67、<p><b> }</b></p><p> else if (msgReceived.startsWith("/creatgame [inchess]"))</p><p> { // 收到的信息為創(chuàng)建游戲</p><p> String gameCreaterName = msgReceived.s
68、ubstring(20); //取得服務(wù)器名</p><p> synchronized (clientNameHash)</p><p> { // 將用戶端口放到用戶列表中</p><p> clientNameHash.put(clientSocket, msgReceived.substring(11));</p><p>&l
69、t;b> }</b></p><p> synchronized (chessPeerHash)</p><p> { // 將主機(jī)設(shè)置為等待狀態(tài)</p><p> chessPeerHash.put(gameCreaterName, "wait");</p><p><b> }&l
70、t;/b></p><p> Feedback("/yourname " + clientNameHash.get(clientSocket));</p><p> sendGamePeerMsg(gameCreaterName, "/OK");</p><p> sendPublicMsg(getUserList
71、());</p><p><b> }</b></p><p> else if (msgReceived.startsWith("/joingame "))</p><p> { // 收到的信息為加入游戲時</p><p> StringTokenizer userTokens = new
72、 StringTokenizer(msgReceived, " ");</p><p> String userToken;</p><p> String gameCreatorName;</p><p> String gamePaticipantName;</p><p> String[] playerNa
73、mes = { "0", "0" };</p><p> int nameIndex = 0;</p><p> while (userTokens.hasMoreTokens())</p><p><b> {</b></p><p> userToken = (Stri
74、ng) userTokens.nextToken(" ");</p><p> if (nameIndex >= 1 && nameIndex <= 2)</p><p><b> {</b></p><p> playerNames[nameIndex - 1] = userToken;
75、// 取得游戲者命</p><p><b> }</b></p><p> nameIndex++;</p><p><b> }</b></p><p> gameCreatorName = playerNames[0];</p><p> gamePaticip
76、antName = playerNames[1];</p><p> if (chessPeerHash.containsKey(gameCreatorName)</p><p> && chessPeerHash.get(gameCreatorName).equals("wait"))</p><p> { // 游戲已創(chuàng)
77、建</p><p> synchronized (clientNameHash)</p><p> { // 增加游戲加入者的套接口與名稱的對應(yīng)</p><p> clientNameHash.put(clientSocket,</p><p> ("[inchess]" + gamePaticipantName)
78、);</p><p><b> }</b></p><p> synchronized (chessPeerHash)</p><p> { // 增加或修改游戲創(chuàng)建者與游戲加入者的名稱的對應(yīng)</p><p> chessPeerHash.put(gameCreatorName, gamePaticipantNa
79、me);</p><p><b> }</b></p><p> sendPublicMsg(getUserList());</p><p> // 發(fā)送信息給游戲加入者</p><p> sendGamePeerMsg(gamePaticipantName,</p><p> (&qu
80、ot;/peer " + "[inchess]" + gameCreatorName));</p><p> // 發(fā)送游戲給游戲創(chuàng)建者</p><p> sendGamePeerMsg(gameCreatorName,</p><p> ("/peer " + "[inchess]" +
81、gamePaticipantName));</p><p><b> }</b></p><p><b> else</b></p><p> { // 若游戲未創(chuàng)建則拒絕加入游戲</p><p> sendGamePeerMsg(gamePaticipantName, "/rej
82、ect");</p><p><b> try</b></p><p><b> {</b></p><p> closeClient();</p><p><b> }</b></p><p> catch (Exception e
83、z)</p><p><b> {</b></p><p> ez.printStackTrace();</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b>&l
84、t;/p><p> else if (msgReceived.startsWith("/[inchess]"))</p><p> { // 收到的信息為游戲中時</p><p> int firstLocation = 0, lastLocation;</p><p> lastLocation = msgRecei
85、ved.indexOf(" ", 0);</p><p> peerName = msgReceived.substring((firstLocation + 1), lastLocation);</p><p> msgReceived = msgReceived.substring((lastLocation + 1));</p><p>
86、; if (sendGamePeerMsg(peerName, msgReceived))</p><p><b> {</b></p><p> Feedback("/error");</p><p><b> }</b></p><p><b> }<
87、;/b></p><p> else if (msgReceived.startsWith("/giveup "))</p><p> { // 收到的信息為放棄游戲時</p><p> String chessClientName = msgReceived.substring(8);</p><p> i
88、f (chessPeerHash.containsKey(chessClientName)</p><p> && !((String) chessPeerHash.get(chessClientName))</p><p> .equals("wait"))</p><p> { // 勝利方為游戲加入者,發(fā)送勝利信息&l
89、t;/p><p> sendGamePeerMsg((String) chessPeerHash.get(chessClientName),</p><p> "/youwin");</p><p> synchronized (chessPeerHash)</p><p> { // 刪除退出游戲的用戶</p&
90、gt;<p> chessPeerHash.remove(chessClientName);</p><p><b> }</b></p><p><b> }</b></p><p> if (chessPeerHash.containsValue(chessClientName))</p&g
91、t;<p> { // 勝利方為游戲創(chuàng)建者,發(fā)送勝利信息</p><p> sendGamePeerMsg((String) getHashKey(chessPeerHash,</p><p> chessClientName), "/youwin");</p><p> synchronized (chessPeerHas
92、h)</p><p> {// 刪除退出游戲的用戶</p><p> chessPeerHash.remove((String) getHashKey(chessPeerHash,</p><p> chessClientName));</p><p><b> }</b></p><p>
93、;<b> }</b></p><p><b> }</b></p><p><b> else</b></p><p> { // 收到的信息為其它信息時</p><p> int lastLocation = msgReceived.indexOf("
94、", 0);</p><p> if (lastLocation == -1)</p><p><b> {</b></p><p> Feedback("無效命令");</p><p><b> return;</b></p><p>
95、<b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><b> else</b></p><p><b> {</b></p><p>
96、msgReceived = clientNameHash.get(clientSocket) + ">" + msgReceived;</p><p> serverMsgPanel.msgTextArea.append(msgReceived + "\n");</p><p> sendPublicMsg(msgReceived);<
97、;/p><p> serverMsgPanel.msgTextArea.setCaretPosition(serverMsgPanel.msgTextArea.getText()</p><p> .length());</p><p><b> }</b></p><p><b> }</b>
98、</p><p><b> // 發(fā)送公開信息</b></p><p> public void sendPublicMsg(String publicMsg)</p><p><b> {</b></p><p> synchronized (clientDataHash)</p&g
99、t;<p><b> {</b></p><p> for (Enumeration enu = clientDataHash.elements(); enu</p><p> .hasMoreElements();)</p><p><b> {</b></p><p>
100、DataOutputStream outputData = (DataOutputStream) enu.nextElement();</p><p><b> try</b></p><p><b> {</b></p><p> outputData.writeUTF(publicMsg);</p>
101、<p><b> }</b></p><p> catch (IOException es)</p><p><b> {</b></p><p> es.printStackTrace();</p><p><b> }</b></p>&
102、lt;p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p> // 發(fā)送信息給指定的游戲中的用戶</p><p> public boolean sendGamePeerMsg(String gam
103、ePeerTarget, String gamePeerMsg)</p><p><b> {</b></p><p> for (Enumeration enu = clientDataHash.keys(); enu.hasMoreElements();)</p><p> { // 遍歷以取得游戲中的用戶的套接口</p>
104、<p> Socket userClient = (Socket) enu.nextElement();</p><p> if (gamePeerTarget.equals((String) clientNameHash.get(userClient))</p><p> && !gamePeerTarget.equals((String) clien
105、tNameHash</p><p> .get(clientSocket)))</p><p> { // 找到要發(fā)送信息的用戶時</p><p> synchronized (clientDataHash)</p><p><b> {</b></p><p><b> //
106、 建立輸出流</b></p><p> DataOutputStream peerOutData = (DataOutputStream) clientDataHash</p><p> .get(userClient);</p><p><b> try</b></p><p><b>
107、{</b></p><p><b> // 發(fā)送信息</b></p><p> peerOutData.writeUTF(gamePeerMsg);</p><p><b> }</b></p><p> catch (IOException es)</p><
108、;p><b> {</b></p><p> es.printStackTrace();</p><p><b> }</b></p><p><b> }</b></p><p> return false;</p><p><b
109、> }</b></p><p><b> }</b></p><p> return true;</p><p><b> }</b></p><p> // 發(fā)送反饋信息給連接到主機(jī)的人</p><p> public void Feedbac
110、k(String feedBackMsg)</p><p><b> {</b></p><p> synchronized (clientDataHash)</p><p><b> {</b></p><p> DataOutputStream outputData = (DataOut
111、putStream) clientDataHash</p><p> .get(clientSocket);</p><p><b> try</b></p><p><b> {</b></p><p> outputData.writeUTF(feedBackMsg);</p>
112、;<p><b> }</b></p><p> catch (Exception eb)</p><p><b> {</b></p><p> eb.printStackTrace();</p><p><b> }</b></p>&
113、lt;p><b> }</b></p><p><b> }</b></p><p><b> // 取得用戶列表</b></p><p> public String getUserList()</p><p><b> {</b><
114、;/p><p> String userList = "/userlist";</p><p> for (Enumeration enu = clientNameHash.elements(); enu.hasMoreElements();)</p><p><b> {</b></p><p>
115、 userList = userList + " " + (String) enu.nextElement();</p><p><b> }</b></p><p> return userList;</p><p><b> }</b></p><p> // 根據(jù)
116、value值從Hashtable中取得相應(yīng)的key</p><p> public Object getHashKey(Hashtable targetHash, Object hashValue)</p><p><b> {</b></p><p> Object hashKey;</p><p> for
117、(Enumeration enu = targetHash.keys(); enu.hasMoreElements();)</p><p><b> {</b></p><p> hashKey = (Object) enu.nextElement();</p><p> if (hashValue.equals((Object) tar
118、getHash.get(hashKey)))</p><p> return hashKey;</p><p><b> }</b></p><p> return null;</p><p><b> }</b></p><p> // 剛連接到主機(jī)時執(zhí)行的方法&
119、lt;/p><p> public void sendInitMsg()</p><p><b> {</b></p><p> sendPublicMsg(getUserList());</p><p> Feedback("/yourname " + (String) clientNameHa
120、sh.get(clientSocket));</p><p> Feedback("Java 五子棋客戶端");</p><p> Feedback("/list --更新用戶列表");</p><p> Feedback("/<username> <talk> --私聊");
121、</p><p> Feedback("注意:命令必須對所有用戶發(fā)送");</p><p><b> }</b></p><p> public void closeClient()</p><p><b> {</b></p><p> ser
122、verMsgPanel.msgTextArea.append("用戶斷開連接:" + clientSocket + "\n");</p><p> synchronized (chessPeerHash)</p><p> { //如果是游戲客戶端主機(jī)</p><p> if (chessPeerHash.contain
123、sKey(clientNameHash.get(clientSocket)))</p><p><b> {</b></p><p> chessPeerHash.remove((String) clientNameHash.get(clientSocket));</p><p><b> }</b></p&g
124、t;<p> if (chessPeerHash.containsValue(clientNameHash.get(clientSocket)))</p><p><b> {</b></p><p> chessPeerHash.put((String) getHashKey(chessPeerHash,</p><p>
125、 (String) clientNameHash.get(clientSocket)),</p><p> "tobeclosed");</p><p><b> }</b></p><p><b> }</b></p><p> synchronized (clien
126、tDataHash)</p><p> { // 刪除客戶數(shù)據(jù)</p><p> clientDataHash.remove(clientSocket);</p><p><b> }</b></p><p> synchronized (clientNameHash)</p><p>
127、 { // 刪除客戶數(shù)據(jù)</p><p> clientNameHash.remove(clientSocket);</p><p><b> }</b></p><p> sendPublicMsg(getUserList());</p><p> serverMsgPanel.statusLabel.setT
128、ext("當(dāng)前連接數(shù):" + clientDataHash.size());</p><p><b> try</b></p><p><b> {</b></p><p> clientSocket.close();</p><p><b> }</b&
129、gt;</p><p> catch (IOException exx)</p><p><b> {</b></p><p> exx.printStackTrace();</p><p><b> }</b></p><p> isClientClosed =
130、true;</p><p><b> }</b></p><p> public void run()</p><p><b> {</b></p><p> DataInputStream inputData;</p><p> synchronized (cli
131、entDataHash)</p><p><b> {</b></p><p> serverMsgPanel.statusLabel.setText("當(dāng)前連接數(shù):" + clientDataHash.size());</p><p><b> }</b></p><p>
132、;<b> try</b></p><p> {// 等待連接到主機(jī)的信息</p><p> inputData = new DataInputStream(clientSocket.getInputStream());</p><p> sendInitMsg();</p><p> while (true
133、)</p><p><b> {</b></p><p> String message = inputData.readUTF();</p><p> dealWithMsg(message);</p><p><b> }</b></p><p><b>
134、; }</b></p><p> catch (IOException esx){}</p><p><b> finally</b></p><p><b> {</b></p><p> if (!isClientClosed)</p><p>&l
135、t;b> {</b></p><p> closeClient();</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><b> }&
溫馨提示
- 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. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 網(wǎng)絡(luò)對弈課程設(shè)計說明書
- 網(wǎng)絡(luò)課程設(shè)計說明書
- 網(wǎng)絡(luò)工程課程設(shè)計說明書
- 課程設(shè)計說明書
- 課程設(shè)計說明書
- 網(wǎng)絡(luò)管理技術(shù)課程設(shè)計說明書
- 前門課程設(shè)計說明書
- javaweb課程設(shè)計說明書
- 后蓋課程設(shè)計說明書
- 鍋爐課程設(shè)計說明書
- 空調(diào)課程設(shè)計說明書
- 蝸輪課程設(shè)計說明書
- 采礦課程設(shè)計說明書
- 機(jī)床課程設(shè)計說明書
- caxa課程設(shè)計說明書
- 化工課程設(shè)計說明書
- vb課程設(shè)計說明書
- 課程設(shè)計說明書.doc
- 課程設(shè)計說明書.doc
- 課程設(shè)計說明書.doc
評論
0/150
提交評論