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