版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p> 編號(hào): </p><p> 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)說(shuō)明書(shū)</p><p> 題 目:網(wǎng)絡(luò)對(duì)弈程序設(shè)計(jì) </p><p> 系 別:計(jì)算機(jī)科學(xué)與工程學(xué)院 </p><p> 專 業(yè):計(jì)算機(jī)科學(xué)與技術(shù) </p><p>
2、 學(xué)生姓名: </p><p> 學(xué) 號(hào): </p><p> 指導(dǎo)教師: </p><p> 2013 年 3 月 20 日</p><p><b> 目 錄</b></p><
3、;p> 1 設(shè)計(jì)任務(wù)及目標(biāo)1</p><p> 1.1 開(kāi)發(fā)背景以及設(shè)計(jì)目標(biāo)1</p><p><b> 1.2設(shè)計(jì)任務(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)運(yùn)行環(huán)境4</p><p><b> 3 總體
5、設(shè)計(jì)4</b></p><p> 3.1系統(tǒng)結(jié)構(gòu)設(shè)計(jì)4</p><p> 3.2服務(wù)器設(shè)計(jì)5</p><p> 3.3客戶端設(shè)計(jì)7</p><p><b> 3.4棋類設(shè)計(jì)8</b></p><p><b> 4 詳細(xì)設(shè)計(jì)9</b></
6、p><p><b> 4.1 服務(wù)器9</b></p><p> 4.1.1服務(wù)器主類的設(shè)計(jì)開(kāi)發(fā)9</p><p> 4.1.2服務(wù)器線程的設(shè)計(jì)開(kāi)發(fā)13</p><p> 4.2 客戶端23</p><p> 4.3棋盤以及規(guī)則26</p><p> 5
7、軟件實(shí)現(xiàn)以及使用說(shuō)明46</p><p> 5.1服務(wù)器運(yùn)行使用及測(cè)試46</p><p> 5.2 客戶端運(yùn)行使用及測(cè)試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所遇到的問(wèn)題53</p><p><b> 6.4體會(huì)54</b></p><p><b> 7 參考文獻(xiàn)55</b></p><p><b&g
9、t; 1 設(shè)計(jì)任務(wù)及目標(biāo)</b></p><p> 1.1 開(kāi)發(fā)背景以及設(shè)計(jì)目標(biāo)</p><p> 五子棋有著悠久的歷史,五子棋愛(ài)好者更是不計(jì)其數(shù),但是由于人們工作地點(diǎn),時(shí)間的限制,生活節(jié)奏的加快,人們之間的交流越來(lái)越少,面對(duì)面下五子棋的機(jī)會(huì)更是少了很多,那種面對(duì)面的下棋的方式已經(jīng)不再適應(yīng)人們的生活,但網(wǎng)絡(luò)給了人們一個(gè)交流的平臺(tái),因此人們開(kāi)始轉(zhuǎn)向網(wǎng)絡(luò)五子棋。</p&
10、gt;<p> 網(wǎng)絡(luò)五子棋有很多優(yōu)點(diǎn),通過(guò)網(wǎng)絡(luò)五子棋,對(duì)弈雙方可以是網(wǎng)絡(luò)上任意兩個(gè)五子棋的愛(ài)好者,甚至從不認(rèn)識(shí)。網(wǎng)絡(luò)五子棋讓對(duì)弈的范圍更加的廣泛,讓玩家可以與更多的五子棋愛(ài)好者切磋棋藝。</p><p> 所以我此次網(wǎng)絡(luò)課程設(shè)計(jì)綜合運(yùn)用《計(jì)算機(jī)網(wǎng)絡(luò)》、《JAVA語(yǔ)言程序設(shè)計(jì)》、《網(wǎng)絡(luò)編程》等課程知識(shí);從需求分析入手,系統(tǒng)地掌握計(jì)算機(jī)網(wǎng)絡(luò)編程初級(jí)技術(shù),獨(dú)立、合理地完成網(wǎng)絡(luò)五子棋對(duì)弈程序設(shè)計(jì)任務(wù)。設(shè)
11、計(jì)目標(biāo)主要包括:</p><p> ?。?)實(shí)現(xiàn)需求分析階段所要求的服務(wù)器端以及客戶端的功能。</p><p> ?。?)游戲界面樸素美觀。</p><p> ?。?)棋子樣式采用傳統(tǒng)樣式,黑色和白色。</p><p> ?。?)客戶端的信息交流完全通過(guò)服務(wù)器傳遞完成。</p><p><b> 1.2設(shè)計(jì)
12、任務(wù)</b></p><p> 完成一個(gè)網(wǎng)絡(luò)五子棋對(duì)弈程序設(shè)計(jì)工作。</p><p> 根據(jù)自身多年來(lái)進(jìn)行網(wǎng)絡(luò)對(duì)弈的經(jīng)驗(yàn),以及了解,對(duì)網(wǎng)絡(luò)五子棋對(duì)弈的設(shè)計(jì)進(jìn)行需求分析。根根設(shè)計(jì)目標(biāo)以及需求分析對(duì)五子棋游戲界面總體規(guī)劃和設(shè)計(jì),游戲界面設(shè)計(jì)好以后進(jìn)行服務(wù)器端和客戶端的規(guī)劃設(shè)計(jì),最后進(jìn)行棋盤以及棋子的設(shè)計(jì)。設(shè)計(jì)階段要進(jìn)行服務(wù)器端框架設(shè)計(jì)與業(yè)務(wù)代碼開(kāi)發(fā),客戶端框架設(shè)計(jì)與業(yè)務(wù)代碼的開(kāi)
13、發(fā),棋子以及棋盤類的設(shè)計(jì)開(kāi)發(fā),規(guī)則類的設(shè)計(jì)開(kāi)發(fā)等。</p><p><b> 2 需求分析 </b></p><p><b> 2.1系統(tǒng)需求</b></p><p> 滿足客戶端連接到服務(wù)器的基本要求。</p><p> 服務(wù)器滿足記錄客戶端游戲動(dòng)作的基本要求。</p>&l
14、t;p> 滿足服務(wù)器實(shí)時(shí)獲得客戶端游戲狀態(tài)的基本要求。</p><p><b> 2.2用戶需求</b></p><p> 2.2.1服務(wù)端需求</p><p> ?。?)可以有一個(gè)顯示服務(wù)器狀態(tài)的界面,用于記錄各個(gè)客戶端的連接狀態(tài)。服務(wù)器是用于連接各個(gè)客戶端的通信,如果獨(dú)立地創(chuàng)建一個(gè)直觀的服務(wù)器,將有力地顯示客戶端的每個(gè)狀態(tài),直觀
15、地向用戶反應(yīng)各類信息。</p><p> ?。?)可以支持多人同時(shí)在線。一個(gè)服務(wù)器能夠你能夠接受來(lái)自其他多個(gè)客戶端的請(qǐng)求,提供相應(yīng)的響應(yīng)服務(wù),是網(wǎng)絡(luò)對(duì)弈的基本要求。</p><p> ?。?)可以顯示在線用戶的信息。顯示在線用戶的信息,比如主機(jī)名,IP地址,以及連接斷的狀態(tài),有利于用戶隨時(shí)監(jiān)控客戶端的通信狀態(tài)。</p><p> ?。?)不允許玩家同名。不允許客戶端
16、同名即是不允許客戶端的端口號(hào)相同,如果相同,將會(huì)造成游戲登陸用戶的管理混亂。</p><p> ?。?)服務(wù)器界面節(jié)約大方。服務(wù)器是用于監(jiān)控客戶端的連接情況,沒(méi)用必要做得繁雜,用戶只需要直觀的狀態(tài)顯示,所以我們的服務(wù)器不需要設(shè)計(jì)太多按鈕,只需要有顯示服務(wù)器狀態(tài),關(guān)閉服務(wù)器,清空列表的按鈕,方便用戶操作。</p><p> 2.2.2客戶端需求 </p><p>
17、 能夠通過(guò)主機(jī)IP及端口號(hào)登陸到服務(wù)器。 </p><p> 可以顯示當(dāng)前所有用戶。游戲客戶端應(yīng)設(shè)計(jì)一個(gè)可以顯示當(dāng)前 所有在線用戶的列表,有助于用戶隨意選擇玩家挑戰(zhàn)。</p><p> 可以從在線用戶列表中選擇玩家進(jìn)行挑戰(zhàn)。</p><p> 可以創(chuàng)建以及接受挑戰(zhàn)。</p><p> 如果對(duì)方正在與其他玩家對(duì)弈,則應(yīng)給出相應(yīng)提示。&
18、lt;/p><p> 五子棋規(guī)則一定要嚴(yán)密。其中五子棋游戲的規(guī)則如下:</p><p><b> 棋盤,棋子:</b></p><p> 棋盤為十五路,正中一點(diǎn)為“天元”,周圍四點(diǎn)為小星。</p><p> 棋子分黑白兩色,黑子113枚,白子112枚,共225枚。</p><p><b&
19、gt; 比賽規(guī)則:</b></p><p> 黑先白后,從天元開(kāi)始落子。然后執(zhí)白棋的一方在黑棋周圍的交叉點(diǎn)上落子,白第二著棋應(yīng)布在自己河界的一側(cè)。此后,執(zhí)黑方在以天元為中心的25個(gè)交叉點(diǎn)的范圍內(nèi)布盤面的第三著棋。</p><p> 最先在橫向,豎向,斜向形成連續(xù)的相同色五個(gè)棋子的一方為勝。</p><p> 黑棋禁手判負(fù),白棋無(wú)禁手。黑棋禁手包括
20、“三三”,“四四”,“長(zhǎng)連”。黑方只能“四三”勝。所謂禁手,是指黑方一子落下同時(shí)形成兩個(gè)或兩個(gè)以上的活三,沖四及長(zhǎng)連禁手。長(zhǎng)連禁手是指黑方形成六個(gè)或六個(gè)以上的連續(xù)棋子。</p><p> 雙方均不能形成五連為和棋。</p><p> 對(duì)局中拔子,中途退場(chǎng)均判為負(fù)。</p><p> 五連與禁手同時(shí)形成,先五為勝。因黑方已形成五連,故禁手失效,黑方勝。</
21、p><p> 黑方禁手形成時(shí),白方應(yīng)立即指出禁手點(diǎn),黑方即負(fù)。若白方繼續(xù)應(yīng)子,則黑方禁手不成立。</p><p> 高段位職業(yè)比賽的特殊規(guī)定:“三手可交換”:黑下完第2手,執(zhí)白者可提出交換。即執(zhí)白方變?yōu)閳?zhí)黑方?!拔迨謨纱蚍ā保簣?zhí)黑下第五手時(shí),必須下兩手棋,執(zhí)白者從這兩手棋中任選一步。</p><p> 本文所論述的聯(lián)機(jī)五子棋系統(tǒng)就是依照這種方式進(jìn)行的。</p
22、><p> 2.2.3技術(shù)上可行性分析</p><p> 對(duì)需求分析階段的結(jié)果進(jìn)行總結(jié),對(duì)軟件的可行性分析如下:</p><p> 網(wǎng)絡(luò)對(duì)弈需要兩個(gè)客戶端進(jìn)行通信,而利用服務(wù)器的線程開(kāi)發(fā),進(jìn)行中間中介連接正好可以完成。</p><p> 五子棋的規(guī)則雖然嚴(yán)密,但是通過(guò)各種情況分析,然后將每個(gè)情況分析設(shè)計(jì)出來(lái)。</p><
23、;p> 本系統(tǒng)的設(shè)計(jì)運(yùn)行環(huán)境只用到MyEclipse的編程軟件,無(wú)需借用到其它的軟件,比較容易實(shí)現(xiàn)。</p><p> 2.3.系統(tǒng)運(yùn)行環(huán)境</p><p> 系統(tǒng)運(yùn)行環(huán)境:MyEclipse 6.6</p><p><b> 3 總體設(shè)計(jì)</b></p><p><b> 3.1系統(tǒng)結(jié)構(gòu)設(shè)計(jì)&
24、lt;/b></p><p> 該游戲主要分為服務(wù)器端與客戶端兩部分。</p><p> 服務(wù)器端的功能主要是建立與客戶端的連接,監(jiān)控客戶端的連接及斷開(kāi)的狀態(tài),接收客戶端發(fā)送的信息以及向客戶端發(fā)送信息。</p><p> 客戶端的功能主要是連接服務(wù)器端,創(chuàng)建游戲用戶,創(chuàng)建游戲,加入游戲,選擇玩家挑戰(zhàn),向服務(wù)器發(fā)送信息,接收服務(wù)器端發(fā)送來(lái)的信息。其具體的功
25、能模塊如圖所示:</p><p><b> 3.2服務(wù)器設(shè)計(jì)</b></p><p> 服務(wù)器的設(shè)計(jì)主要分為服務(wù)器主界面,服務(wù)器線程,服務(wù)器主機(jī)面板三個(gè)部分。</p><p> 服務(wù)器主界面的設(shè)計(jì)主要包括界面大小,界面背景,界面上的按鈕,比如清空列表,服務(wù)器狀態(tài),關(guān)閉服務(wù)器的設(shè)計(jì),以及啟動(dòng)對(duì)客戶端的監(jiān)聽(tīng),啟動(dòng)服務(wù)器線程。</p>
26、;<p> 服務(wù)器線程的設(shè)計(jì)主要包括接受多個(gè)客戶端的連接,接受客戶端信息,向客戶端發(fā)送信息。</p><p> 服務(wù)器主機(jī)面板的設(shè)計(jì)主要包括客戶端信息板的設(shè)計(jì),包括板的大小,背景顏色。其具體的功能模塊如圖所示:</p><p><b> 3.3客戶端設(shè)計(jì)</b></p><p> 客戶端的設(shè)計(jì)主要分為客戶端界面,客戶端線程
27、兩部分。</p><p> 客戶端界面的設(shè)計(jì)主要包括客戶端界面大小,背景顏色,主要按鈕:創(chuàng)建游戲,加入游戲,連接到服務(wù)器,放棄游戲,退出游戲的設(shè)計(jì)以及它們對(duì)應(yīng)事件的處理。</p><p> 客戶端線程的設(shè)計(jì)主要包括連接到服務(wù)器,向服務(wù)器發(fā)送信息,接受服務(wù)器信息的設(shè)計(jì)以及它們對(duì)應(yīng)的事件處理,比如收到服務(wù)器發(fā)送來(lái)的游戲勝利,信息錯(cuò)誤,信息有效等的處理。其具體功能模塊如圖所示:</p&
28、gt;<p><b> 3.4棋類設(shè)計(jì)</b></p><p> 五子棋類的設(shè)計(jì)主要分為棋盤,棋子,五子棋動(dòng)作線程,規(guī)則四部分。</p><p> 棋盤的設(shè)計(jì)主要包括畫(huà)棋子,捕獲下棋事件,畫(huà)網(wǎng)絡(luò)棋盤。棋子的設(shè)計(jì)包括黑棋以及白旗的設(shè)計(jì),其中有大小,顏色,所屬棋盤的設(shè)計(jì)。</p><p> 五子棋動(dòng)作線程的設(shè)計(jì)包括處理捕獲下
29、棋信息,發(fā)送當(dāng)前下棋信息,這一部分的設(shè)計(jì)是五子棋類設(shè)計(jì)的重點(diǎn)。</p><p> 規(guī)則的設(shè)包括取得指定棋子的位置,判斷當(dāng)前棋子是否取得勝利,當(dāng)前棋子各個(gè)方向的判斷,當(dāng)前所要下的棋子是否越界。</p><p><b> 4 詳細(xì)設(shè)計(jì)</b></p><p><b> 4.1 服務(wù)器</b></p><
30、;p> 4.1.1服務(wù)器主類的設(shè)計(jì)開(kāi)發(fā)</p><p> 服務(wù)器主類即服務(wù)器端的運(yùn)行類,用戶通過(guò)運(yùn)行該類進(jìn)入服務(wù)器的主界面。其中包括創(chuàng)建服務(wù)器端用到的控件以及聲明用到的對(duì)象引用,完成對(duì)控件的初始化:設(shè)置窗體的標(biāo)題,圖標(biāo),大小以及可見(jiàn)性,將各個(gè)控件添加到各面板的相應(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ù)器啟動(dòng)于:"</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)聽(tīng)客戶端套接口的信息</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)建并運(yùn)行服務(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è)計(jì)開(kāi)發(fā)</p><p> 服務(wù)器線程是服務(wù)器啟動(dòng)后創(chuàng)建并啟動(dòng)的第一個(gè)線程,該線程主要用于接收客戶端的連接,并未每個(gè)連接分配一個(gè)服務(wù)器代理線程。服務(wù)器代理線程主要用于接收客戶端傳來(lái)的消息,并將該消息轉(zhuǎn)發(fā)給另一個(gè)客戶端。服務(wù)器為所有客戶端都分配了一個(gè)該類線程實(shí)例,單獨(dú)為特定客戶端進(jìn)行服務(wù)。同時(shí)每一個(gè)服務(wù)器代理線程都有能唯一標(biāo)識(shí)的名稱。</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; // 保存客戶端端口與輸出流對(duì)應(yīng)的Hash</p><p> Hashtable clientNameHash; // 保存客戶端套接口和客戶名對(duì)應(yīng)的Hash</p><p> Hashtable chessPeerHash; // 保存游戲創(chuàng)建者和游戲加入者對(duì)應(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> { // 收到的信息為加入游戲時(shí)</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> { // 增加游戲加入者的套接口與名稱的對(duì)應(yīng)</p><p> clientNameHash.put(clientSocket,</p><p> ("[inchess]" + gamePaticipantName)
78、);</p><p><b> }</b></p><p> synchronized (chessPeerHash)</p><p> { // 增加或修改游戲創(chuàng)建者與游戲加入者的名稱的對(duì)應(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> { // 收到的信息為游戲中時(shí)</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> { // 收到的信息為放棄游戲時(shí)</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> { // 收到的信息為其它信息時(shí)</p><p> int lastLocation = msgReceived.indexOf("
94、", 0);</p><p> if (lastLocation == -1)</p><p><b> {</b></p><p> Feedback("無(wú)效命令");</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ā)送公開(kāi)信息</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ā)送信息的用戶時(shí)</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ī)時(shí)執(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("注意:命令必須對(duì)所有用戶發(fā)送");</p><p><b> }</b></p><p> public void closeClient()</p><p><b> {</b></p><p> ser
122、verMsgPanel.msgTextArea.append("用戶斷開(kāi)連接:" + 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. 本站所有資源如無(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 網(wǎng)絡(luò)對(duì)弈課程設(shè)計(jì)說(shuō)明書(shū)
- 網(wǎng)絡(luò)課程設(shè)計(jì)說(shuō)明書(shū)
- 網(wǎng)絡(luò)工程課程設(shè)計(jì)說(shuō)明書(shū)
- 課程設(shè)計(jì)說(shuō)明書(shū)
- 課程設(shè)計(jì)說(shuō)明書(shū)
- 網(wǎng)絡(luò)管理技術(shù)課程設(shè)計(jì)說(shuō)明書(shū)
- 前門課程設(shè)計(jì)說(shuō)明書(shū)
- javaweb課程設(shè)計(jì)說(shuō)明書(shū)
- 后蓋課程設(shè)計(jì)說(shuō)明書(shū)
- 鍋爐課程設(shè)計(jì)說(shuō)明書(shū)
- 空調(diào)課程設(shè)計(jì)說(shuō)明書(shū)
- 蝸輪課程設(shè)計(jì)說(shuō)明書(shū)
- 采礦課程設(shè)計(jì)說(shuō)明書(shū)
- 機(jī)床課程設(shè)計(jì)說(shuō)明書(shū)
- caxa課程設(shè)計(jì)說(shuō)明書(shū)
- 化工課程設(shè)計(jì)說(shuō)明書(shū)
- vb課程設(shè)計(jì)說(shuō)明書(shū)
- 課程設(shè)計(jì)說(shuō)明書(shū).doc
- 課程設(shè)計(jì)說(shuō)明書(shū).doc
- 課程設(shè)計(jì)說(shuō)明書(shū).doc
評(píng)論
0/150
提交評(píng)論