この記事では、参照用のJava実装Goziqiオンラインバージョンの特定のコードを共有しています。特定のコンテンツは次のとおりです
要件分析:
オンラインgojiの場合、通常のゴジに基づいて次の機能を追加する必要があります。
1。サーバー側とクライアントを持っています。ユーザーがクライアントを介してサーバーにログインした後、他のログインユーザーとゲームをプレイできます。
2.サーバーは、複数のユーザーグループをサポートして同時にゲームをプレイします
3.ユーザーはサーバーで新しいゲームを作成したり、作成したゲームに参加したりできます
4.ユーザーはチェスをしている間、チャットしてコミュニケーションをとることができます
上記から、実装する必要がある関数を知ることができます。
serverサーバーとクライアントの機能を提供します
サーバーはクライアントのログインステータスを監視し、複数のクライアントがログインできるようにします
clientsユーザーはクライアントを介してサーバーにログインできます。その後、現在オンラインでサーバーの他のユーザーを見ることができます。
serverサーバーにログインした後、ユーザーは新しいGoziゲームを作成したり、作成したGoziゲームに参加したりできます。
・ユーザーはクライアントを通して普通のgojiのような他のユーザーとゲームをプレイできます
関数によれば、ネットワークGochiは4つのモジュールに分割されます。つまり、ユーザーパネルモジュール、ボードパネルモジュール、Gochiサーバーモジュール、およびGochiクライアントモジュール
ユーザーパネルモジュールのコンパイルを開始しましょう。
1.ユーザーリストパネルを開発します
java.awt。*; /*** 2016/11/21に管理者によって作成されました。 *///初期状態では、「ユーザーなし」という名前の10の情報がリストに追加され、サーバーが同時にオンラインで最大10人のユーザーをサポートしていることを示します。 public userlistpad(){setlayout(new borderlayout()); for(int i = 0; i <10; i ++){userlist.add(i+"。"+"no user"); } add(userlist、borderlayout.center); }} 2。ユーザーチャットパネルを開発します
javax.swing。*; java.awt。*; /*** 2016/11/21に管理者によって作成されました。 *///チャットパネルは、垂直スクロールバーを備えたTextareaビューコントロールです。 //「borderlayout」レイアウト形式を使用して、Textareaがパネルに追加されます。 Public Class UserChatPad拡張jpanel {public jtextarea chattextarea = new jtextarea( "コマンドエリア"、18,20); public userchatpad(){setlayout(new borderlayout()); chattextarea.setautoscrolls(true); chattextarea.setlinewrap(true); add(chattextarea、borderlayout.center); }} 3.ユーザー入力パネルを開発します
javax.swing。*; java.awt。*; /*** 2016/11/21に管理者によって作成されました。 *//パネルには2つのビューコントロールが含まれていますpublic jcombobox userchoice = new jcombobox(); public userininputpad(){setlayout(new flowlayout(flowlayout.left)); for(int i = 0; i <50; i ++){userchoice.additem(i+"。"+"no user"); } userchoice.setsize(60,24); add(userchoice); add(contentinputted); }} 4.ユーザー操作パネルを開発します
javax.swing。*; java.awt。*; /*** 2016/11/21に管理者によって作成されました。 */ public class usercontrolpadはjpanelを拡張します{public jlabel iplabel = new Jlabel( "ip"、jlabel.left); public jtextfield ipinputted = new jtextfield( "localhost"、10); public jbutton connectbutton = new jbutton( "connect to server"); public jbutton createbutton = new JButton( "Create Game"); public jbutton joinbutton = new jbutton( "Join Game"); public jbutton cancelbutton = new jbutton( "Give Up Game"); public jbutton exitbutton = new jbutton( "Exit Game"); public usercontrolpad(){setlayout(new flowlayout(flowlayout.left)); setbackground(color.light_gray); add(iplabel); add(ipinputted); add(connectbutton); add(createbutton); add(joinbutton); add(cancelbutton); add(exitbutton); }}以下のボードパネルモジュールの開発を開始します
1.黒いチェスを開発します
java.awt。*; /*** 2016/11/21に管理者によって作成されました。 */ public class firpointblackはキャンバスを拡張します{firpad padbelonged; //ブラックチェスが公共のFirpointBlackに属するボード(FIRPAD PADBELONGED){SetSize(20、20); //チェスのピースサイズを設定します。 } public void paint(グラフィックスG){//チェスピースg.setcolor(color.black); G.Filloval(0、0、14、14); }} 2。白いチェスのカテゴリを開発します
java.awt。*; /*** 2016/11/21に管理者によって作成されました。 */ public class firpointhhiteはキャンバスを拡張します{firpad padbelonged; //白いチェスが公共のファイポイントホワイトに属するボード(Firpad Padbelonged){SetSize(20、20); this.padbelonged = padbelonged; } public void paint(グラフィックスG){//チェスピースを描くg.setcolor(color.white); G.Filloval(0、0、14、14); }} 3.チェスボードパネルを開発します
java.awt。*; java.awt.event。*; java.io.*をインポートします。 java.net。*; javax.swing.jtextfieldをインポートします。 /*** 2016/11/21に管理者によって作成されました。 */ public class firpad拡張パネルは、mouseListener、actionlistener {//マウスをパブリックブールイスマウスエンブル= falseを使用できます。 // public boolean iswinned = falseを獲得するかどうか。 // Chess Public Boolean Isgaming = falseをプレイするかどうか。 //チェスピースのX -Axis座標ビットpublic int chessx_pos = -1; //チェスピースのy -axis座標ビットpublic public int chessy_pos = -1; //チェスピースの色public int chesscolor = 1; // Black X-Axis Coordinate Bit Array public int chessblack_xpos [] = new int [200]; // Black Y-Axis Coordinate Bit Array public int chessblack_ypos [] = new int [200]; //ホワイトY軸調整ビットアレイpublic int chesswhite_xpos [] = new int [200]; //ホワイトチェスy-xis座標桁アレイpublic int chesswhite_ypos [] = new int [200]; //ブラックチェスの数Public Int ChessBlackCount = 0; //ホワイトチェスの数Public Int ChessWhiteCount = 0; //ブラックチェスの数が公開されますint chessblackvictimes = 0; //白いチェスの数が公開されます。 //白いチェスの数が公開されます。 //スリーブインターフェイスパブリックソケットチェスソケット。 public datainputStream inputData; public dataoutputStream outputData; public string chesselfname = null; public string chesspeername = null; public string host = null; public int port = 4331; public Textfield statustext = new Textfield( "サーバーに接続してください!"); public firthread firthread = new firthread(this); public firpad(){setSize(440、440); SetLayout(null); setbackground(color.light_gray); addmouseListener(this); add(statustext); statustext.setbounds(new Rectangle(40、5、360、24)); statustext.setedable(false); } //ホストに接続して、パブリックブールンConnectServer(String ServerIP、Int ServerPort)スロー例外{//ホストポートChesssocket = new Socket(serverIp、serverport)を取得します; //入力ストリームinputData = new DatainputStream(chesssocket.getInputStream())を取得します。 // get outputData = new DataOutputStream(chesssocket.getOutputStream()); firthread.start(); trueを返します。 } catch(ioException ex){statustext.settext( "接続失敗! /n"); } falseを返します。 } //公開void setvicstatus(int vicchesscolor)を獲得するときにボードステータスを設定します{//ボードをクリアするthis.removeall(); //ブラックチェスの位置をゼロに設定します(int i = 0; i <= chessblackcount; i ++){chessblack_xpos [i] = 0; chessblack_ypos [i] = 0; } //ホワイトチェスの位置をゼロに設定します(int i = 0; i <= chesswhitecount; i ++){chesswhite_xpos [i] = 0; chesswhite_ypos [i] = 0; } //ボード上のブラックチェスの数をクリアChessblackCount = 0; //ボード上のホワイトチェスの数をクリアChesswhitecount = 0; add(statustext); statustext.setbounds(40、5、360、24); if(vicchesscolor == 1){// Black ChessがChessBlackVictimes ++を獲得します。 statustext.settext( "black、black:white" + chessblackvictimes + ":" + chesswhitevictimes + "、ゲーム再起動、ホワイトを待つ..."); } else if(vicchesscolor == -1){//ホワイトチェスがChesswhitevictimes ++を獲得します。 statustext.settext( "black:white" + chessblackvictimes + ":" + chesswhitevictimes + "、ゲーム再起動、blackを待つ..."); }} //指定されたチェスピースの位置を取得しますpublic void setlocation(int xpos、int ypos、int chesscolor){if(chesscolor == 1){//チェスピースが黒の場合、chessblackcount] = xpos * 20; chessblack_ypos [chessblackcount] = ypos * 20; ChessBlackCount ++; } else if(chesscolor == -1){//チェスピースが白い場合、chesswhite_xpos [chesswhitecount] = xpos * 20; Chesswhitecount ++; }} //現在の状態が勝利状態であるかどうかを決定します。 //接続されたChessLinkedCompareの数= 1; //ピースを続けたいかどうかを比較するために使用されますint chesstocompareindex = 0; //比較するピースのインデックス位置int closegrid = 1; //隣接するグリッドの位置if(chesscolor == 1){// chesslinkedcount = 1; //チェスピース自体がカウントされている場合、接続の初期数は1 //以下のループステートメントの各ペアはグループです。なぜなら、次の期間の位置は両端ではなく中央にある(CloseGrid = 1; CloseGrid <= 4; CloseGrid ++){// 4つの隣接するグリッドを通過する(Chesstocompareindex = chesstocompareindex; chesstocompareindex; chesstocompareindex ++){//ボード上のすべての黒いチェスのピースを通過するif((xpos+closegrid) * 20 == chesstocompareindex])&&((ypos * 20)== chessblack_ypos [chesstocompareindex]) ChessLinkedCount + 1; //接続の数に1を追加します(chesslinkedcount == 5){// 5つのピースが接続されている場合、勝利は真実です。 }}}} if(chesslinkedcount ==(chesslinkedcompare+1)){chesslinkedcompare ++; } else {//中央に黒ではないチェスの部分がある場合、この枝に入り、この時点で再び破壊する必要はありません。 }} for(closegrid = 1; closegrid <= 4; closegrid ++){for(chesstocompareindex = 0; chesstocompareindex <= chesstocompareindex ++){if(((xpos -closegrid) * 20 == chesstocompareindex) chessblack_ypos [chesstocompareindex]))){//現在再生されているChesslinkedCount ++の左側にある4つのチェスの部分を決定します。 if(chesslinkedcount == 5){return true; }}}} if(chesslinkedcount ==(chesslinkedcompare+1)){chesslinkedcompare ++; } else {break; }} // forループの新しいセットを入力すると、接続の数などをリセットします。ChessLinkedCount= 1; ChessLinkedCompare = 1; for(closegrid = 1; closegrid <= 4; closegrid ++){for(chesstocompareindex = 0; chesstocompareindex <= chesstocompareindex ++){if((xpos * 20 == chessblack_xpos [chesstocompareindex]) chessblack_ypos [chesstocompareindex]))){//現在再生されているChesslinkedCount ++の上位4個かどうかを判断します。 if(chesslinkedcount == 5){return true; }}} if(chesslinkedcount ==(chesslinkedcompare+1)){chesslinkedcompare ++; } else {break; }} for(closegrid = 1; closegrid <= 4; closegrid ++){for(chesstocompareindex = 0; chesstocompareindex <= chesstocompareindex ++){if((xpos 20 == chesstocompareindex [chesstocompareindex]) * 20 == chessblack_ypos [chesstocompareindex]))){//現在再生されたchesslinkedcount ++の下の4つのピースがかどうかを判断します。 if(chesslinkedcount == 5){return true; }}} if(chesslinkedcount ==(chesslinkedcompare+1)){chesslinkedcompare ++; } else {break; }} chesslinkedcount = 1; ChessLinkedCompare = 1; for(closegrid = 1; closegrid <= 4; closegrid ++){for(chesstocompareindex = 0; chesstocompareindex <= chesstocompareindex ++){if(((xpos -closegrid) * 20 == chesstocompareindex) * 20 =+++ Chessblack_ypos [ChesstocompareIndex])))) }} for(closegrid = 1; closegrid <= 4; closegrid ++){for(chesstocompareindex = 0; chesstocompareindex <= chesstocompareindex ++){if(((xpos+closegrid) * 20 == chessblack_xpos [yessocompareindex)] Chessblack_ypos [ChesstocompareIndex])){//現在のチェスの右側の4つのチェスピースは、chesslinkedcount == 5){chesslinkedcomedcomedcomedcomedcomedcomedcomed> {break;} chesslinkedcount = 1; chessblack_xpos [chesstocompareindex])&&(ypos+closegrid) * 20 == chesstocompareindex])){//現在のチェスピースの4つのチェスピースが、chesslinkedcount ++の場合( (ChessLinkedCount ==(ChessLinkedCompare+1)){ChessLinkedCompare ++; ((xpos -closegrid) * 20 == chessblack_xpos [chesstocompareindex])&&(ypos -closegrid) * 20 == chesstocompareindex]){// true; (chesstocompareindex = 0; chesstocompareindex <= chesstocompareindex ++){if((xpos+closegrid) * 20 == chesstocompareindex])現在、ChessLinkedCount == 5)を再生します。 0; ChesstocompareIndex <= chesstocompareindex ++){(xpos -closegrid) * 20 == ChesslinkedCount ==}}}} closegrid ++){for(chesstocompareindex = 0; chesstocompareindex <= chesstocompareindex ++){if((xpos * 20 == chesstocompareindex])&&(ypos+closegrid)現在プレイしている++の上位4個。 (chesstocompareindex = 0; chesstocompareindex <= chesstocompareindex ++){if(xpos * 20 == chesswhite_xpos [chesstocompareindex]) ChesslinkedCount ==}}}} closegrid ++){for(chesstocompareindex = 0; chesstocompareindex <= chesstocompareindex ++){if((xpos -closegrid) * 20 == chesswhite_xpos [chesstocompareindex]) {現在、現在のチェスの左方向にある4つのピースが++です<= 4。 chesswhite_ypos [chesstocompareindex])){//現在のチェスの右側の4つのチェスのピースが、chesslinkedcount == 5) {break;} chesslinkedcount = 1; chesswhite_xpos [chesstocompareindex])&&(ypos+closegrid) * 20 == chesstocompareindex])){// (ChessLinkedCount ==(ChessLinkedCompare+1)){ChessLinkedCompare ++; ((xpos-closegrid) * 20 == chesswhite_xpos [chesstocompareindex]) }} if(chesslinkedcompare + 1){chesslinkedcompare ++; } drawline(400、400、400); G.fillval(337、337、6、6); firplack black(これ)firphite = new firpointhwhite(Chesscolor ==); (iswinned == false){//非win firthread.sendmessage( " + chesspeername +" + xpos + "" + chesscolor)境界Statustext.settext( "black(" + chessblackcount + "step) + xpos +"、それはホワイトスクエアのターンです。 Chesscolor); setlocation(xpos、yscolor); firpwhite.setbounds(xpos * 20-7、16、16); 「 + ypos + " + chesscolor); ypo、int chesscolor){firpopentblack = new firpwhite = new firpointhwhite(this); addd(firpblack); Chesspeername + chesscolor); ypos、iswinned == addd(firpwhite)(xpos * 20-7、16、16) { /" + chesspeername" /chesscolor(firpwhite.setbounds); e){e.getModifiers()== button1_mask){int)e.getx(); / 20> 19 || //チェスの位置が間違っている場合、アクションは実行されません} e){} public void mouseclicked(mousevent e){} public void actionperformed(ActionEvent e){}} 4.チェスボードスレッドを開発します
Java.util.StringTokenizerをインポートします。 java.io.ioexceptionをインポートします。 /*** 2016/11/21に管理者によって作成されました。 */ public class firthreadはスレッドを拡張します{firpad curpad; //現在のスレッドのチェスボードパブリックFIRTHREAD(FIRPAD CURRPAD){this.currpad = currpad; } //取得した情報を処理しますpublic public void dealwithmsg(string msgreceived){if(msgreceived.startswith( "/chess")){//受け取った情報はチェスstringtokenizer usermsgtoken = new stringtokenizer(msgreceived、 ""); //チェスピース情報と0インデックスの配列は次のとおりです。 1インデックスビット:Y座標。 2インデックスビット:chessinfo = {"-1"、 "-1"、 "0"}; int i = 0; //フラグビット文字列chessinfotoken; while(usermsgtoken.hasmoretokens()){chessinfotoken =(string)usermsgtoken.nexttoken( ""); if(i> = 1 && i <= 3){chessinfo [i -1] = chessinfotoken; } i ++; } currpad.paintnetfirpoint(integer.parseint(chessinfo [0])、integer .parseint(chessinfo [1])、integer.parseint(chessinfo [2])); } else if(msgreceived.startswith( "/yourname")){//受信したメッセージはCurrpad.chessselfname = msgreceived.substring(10); } else if(msgreceived.equals( "/error")){//受信したエラーメッセージはcurrpad.statustext.settext( "ユーザーが存在しない、再生してください!"); }} //メッセージを送信しますpublic void sendmessage(string sndmessage){try {currpad.outputdata.writeutf(sndmessage); } catch(Exception ea){ea.printstacktrace();; }} public void run(){string msgreceived = ""; try {while(true){//情報入力を待つmsgreceived = currpad.inputdata.readutf(); dealwithmsg(msgreceived); }} catch(ioexception es){}}}以下のサーバーモジュールの開発を開始します
1.サーバー情報パネルを開発します
java.awt.borderlayoutをインポートします。 java.awt.colorをインポートします。 java.awt.flowlayoutをインポートします。 java.awt.labelをインポートします。 java.awt.panelをインポートします。 java.awt.textareaをインポートします。 javax.swing.jlabelをインポートします。 /*** 2016/11/21に管理者によって作成されました。 */ public class servermsgpanel拡張パネル{public textarea msgtextarea = new textarea( ""、22、50、textarea.scrollbars_vertical_only); public jlabel staturelabel = new Jlabel( "Current Connections:"、Label.Left); publicパネルmsgpanel = new Panel(); publicパネルstatuspanel = new Panel(); public servermsgpanel(){setSize(350、300); setbackground(color.light_gray); setLayout(new borderlayout()); msgpanel.setLayout(new FlowLayout()); msgpanel.setsize(210、210); statuspanel.setlayout(new borderlayout()); statuspanel.setsize(210、50); msgpanel.add(msgtextarea); statuspanel.add(statuslabel、borderlayout.west); add(msgpanel、borderlayout.center); add(statuspanel、borderlayout.north); }} 2。サーバープロセスを開発します
java.io.datainputStreamをインポートします。 java.io.dataoutputStreamをインポートします。 java.io.ioexceptionをインポートします。 java.net.socketをインポートします。 java.util.numerationをインポートします。 java.util.hashtableをインポートします。 Java.util.StringTokenizerをインポートします。 /*** 2016/11/21に管理者によって作成されました。 */ public class firserverthread extends thread {socket clientsocket; //クライアントソケット情報Hashtable ClientDatahashを保存します。 //クライアントポートと出力ストリームに対応するハッシュハッシュテーブルClientNamehashを保存します。 //クライアントソケットとクライアント名に対応するハッシュハッシュテーブルチェスピアハッシュを保存します。 //ゲームクリエーターとゲームジョイナーに対応するハッシュサーバーのservermsgpanelを保存します。 boolean isclientclosed = false; public firserverthread(Socket ClientSocket、HashTable ClientDatahash、HashTable ClientNameHash、HashTable ChessPeerHash、ServerMSGPanel Server){this.clientsocket = clientSocket; this.clientDatahash = clientDatahash; this.clientNameHash = clientNameHash; this.chesspeerhash = chesspeerhash; this.servermsgpanel = server; } public void dealwithmsg(string msgreceived){string clientName;文字列ピーン名; if(msgreceived.startswith( "/")){if(msgreceived.equals( "/list")){//受信した情報は、ユーザーリストフィードバック(getuserlist())を更新するためです。 } else if(msgreceived.startswith( "/creatgame [inchess]" ")){//受信したメッセージは、ゲーム文字列gamecreatertername = msgreceived.substring(20)を作成することです。 //サーバー名をsynchronized(clientnamehash){//ユーザーポートをユーザーリストにclientnamehash.put(clientsocket、msgreceived.substring(11))に取得します。 } synchronized(chesspeerhash){//ホストを待機状態に設定しますchesspeerhash.put(gamecreatertername、 "wait"); }フィードバック( "/yourname" + clientnamehash.get(clientsocket)); sendgamepeermsg(gamecreatername、 "/ok"); sendpublicmsg(getUserList()); } else if(msgreceived.startswith( "/joingame")){//受信したメッセージは、ゲームstringtokenizer usertokens = new StringTokenizer(msgreceived、 "")に参加するときです。文字列usertoken;文字列gamecreatorname; String GamePaticIpantName; string [] playnames = {"0"、 "0"}; int nameindex = 0; while(usertokens.hasmoretokens()){usertoken =(string)usertokens.nexttoken( ""); if(nameindex> = 1 && nameindex <= 2){playernames [nameindex -1] = usertoken; //プレイヤーの寿命を取得} nameindex ++; } gamecreatorname = playernames [0]; GamePaticIpantName = playnames [1]; if(chesspeerhash.containskey(gamecreatorname)&& chesspeerhash.get(gamecreatorname).equals( "wait")){//ゲームが作成された(clientnamehash){//対応するClientNamehash.put(clionepaticipantnamesocket); } synchronized(chesspeerhash){//対応するchesspeerhash.put(gamecreatorname、gamepaticipantname); } sendpublicmsg(getUserList()); //ゲームジョイナーにメッセージを送信しますSendGamePeermsg(GamePaticIpantName、( "/Peer" + "[inchess]" + gamecreatorname)); //ゲームをゲームクリエイターSendGamePeermsg(gamecreatorname、( "/peer" + "[inchess]" + gamepaticipantname))に送信します。 } else {//ゲームが作成されていない場合、ゲームはsendgamepeermsg(gamepaticipantname、 "/requeject")の追加を拒否されます。 try {closeclient(); } catch(Exception ez){ez.printstacktrace(); }}} else if(msgreceived.startswith( "/[inchess]" ")){//受信したメッセージはint firstlocation = 0、lastlocation; lastlocation = msgreceived.indexof( ""、0); PeerName = MSGRECEIVED.SUBSTRING((FirstLocation + 1)、LastLocation); msgreceived = msgreceived.substring((lastlocation + 1)); if(sendgamepeermsg(peername、msgreceived)){feedback( "/error"); }} else if(msgreceived.startswith( "/giveup")){//受信したメッセージは、ゲーム文字列chessclientname = msgreceived.substring(8)を放棄するときです。 if(chesspeerhash.containskey(chessclientname)&&!((string)chesspeerhash.get(chessclientname)).equals( "wait")){//勝者はゲームジョイナーです。同期(ChesspeerHash){//ユーザーを削除してくださいChessPeerHash.Remove(ChessClientName); }} if(chesspeerhash.containsvalue(chessclientname)){//勝者はゲームクリエーターであり、勝利メッセージsendgamepeermsg((string)gethashkey(chesspeerhash、chessclientname)、 "/youwin");同期(ChesspeerHash){//ユーザーを削除するゲームを終了しますChesspeerHash.Remove((string)GethashKey(ChesspeerHash、ChessClientName)); }}} else {//受信した情報が他の情報である場合int lastlocation = msgreceived.indexof( ""、0); if(lastlocation == -1){feedback( "invalid command");戻る; }}} else {msgreceived = clientnamehash.get(clientsocket) + ">" + msgreceived; servermsgpanel.msgtextarea.append(msgreceived + "/n"); sendpublicmsg(msgreceived); servermsgpanel.msgtextarea.setCaretPosition(servermsgpanel.msgtextarea.getText().Length()); }} // public public void sendpublicmsg(string publicmsg){synchronized(clientDatahash){for(enumeration enu = clientDatahash.Elements(); enu .hasMoreElements(); try {outputdata.writeutf(publicmsg); } catch(ioexception es){es.printstacktrace(); }}}}}} //指定されたゲームのパブリックブーリアンsendgamepeermsg(String gamepeertarget、string gamepeermsg)のユーザーに情報を送信します(列挙enu = clientdatahash.keys(); enu.hasmoreelements(){// raverse = raverse = raverse interface in socket in socke in sucked users in scopte enu.nextelement(); if(gamepeertarget.equals((string)clientnamehash.get(userclient))&&!gamepeertarget.equals((string)clientnamehash .get .get .get .get .get(clientsocket)){// synchronized(clientDatahash){//出力ストリームデータ削除を作成するPeeroutahash =(useTputtream)(usutputputStream)クライアントDatahash。 try {//情報を送信peeroutdata.writeutf(gamepeermsg); } catch(ioexception es){es.printstacktrace(); } } return false; }} trueを返します。 } // Send feedback information to the person connected to the host public void Feedback(String feedBackMsg) { synchronized (clientDataHash) { DataOutputStream outputData = (DataOutputStream) clientDataHash .get(clientSocket); try { outputData.writeUTF(feedBackMsg); } catch (Exception eb) { eb.printStackTrace(); } } } // Get the user list public String getUserList() { String userList = "/userlist"; for (Enumeration enu = clientNameHash.elements(); enu.hasMoreElements();) { userList = userList + " " + (String) enu.nextElement(); } return userList; } // Get the corresponding key from the Hashtable according to the value value public Object getHashKey(Hashtable targetHash, Object hashValue) { Object hashKey; for (Enumeration enu = targetHash.keys(); enu.hasMoreElements();) { hashKey = (Object) enu.nextElement(); if (hashValue.equals((Object) targetHash.get(hashKey))) return hashKey; } return null; } // Method executed when just connected to the host public void sendInitMsg() { sendPublicMsg(getUserList()); Feedback("/yourname " + (String) clientNameHash.get(clientSocket)); Feedback("Java Goziches client"); Feedback("/list --update user list"); Feedback("/<username> <talk> --private chat"); Feedback("Note: the command must be sent to all users"); } public void closeClient() { serverMsgPanel.msgTextArea.append("User disconnected:" + clientSocket + "/n"); synchronized (chessPeerHash) { //If it is a game client host if (chessPeerHash.containsKey(clientNameHash.get(clientSocket))) { chessPeerHash.remove((String) clientNameHash.get(clientSocket)); } if (chessPeerHash.containsValue(clientNameHash.get(clientSocket))) { chessPeerHash.put((String) getHashKey(chessPeerHash, (String) clientNameHash.get(clientSocket)), "tobeclosed"); } } synchronized (clientDataHash) { // Delete customer data clientDataHash.remove(clientSocket); } synchronized (clientNameHash) { // Delete customer data clientDataHash.remove(clientSocket); } synchronized (clientNameHash) { // Delete customer data clientNameHash.remove(clientSocket); } sendPublicMsg(getUserList()); serverMsgPanel.statusLabel.setText("Current connections:" + clientDataHash.size()); try { clientSocket.close(); } catch (IOException exx) { exx.printStackTrace(); } isClientClosed = true; } public void run() { DataInputStream inputData; synchronized (clientDataHash) { serverMsgPanel.statusLabel.setText("Current connections:" + clientDataHash.size()); } try { // Wait for information to connect to the host inputData = new DataInputStream(clientSocket.getInputStream()); sendInitMsg(); while (true) { String message = inputData.readUTF(); dealWithMsg(message); } } catch (IOException esx){} finally { if (!isClientClosed) { closeClient(); } } } } } } 3.开发服务器端
java.io.*をインポートします。 import java.net.*; import java.awt.*; import java.util.*; import java.awt.event.*; import javax.swing.JButton; /** * Created by Administrator on 2016/11/21. */ public class FIRServer extends Frame implements ActionListener{ JButton clearMsgButton = new JButton("Clear List"); JButton serverStatusButton = new JButton("Server Status"); JButton closeServerButton = new JButton("Shunt down the server"); Panel buttonPanel = new Panel(); ServerMsgPanel serverMsgPanel = new ServerMsgPanel(); ServerSocket serverSocket; Hashtable clientDataHash = new Hashtable(50); //Bind client socket and output stream Hashtable clientNameHash = new Hashtable(50); //Bind client socket and client name Hashtable chessPeerHash = new Hashtable(50); //Bind the game creator and game joiner public FIRServer() { super("Java Goji Server"); setBackground(Color.LIGHT_GRAY); buttonPanel.setLayout(new FlowLayout()); clearMsgButton.setSize(60, 25); buttonPanel.add(clearMsgButton); clearMsgButton.addActionListener(this); serverStatusButton.setSize(75, 25); buttonPanel.add(serverStatusButton); serverStatusButton.addActionListener(this); closeServerButton.setSize(75, 25); buttonPanel.add(closeServerButton); closeServerButton.addActionListener(this); add(serverMsgPanel, BorderLayout.CENTER); add(buttonPanel, BorderLayout.SOUTH); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } });パック(); setVisible(true); setSize(400, 300); setResizable(false); validate(); try { createServer(4331, serverMsgPanel); } catch (Exception e) { e.printStackTrace(); } } // Create server with specified ports and panels public void createServer(int port, ServerMsgPanel serverMsgPanel) throws IOException { Socket clientSocket; // Client socket long clientAccessNumber = 1; // The number of clients connected to the host this.serverMsgPanel = serverMsgPanel; // Set the current host try { serverSocket = new ServerSocket(port); serverMsgPanel.msgTextArea.setText("Server started at:" + InetAddress.getLocalHost() + ":" //djr + serverSocket.getLocalPort() + "/n"); while (true) { // Listen to the information of the client socket clientSocket = serverSocket.accept(); serverMsgPanel.msgTextArea.append("Connected user:" + clientSocket + "/n"); // Create client output stream DataOutputStream outputData = new DataOutputStream(clientSocket .getOutputStream()); // Bind client socket and output stream clientDataHash.put(clientSocket, outputData); // Bind client socket and client name clientNameHash .put(clientSocket, ("New Player" + clientAccessNumber++)); // Create and run the server-side thread FIRServerThread thread = new FIRServerThread(clientSocket, clientDataHash, clientNameHash, chessPeerHash, serverMsgPanel); thread.start(); } } catch (IOException ex) { ex.printStackTrace(); } } public void actionPerformed(ActionEvent e) { if (e.getSource() == clearMsgButton) { // Clear server information serverMsgPanel.msgTextArea.setText(""); } if (e.getSource() == serverStatusButton) { // Show server information try { serverMsgPanel.msgTextArea.append("Server Information:" + InetAddress.getLocalHost() + ":" + serverSocket.getLocalPort() + "/n"); } catch (Exception ee) { ee.printStackTrace(); } } if (e.getSource() == closeServerButton) { // Close the server System.exit(0); } } public static void main(String args[]) { FIRServer firServer = new FIRServer(); }}下面开始编写客户端模块
1.开发客户端
import java.awt.*; import java.awt.event.*; java.io.*をインポートします。 import java.net.*; javax.swing.jframeをインポートします。 import djr.chess.gui.UserChatPad; import djr.chess.gui.UserControlPad; import djr.chess.gui.UserInputPad; import djr.chess.gui.UserListPad; import djr.chess.pad.FIRPad; /** * Created by Administrator on 2016/11/21. */ public class FIRClient extends Frame implements ActionListener,KeyListener { // Client socket Socket clientSocket; // Data input stream DataInputStream inputStream; // Data output stream DataOutputStream outputStream; // Username String chessClientName = null; // Host address String host = null; // Host port int port = 4331; // Whether you are chatting boolean isOnChat = false; // Whether you are playing chess boolean isOnChess = false; // Is the game in progress boolean isGameConnected = false; // Whether it is the game creator boolean isCreator = false; // Whether it is the game entrant boolean isParticipant = false; // User List area UserListPad userListPad = new UserListPad(); // User Chat area UserChatPad userChatPad = new UserChatPad(); // User Operation area UserControlPad userControlPad = new UserControlPad(); // User input area UserInputPad userInputPad = new UserInputPad(); // Chess area FIRPad firPad = new FIRPad(); // Panel southPanel = new Panel(); Panel northPanel = new Panel(); Panel centerPanel = new Panel(); Panel eastPanel = new Panel(); // Construct method to create interface public FIRClient() { super("Java Goji Client"); setLayout(new BorderLayout()); host = userControlPad.ipInputted.getText(); eastPanel.setLayout(new BorderLayout()); eastPanel.add(userListPad, BorderLayout.NORTH); eastPanel.add(userChatPad, BorderLayout.CENTER); eastPanel.setBackground(Color.LIGHT_GRAY); userInputPad.contentInputted.addKeyListener(this); firPad.host = userControlPad.ipInputted.getText(); centerPanel.add(firPad, BorderLayout.CENTER); centerPanel.add(userInputPad, BorderLayout.SOUTH); centerPanel.setBackground(Color.LIGHT_GRAY); userControlPad.connectButton.addActionListener(this); userControlPad.createButton.addActionListener(this); userControlPad.joinButton.addActionListener(this); userControlPad.cancelButton.addActionListener(this); userControlPad.exitButton.addActionListener(this); userControlPad.createButton.setEnabled(false); userControlPad.joinButton.setEnabled(false); userControlPad.cancelButton.setEnabled(false); southPanel.add(userControlPad, BorderLayout.CENTER); southPanel.setBackground(Color.LIGHT_GRAY); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { if (isOnChat) { // try in chat { // Close the client socket clientSocket.close(); } catch (Exception ed){} } if (isOnChess || isGameConnected) { // Try in chess { // Close the chess port firPad.chessSocket.close(); } catch (Exception ee){} } System.exit(0); } }); add(eastPanel, BorderLayout.EAST); add(centerPanel, BorderLayout.CENTER); add(southPanel, BorderLayout.SOUTH);パック(); setSize(670, 560); setVisible(true); setResizable(false); this.validate(); } // Connect to the server according to the specified IP address and port public boolean connectToServer(String serverIP, int serverPort) throws Exception { try { // Create client socket clientSocket = new Socket(serverIP, serverPort); // Create input stream inputStream = new DataInputStream(clientSocket.getInputStream()); // Create outputStream = new DataOutputStream(clientSocket.getOutputStream()); // Create client thread FIRClientThread clientthread = new FIRClientThread(this); // Start the thread and wait for chat information clientthread.start(); isOnChat = true; trueを返します。 } catch (IOException ex) { userChatPad.chatTextArea .setText("Cannot connect!/n"); } falseを返します。 } // Client event handling public void actionPerformed(ActionEvent e) { if (e.getSource() == userControlPad.connectButton) { // Connect to the host button click event host = firPad.host = userControlPad.ipInputted.getText(); // Get the host address try { if (connectToServer(host, port)) { // When successfully connecting to the host, set the corresponding interface status of the client userChatPad.chatTextArea.setText(""); userControlPad.connectButton.setEnabled(false); userControlPad.createButton.setEnabled(true); userControlPad.joinButton.setEnabled(true); firPad.statusText.setText("Connection successful, please wait!"); } } catch (Exception ei) { userChatPad.chatTextArea .setText("Cannot connect!/n"); } } if (e.getSource() == userControlPad.exitButton) { // Leave the game button click event if (isOnChat) { // If the user is in a chat state try { // Close the client socket clientSocket.close(); } catch (Exception ed){} } if (isOnChess || isGameConnected) { // If the user is in the game state try { // Close the game port firPad.chessSocket.close(); } catch (Exception ee){} } System.exit(0); } if (e.getSource() == userControlPad.joinButton) { // Join the game button click event String selectedUser = (String)userListPad.userList.getSelectedItem(); // Get the game to be joined if (selectedUser == null || selectedUser.startsWith("[inchess]") || selectedUser.equals(chessClientName)) { // If the user to be joined is not selected, or the selected user is already in the game, a prompt message is given for firPad.statusText.setText("A user must be selected!"); } else { // Perform the operation of joining the game try { if (!isGameConnected) { // If the game socket is not connected if (firPad.connectServer(firPad.host, firPad.port)) { // If the connection to the host is successful isGameConnected = true; isOnChess = true; isParticipant = true; userControlPad.createButton.setEnabled(false); userControlPad.joinButton.setEnabled(false); userControlPad.cancelButton.setEnabled(true); firPad.firThread.sendMessage("/joingame " + (String)userListPad.userList.getSelectedItem() + " " + chessClientName); } } else { // If isOnChess = true; isParticipant = true; userControlPad.createButton.setEnabled(false); userControlPad.joinButton.setEnabled(false); userControlPad.cancelButton.setEnabled(true); firPad.firThread.sendMessage("/joingame " + (String)userListPad.userList.getSelectedItem() + " " + chessClientName); } } catch (Exception ee) { isGameConnected = false; isOnChess = false; isParticipant = false; userControlPad.createButton.setEnabled(true); userControlPad.joinButton.setEnabled(true); userControlPad.cancelButton.setEnabled(false); userChatPad.chatTextArea .setText("Cannot connect: /n" + ee); } } } } if (e.getSource() == userControlPad.createButton) { // Create game button click event try { if (!isGameConnected) { // If the game port is not connected if (firPad.connectServer(firPad.host, firPad.port)) { // If the connection to the host is successful isGameConnected = true; isOnChess = true; isCreator = true; userControlPad.createButton.setEnabled(false); userControlPad.joinButton.setEnabled(false); userControlPad.cancelButton.setEnabled(true); firPad.firThread.sendMessage("/creatgame " + "[inchess]" + chessClientName); } } else { // If the game port is connected isOnChess = true; isCreator = true; userControlPad.createButton.setEnabled(false); userControlPad.joinButton.setEnabled(false); userControlPad.cancelButton.setEnabled(true); firPad.firThread.sendMessage("/creatgame " + "[inchess]" + chessClientName); } } catch (Exception ec) { isGameConnected = false; isOnChess = false; isCreator = false; userControlPad.createButton.setEnabled(true); userControlPad.joinButton.setEnabled(true); userControlPad.cancelButton.setEnabled(false); ec.printStackTrace(); userChatPad.chatTextArea.setText("Cannot connect: /n" + ec); } } if (e.getSource() == userControlPad.cancelButton) { // Exit the game button click event if (isOnChess) { // FirPad.firThread.sendMessage("/giveup " + chessClientName); firPad.setVicStatus(-1 * firPad.chessColor); userControlPad.createButton.setEnabled(true); userControlPad.joinButton.setEnabled(true); userControlPad.cancelButton.setEnabled(false); firPad.statusText.setText("Please create or add the game!"); } if (!isOnChess) { // non-game userControlPad.createButton.setEnabled(true); userControlPad.joinButton.setEnabled(true); userControlPad.cancelButton.setEnabled(false); firPad.statusText.setText("Please create or join the game!"); } isParticipant = isCreator = false; } } public void keyPressed(KeyEvent e) { TextField inputwords = (TextField) e.getSource(); if (e.getKeyCode() == KeyEvent.VK_ENTER) { // Handle the carriage enter key event if (userInputPad.userChoice.getSelectedItem().equals("all users")) { // Send a message to everyone try { // Send a message outputStream.writeUTF(inputwords.getText()); inputwords.setText(""); } catch (Exception ea) { userChatPad.chatTextArea .setText("Cannot connect to the server!/n"); userListPad.userList.removeAll(); userInputPad.userChoice.removeAll(); inputwords.setText(""); userControlPad.connectButton.setEnabled(true); } } else { // Send a message to the designated person try { outputStream.writeUTF("/" + userInputPad.userChoice.getSelectedItem() + " " + inputwords.getText()); inputwords.setText(""); } catch (Exception ea) { userChatPad.chatTextArea .setText("Cannot connect to the server!/n"); userListPad.userList.removeAll(); userInputPad.userChoice.removeAll(); inputwords.setText(""); userControlPad.connectButton.setEnabled(true); } } } public void keyTyped(KeyEvent e) {} public void keyReleased(KeyEvent e) {} public static void main(String args[]) { FIRClient chessClient = new FIRClient(); }} 2.开发客户端线程
java.io.ioexceptionをインポートします。 import java.util.StringTokenizer; import javax.swing.DefaultListModel; import javax.swing.ListModel; /** * Created by Administrator on 2016/11/21. */ public class FIRClientThread extends Thread{ public FIRClient firClient; public FIRClientThread(FIRClient firClient) { this.firClient = firClient; } public void dealWithMsg(String msgReceived) { if (msgReceived.startsWith("/userlist ")) { // If the information obtained is the user list StringTokenizer userToken = new StringTokenizer(msgReceived, " "); int userNumber = 0; // Clear the client user list firClient.userListPad.userList.removeAll(); // Clear the client user drop-down box firClient.userInputPad.userChoice.removeAll(); // Clear the client user drop-down box firClient.userInputPad.userChoice.removeAll(); // Add an option to the client user drop-down box firClient.userInputPad.userChoice.addItem("all users"); while (userToken.hasMoreTokens()) { // When data exists in the received user information list String user = (String) userToken.nextToken(" "); // Get user information if (userNumber > 0 && !user.startsWith("[inchess]")) { // When user information is valid, firClient.userListPad.userList.add(user); // Add user information to the user list firClient.userInputPad.userChoice.addItem(user); // Add user information to the user drop-down box} userNumber++; } firClient.userInputPad.userChoice.setSelectedIndex(0);// The drop-down box selects everyone by default} else if (msgReceived.startsWith("/yourname ")) { // When the information received is the user's real name firClient.chessClientName = msgReceived.substring(10); // Get the user's real name firClient.setTitle("Java Goji Client" + "Username:" + firClient.chessClientName); // Set the title of the program Frame} else if (msgReceived.equals("/reject")) { // The message received is when the user is rejected try { firClient.firPad.statusText.setText("Cannot join the game!"); firClient.userControlPad.cancelButton.setEnabled(false); firClient.userControlPad.joinButton.setEnabled(true); firClient.userControlPad.createButton.setEnabled(true); } catch (Exception ef) { firClient.userChatPad.chatTextArea .setText("Cannot close!"); } firClient.userControlPad.joinButton.setEnabled(true); } else if (msgReceived.startsWith("/peer ")) { // When receiving the message is waiting in the game, firClient.firPad.chessPeerName = msgReceived.substring(6); if (firClient.isCreator) { // If the user is the game builder firClient.firPad.chessColor = 1; // Set it to be black chess first firClient.firPad.isMouseEnabled = true; firClient.firPad.statusText.setText("Black..."); } else if (firClient.isParticipant) { // If the user is a game joiner firClient.firPad.chessColor = -1; // Set it as a white chess last sex firClient.firPad.statusText.setText("Game join, wait for the opponent."); } } else if (msgReceived.equals("/youwin")) { // The message received is victory information firClient.isOnChess = false; firClient.firPad.setVicStatus(firClient.firPad.chessColor); firClient.firPad.statusText.setText("opter exit"); firClient.firPad.isMouseEnabled = false; } else if (msgReceived.equals("/OK")) { // Received a message to create the game for successful firClient.firPad.statusText.setText("Game creation waiting for opponent"); } else if (msgReceived.equals("/error")) { // Received a message to firClient.userChatPad.chatTextArea.append("Error, exit the program./n"); } else { firClient.userChatPad.chatTextArea.append(msgReceived + "/n"); firClient.userChatPad.chatTextArea.setCaretPosition( firClient.userChatPad.chatTextArea.getText().length()); } } public void run() { String message = ""; try { while (true) { // Wait for chat information and enter wait state message = firClient.inputStream.readUTF(); dealWithMsg(message); } } catch (IOException es){} } }至此,网络版五子棋就算是开发完成了。关于这么多类和包的关系如下图:
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。