Este artigo compartilha o código específico para a implementação Java Goziqi versão online para sua referência. O conteúdo específico é o seguinte
Análise de requisitos:
Para o Goji Online, as seguintes funções precisam ser adicionadas com base no Goji comum:
1. Tenha um lado do servidor e um cliente. Depois que os usuários efetuam login no servidor através do cliente, eles podem jogar com outros usuários conectados.
2. O servidor suporta vários grupos de usuários para jogar jogos ao mesmo tempo
3. Os usuários podem criar novos jogos no servidor ou participar de jogos criados
4. Os usuários podem conversar e se comunicar enquanto jogam xadrez
Do exposto, podemos conhecer as funções que precisam ser implementadas:
・ Fornecer funções de servidor e cliente
・ O servidor monitorará o status de login do cliente e permitirá que vários clientes efetuem login
・ Os usuários podem fazer login no servidor através do cliente e, em seguida, podem ver outros usuários do servidor atualmente online e conversar com eles, etc.
・ Após o login no servidor, os usuários podem criar um novo jogo Gozi ou participar do jogo Gozi criado.
・ Os usuários podem jogar com outros usuários, como o comum Goji através do cliente
De acordo com a função, o gochi da rede é dividido em 4 módulos: o módulo do painel do usuário, o módulo do painel da placa, o módulo do servidor gochi e o módulo do cliente gochi
Vamos começar a compilar o módulo do painel do usuário:
1. Desenvolva o painel da lista de usuários
importar java.awt.*; /*** Criado pelo Administrador em 2016/11/21. */// No estado inicial, 10 informações denominadas "nenhum usuário" serão adicionadas à lista, indicando que o servidor suporta até 10 usuários on -line ao mesmo tempo. public userlistpad () {setLayout (new BorderLayout ()); for (int i = 0; i <10; i ++) {userList.add (i+"."+"sem usuário"); } add (userlist, borderlayout.center); }} 2. Desenvolva o painel de bate -papo de usuário
importar javax.swing.*; importar java.awt.*; /*** Criado pelo Administrador em 2016/11/21. */// O painel de bate -papo é um controle de visualização da Textarea com uma barra de rolagem vertical. // O Textarea é adicionado ao painel, usando o formato de layout "BorderLayout". classe pública userChatpad estende JPanel {public jtextarea chattextarea = new jtextarea ("área de comando", 18,20); public userChatpad () {setLayout (new BorderLayout ()); ChatTextarea.SetAUTOsCrolls (true); chattextarea.setLineWrap (true); add (chattextarea, borderlayout.center); }} 3. Desenvolva o painel de entrada do usuário
importar javax.swing.*; importar java.awt.*; /*** Criado pelo Administrador em 2016/11/21. */// O painel contém dois controles de exibição // contentInpitt é um controle de campo de texto, onde os usuários podem inserir informações de bate -papo public classe userInputpad estende o jpanel {public jtextfield contentInputted = new jtextfield ("", 26); public jComBobox userChoice = new JCOMBOBOX (); public userInputPad () {setLayout (new FlowLayout (FlowLayout.Left)); for (int i = 0; i <50; i ++) {userChoice.additem (i+"."+"sem usuário"); } userChoice.SetSize (60,24); add (userChoice); add (contentInputted); }} 4. Desenvolva o painel de operação do usuário
importar javax.swing.*; importar java.awt.*; /*** Criado pelo Administrador em 2016/11/21. */ classe pública UserControlpad estende JPanel {public jlabel iplabel = new jlabel ("ip", jlabel.left); public jtextfield ipinputted = new jtextfield ("localhost", 10); public jbutton conectButton = new jbutton ("Connect to Server"); public jbutton createButton = new jbutton ("Create Game"); public jbutton junçãobutton = new jbutton ("Join Game"); public jbutton cancelbutton = new jbutton ("Give Up Game"); public jbutton exitbutton = new jbutton ("jogo de saída"); public userControlpad () {setLayout (new FlowLayout (FlowLayout.Left)); contratempo (color.light_gray); add (iPlabel); add (ipInputted); Add (ConnectButton); add (createButton); Add (JunçãoButton); add (cancelbutton); add (exitbutton); }} Comece a desenvolver o módulo do painel da placa abaixo
1. Desenvolva xadrez preto
importar java.awt.*; /*** Criado pelo Administrador em 2016/11/21. */ classe pública FirPointblack estende a tela {Firpad PadBelonged; // A placa à qual o xadrez preto pertence a FirPointblack (Firpad Padbelonged) {Setsize (20, 20); // defina o tamanho da peça de xadrez this.padbelonged = padbelonged; } public void Paint (gráficos g) {// desenhe peças de xadrez g.setColor (color.black); G.Filloval (0, 0, 14, 14); }} 2. Desenvolva a categoria de xadrez branco
importar java.awt.*; /*** Criado pelo Administrador em 2016/11/21. */ classe pública FirPointWhite estende a tela {Firpad Padbelonged; // A placa à qual o xadrez branco pertence a FirPointwhite público (Firpad Padbelonged) {Setsize (20, 20); this.padbelonged = padbelonged; } public void Paint (gráficos g) {// desenhe peças de xadrez G.setColor (color.white); G.Filloval (0, 0, 14, 14); }} 3. Desenvolva um painel de tabuleiro de xadrez
importar java.awt.*; importar java.awt.event.*; importar java.io.*; importar java.net.*; importar javax.swing.jtextfield; /*** Criado pelo Administrador em 2016/11/21. */ classe pública firpad estende o painel implementa MouseListener, ActionListener {// O mouse pode ser usado public boolean isMouseenabled = false; // se deve ganhar o booleano público iswinned = false; // se deve jogar o xadrez booleano iSgaming = false; // x -AXIS coordenadas bits da peça de xadrez public int chessx_pos = -1; // y -axis coordenadas bits da peça de xadrez public int chessy_pos = -1; // cor da peça de xadrez public int chesscolor = 1; // Black X-Axis Coordenine Bit Array public int chessblack_xpos [] = new int [200]; // Black Y-Axis Coordenine Bit Array Public int chessblack_ypos [] = new int [200]; // White Y-AXIS Coordena Bit Array Public int chesswhite_xpos [] = new int [200]; // White Chess Y-Axis Coordenine Digit Array public int chesswhite_ypos [] = new int [200]; // número de xadrez preto public int chessblackCount = 0; // número de xadrez branco public int chesswhitEcount = 0; // Número de xadrez preto ganha public int chessblackvictimes = 0; // número de xadrez branco ganha public int chesswhiteVictimes = 0; // número de xadrez branco ganha public int chesswhiteVictimes = 0; // interface de manga Public Socket ChessSocket; public DataAinputStream inputData; public DataOutputStStream OutputData; public string chesselfname = null; public string chesspeername = null; public string host = null; public int porta = 4331; public textfield statustext = new textfield ("conecte -se ao servidor!"); public Firthread Firthread = New Firthread (isto); public Firpad () {Setsize (440, 440); setLayout (nulo); contratempo (color.light_gray); addmouseListener (isto); add (statustustext); statustext.setbounds (novo retângulo (40, 5, 360, 24)); statustext.setEditable (false); } // Conecte -se ao host public boolean ConnectServer (String Serverip, int serverport) lança Exceção {Try {// Get the Host Port ChessSocket = new Socket (Serverip, Serverport); // Obtenha o fluxo de entrada inputData = new DatainputStream (chesssocket.getInputStream ()); // Get OutputData = new DataOutputStream (ChessSocket.getOutputStream ()); firthread.start (); retornar true; } catch (ioexception ex) {statustext.settext ("conexão falhou! /n"); } retornar false; } // Defina o status da placa ao vencer public void setvicstatus (int vicchesscolor) {// limpe a placa this.removeall (); // Defina a posição de xadrez preto como zero para (int i = 0; i <= chessblackCount; i ++) {chessblack_xpos [i] = 0; chessblack_ypos [i] = 0; } // Defina a posição do xadrez branco como zero para (int i = 0; i <= chesswhitecount; i ++) {chesswhite_xpos [i] = 0; chesswhite_ypos [i] = 0; } // Limpe o número de xadrez preto na placa chessblackCount = 0; // Limpe o número de xadrez branco no quadro ChessWhitEcount = 0; add (statustustext); statustext.setbounds (40, 5, 360, 24); if (vicchesscolor == 1) {// xadrez preto ganha chessblackvictimes ++; statustext.settext ("preto, preto: branco" + chessblackvictimes + ":" + chesswhitevictimes + ", reinicialização do jogo, espere por branco ..."); } else if (vicchesscolor == -1) {// white xadrez ganha chesswhiteVictimes ++; statustext.settext ("preto: branco" + chessblackvictimes + ":" + chesswhitevictimes + ", reinicialização do jogo, espere por preto ..."); }} // Obtenha a posição da peça de xadrez especificada SetLocation public void (int xpos, int ypos, int chesscolor) {if (chesscolor == 1) {// Quando a peça de xadrez é preta, chessblack_xpos [chessblackcount] = xpos * 20; chessblack_ypos [chessblackCount] = ypos * 20; ChessBlackCount ++; } else if (chesscolor == -1) {// Quando a peça de xadrez é branca, chesswhite_xpos [chesswhitecount] = xpos * 20; ChessWhitECount ++; }} // Determine se o estado atual é um prêmio booleano do estado vencedor checkvicstatus (int xpos, int ypos, int chesscolor) {int chessLinkedCount = 1; // número de chessLinkedCompare conectado = 1; // costumava comparar se você deseja continuar atravessando uma peça int chessTocomeIndex = 0; // a posição do índice da peça a ser comparada int closeGrid = 1; // a posição da grade adjacente if (chesscolor == 1) {// chessLinkedCount = 1; // Se a própria peça de xadrez for contada, o número inicial de conexões é 1 // cada par de declarações de loop abaixo é um grupo, porque a posição do próximo período pode estar no meio e não nas duas extremidades (close -grid = 1; close -grids <= 4; closeGrid ++) {// transipate a 4 grades adjacent para (chessTear ChessTocompareIndex ++) {// transipita todas as peças de xadrez preto na placa se (((xpos+closeGrid) * 20 == chessblack_xpos [chessToComeIndEx]) && (YPOS * 20) == chesslack_ypos [chessToComEx]) { = ChessLinkedCount + 1; // Adicione 1 ao número de conexões se (ChessLinkedCount == 5) {// Quando as cinco peças estão conectadas, a vitória retorna true; }}}} if (ChessLinkedCount == (ChessLinkedCompare+1)) {ChessLinkedCompare ++; } else {// Se houver uma peça de xadrez no meio que não seja preta, ela entrará neste ramo e não há necessidade de atravessar a quebra novamente neste momento; }} para (closeGrid = 1; closeGrid <= 4; closeGrid ++) {for (chessTocomeIndex = 0; chessTocompareIndex <= chessblackCount; chessTocomPareIndEx ++) {if ((xpos - closeGrid) * 20 == chess] chessblack_ypos [chessTocomeIndex])) {// Determine se as quatro peças de xadrez à esquerda do atualmente tocando ChessLinkedCount ++; if (chessLinkedCount == 5) {return true; }}}} if (ChessLinkedCount == (ChessLinkedCompare+1)) {ChessLinkedCompare ++; } else {break; }} // Ao inserir um novo conjunto de loops, redefinir o número de conexões, etc. ChessLinkedCount = 1; ChessLinkedCompare = 1; para (CloseGrid = 1; CloseGrid <= 4; CloseGrid ++) {for (ChessTocomeIndex = 0; ChessTocomeIndex <= ChessBlackCount; ChessTocomeIndex ++) {if ((xpos * 20 == Chessblack_xpos [chessToComIndarex]) e housed) e (xpos * 20 == Chessblack_xpos [chessTocomIndEx]) e hemal chessblack_ypos [ChessTocomeIndex])) {// Determine se as 4 principais peças do ChessLinkedCount atualmente tocando ++; if (chessLinkedCount == 5) {return true; }}} if (ChessLinkedCount == (ChessLinkedCompare+1)) {ChessLinkedCompare ++; } else {break; }} para (CloseGrid = 1; CloseGrid <= 4; CloseGrid ++) {for (ChessTocomeIndex = 0; ChessTocomeIndex <= ChessblackCount; ChessTocomeIndEx ++) {if (xpos * 20 == Chessblack_xPos [chessTocare) chessblack_ypos [ChessTocomeIndex])) {// Determine se as quatro peças abaixo do atualmente jogado ChessLinkedCount ++; if (chessLinkedCount == 5) {return true; }}} if (ChessLinkedCount == (ChessLinkedCompare+1)) {ChessLinkedCompare ++; } else {break; }} ChessLinkedCount = 1; ChessLinkedCompare = 1; para (CloseGrid = 1; CloseGrid <= 4; CloseGrid ++) {for (chessTocompareIndex = 0; ChessTocompareIndex <= ChessBlackCount; ChessTocompareIndex ++) {if ((((xpos - closeGrid) * 20 == chessBlack_xPos [chess) A imagem está disponível para download em alta resolução por até 1920x1080. }} para (closeGrid = 1; closeGrid <= 4; closeGrid ++) {for (chessTocomeIndex = 0; chessTocomeIndex <= chessblackCount; chessTocomeIndEx ++) {if ((xpos+closeGrid) * 20 == chess) 20 == Chessblack_YPOS [ChessTocomPeeIndex])) {// Determine se as quatro peças de xadrez na direção direita inferior da peça de xadrez atual são pretas de chesslinkedCount ++; } else {break; chessblack_xpos [chessTocompeareIndEx]) && (YPOS+CloseGrid) * 20 == chessblack_ypos [chesstocompearindex]) {// determinar se as quatro peças de xadrez na parte superior da peça de chess atual «). (ChessLinkedCount == (ChessLinkedCompare+1)) {ChessLinkedCompare ++; ((XPOS - CloseGrid) * 20 == chessblack_xpos [chessTocomPeendex]) && ((ypos - closeGrid) * 20 == Chessblack_Ypos [ChessTocomPeendex]) {// Determine os quatro peças de xadrez na direção inferior esquerda do xadrez atual, é o bleoll; Retorno true; (ChessTocomeIndex = 0; ChessTocomeIndex <= ChessWhitEcount; ChessTocomeIndex ++) {if (((xpos+closeGrid) * 20 == Chesswhite_xpos [chessTocomeIndex]) && (yPOs * 20 == ChessWhite_YMos [Chessht [chess fours the the the the theats)) e yosex), que é o que é o que é o que é o que é o setor) * 20 =. do atualmente tocando ChessLinkedCount ++; (chessToCompareIndex = 0; chessToCompareIndex <= chessWhiteCount; chessToCompareIndex++) { if (((xPos - closeGrid) * 20 == chessWhite_XPOS[chessToCompareIndex]) && (yPos * 20 == chessWhite_YPOS[chessToCompareIndex])) {// Determine whether the four pieces on the left de jogo atualmente de CHESSLINGS; Er Chesswhite_YPOS [ChessTocomPeendex])) {// Determine se as 4 principais peças do ChessLinkedCount ++; (CloseGrid = 1; CloseGrid <= 4; CloseGrid ++) {for (ChessTocompareIndex = 0; ChessTocompareIndex <= ChessWhitEcount; ChessTocompareIndex ++) {if ((xpos * 20 == Chesswhite_xpos [chessToComIndarex]) e (xpos * 20 == Chesswhite_xpos [chesstoComex] chesswhite_ypos [chessTocomPeendex])) {// Determine se as quatro peças abaixo do jogo de chesslinkedcount atualmente jogadas; ChessLinkedCount = 1; chesswhite_xpos [ChessTocomeIndex]) && (YPOS+CloseGrid) * 20 == Chesswhite_YPos [ChessTocompareIndex]) {// Determine se todas as 4 peças na direção esquerda da peça atual «) (ChessLinkedCount == (ChessLinkedCompare+1)) {ChessLinkedCompare ++; ((XPOS+CloseGrid) * 20 == Chesswhite_xpos [ChessTocomPeendex]) && (YPOs - CloseGrid) * 20 == Chesswhite_YPos [ChessTocomPeendex]) {// Determine os quatro peças de chess na direção direita inferior do freio de freio, é o shess shess) Retorno verdadeiro; ChessTocompareIndex <= ChessWhitEcount; Piano de xadrez são brancos ChessLinkedCount ++; (ChessTocomeIndex = 0; ChessTocomeIndex <= ChessWhitEcount; ChessTocomeIndex ++) {if (((xpos - closeGrid) * 20 == Chesswhite_xpos [ChessTocomeIndex]) && (ypos - closeGrid) * 20 = CHASSHEMBETIMIMITEIRATHETIMIMIATHEMIMIATHIMATHIMIATHIMATEMET) &/ (YPOS - CloseGrid) * 20 = As quatro peças na direção inferior do que estão atualmente, IF (ChessLinkedCount == 5) {Return (true); Paint (gráficos g) {para (int i = 40; i <= 380; i = i + 20) {g.drawline (40, i, 400, i); 400, 400); // desenhe o chesspawn public void PaintfirPoint (int xpos, int yPOs, int chesscolor) {FirPointblack Firpblack = new FirPointblack (this); chesscolor); // Adicione peças de xadrez à placa Firpblack.Setbounds (XPOs * 20 - 7, YPOs * 20 - 7, 16, 16); else {// ganha o status de Firthread.sendMessage (" /" Parâmetro passado como xadrez preto IsMouseenabled = false; Firthread.sendMessage (" /" + chesspeername + " /xadrez" + xpos + "" + ypos + "" + chesscolor); xpos + " 7, 16, 16); FirPointWhite (isto); 16); Firpblack.SetBounds (XPOs * 20 - 7, YPOS * 20 - 7, 16, 16); Firpwhite. ChessColor); Inputevent.button1_mask) {chessx_pos = (int) e.getx (); chessy_pos / 20> 19) {// Nenhuma ação é executada quando a posição do xadrez está incorreta} else {PaintFirPoint (a, b, chesscolor); Void mouseclicked (mouseevent e) {} public void ActionPormed (ActionEvent e) {}} 4. Desenvolva threads de tabuleiro de xadrez
importar java.util.stringTokenizer; importar java.io.ioException; /*** Criado pelo Administrador em 2016/11/21. */ classe pública Firthread estende o thread {firpad currpad; // O quadro de xadrez do thread atual Firthread (firpad currpad) {this.currpad = currpad; } // Processe as informações obtidas public void dealWithmsg (string msGreCeived) {if (msgreeived.startswith ("/chess")) {// As informações recebidas são o Chess StringTokenizer UsermsgToken = new StringTokenizer (MSGrevived, ""); // A matriz de informações sobre peças de xadrez e 0 índices são: x coordenada; 1 bit de índice: y coordenar; 2 bit de índice: chessInfo = {"-1", "-1", "0"}; int i = 0; // string string string chessinfotoken; while (userMsgtoken.hasmoreTokens ()) {chessInfotoken = (string) userMsgToken.NextToken (""); if (i> = 1 && i <= 3) {chessInfo [i - 1] = chessInfoToken; } i ++; } currpad.PaintNetfirPoint (Integer.parseint (ChessInfo [0]), Inteiro .parseint (ChessInfo [1]), Integer.parseint (ChessInfo [2])); } else if (msgreceived.startswith ("/yourname")) {// A mensagem recebida é renomeada currpad.chessselfname = msgreceived.substring (10); } else if (msGreCeived.equals ("/error")) {// A mensagem de erro recebida é currpad.statustext.settext ("O usuário não existe, por favor, junte-se!"); }} // Envie a mensagem public void sendMessage (string sndmessage) {try {currpad.outputData.writeutf (sndmessage); } catch (exceção ea) {ea.printStackTrace () ;; }} public void run () {string msgreeived = ""; tente {while (true) {// aguarde a entrada de informações msgreceived = currpad.inputData.readUtf (); Dealwithmsg (MSGreceived); }} catch (ioexception es) {}}} Comece a desenvolver o módulo do servidor abaixo
1. Desenvolva o painel de informações do servidor
importar java.awt.borderlayout; importar java.awt.color; importar java.awt.flowlayout; importar java.awt.label; importar java.awt.panel; importar java.awt.textarea; importar javax.swing.jlabel; /*** Criado pelo Administrador em 2016/11/21. */ public class ServermsgPanel estende o painel {public texttarea msgTextarea = new texttarea ("", 22, 50, textarea.scrollbars_vertic_only); public jlabel statusLabel = new jlabel ("Conexões de corrente:", LABEL.LEFT); painel público msgpanel = new painel (); Painel público statusPanel = new Painel (); public servermsgPanel () {setSize (350, 300); contratempo (color.light_gray); setLayout (new BorderLayout ()); msgpanel.setLayout (new FlowLayout ()); msgpanel.setsize (210, 210); statusPanel.setLayout (new BorderLayout ()); statusPanel.SetSize (210, 50); msgPanel.add (msgTextAtea); statusPanel.add (statuslabel, borderlayout.west); add (msgpanel, borderlayout.center); add (statusPanel, borderlayout.north); }} 2. Desenvolva o processo do servidor
importar java.io.datainputStream; importar java.io.dataOutputStream; importar java.io.ioException; importar java.net.socket; importar java.util.enumeration; importar java.util.hashtable; importar java.util.stringTokenizer; /*** Criado pelo Administrador em 2016/11/21. */ classe pública FirserverThread estende o thread {Socket ClientSocket; // salvar informações do soquete do cliente hashtable clientDatahash; // salve o hashtable clientNamehash correspondente à porta do cliente e ao fluxo de saída; // salve o hashtable chesspeerhash correspondente ao soquete do cliente e ao nome do cliente; // salve o hash servermsgpanel correspondente ao criador do jogo e ao Joiner do jogo; boolean isclientcled = false; public FirserverThread (Socket Clientocket, Hashtable clientDataHash, hashtable clientNamehash, hashtable chesspeerhash, servermsgpanel server) {this.clientSocket = clientSocket; this.clientDataHash = clientDataHash; this.clientNameHash = clientNameHash; this.chesspeerhash = chesspeerhash; this.ServermsgPanel = servidor; } public void dealwithmsg (string msGreCeived) {string clientName; String peername; if (msGreCeived.startswith ("/")) {if (msgreeceived.equals ("/list")) {// as informações recebidas são para atualizar o feedback da lista de usuários (getUserList ()); } else if (msGreceived.startswith ("/creatgame [inchess]")) {// A mensagem recebida é para criar o jogo string gamecreArtername = msgreeived.substring (20); // Obtenha o nome do servidor sincronizado (ClientNameHash) {// Coloque a porta do usuário na lista de usuários clientNameHash.put (clusterSocket, msgreceived.substring (11)); } sincronizado (ChesspeerHash) {// Defina o host como o estado de espera Chesspeerhash.put (GameCreArtername, "Wait"); } Feedback ("/yourname" + clientnamehash.get (clusterocket)); sendGamepeMermsg (GameCreArtername, "/OK"); sendpublicmsg (getUserList ()); } else if (msGreceived.startswith ("/loningame")) {// A mensagem recebida é quando ingressar no jogo StringTokenizer userTokens = new StringTokenizer (MSGreCeived, ""); String UserToken; String gamecreatorname; String gamepaticipantName; String [] playerNames = {"0", "0"}; int nameIndex = 0; while (userTokens.hasmoreTokens ()) {userToken = (String) userTokens.nextToken (""); if (nameIndex> = 1 && nameIndex <= 2) {playerNames [nameIndex - 1] = userToken; // Obtenha a vida do jogador} nameIndex ++; } GameCreatorName = PlayerNames [0]; gamepaticipantName = playerNames [1]; if (chesspeerhash.containskey (gamecreatorname) && chesspeerhash.get (gamecreatorname) .equals ("wait")) {// o jogo foi criado sincronizado (clientNameHash) {// adicione o cliente correspondentehash.put (cliquesocket, ("[Inchess]" " } sincronizado (ChesspeerHash) {// Adicionar ou modificar o correspondente ChesspeerHash.put (gameCreatorName, gamepaticipantName); } sendpublicmsg (getUserList ()); // Envie a mensagem para o jogo JOUNS sendgamepeermsg (gamepaticipantName, ("/peer" + "[Inchess]" + gameCreatorname)); // Envie o jogo para o criador do jogo Sendgamepeermsg (gameCreatorName, ("/peer" + "[Inchess]" + gamepaticipantName)); } else {// Se o jogo não for criado, o jogo se recusou a ser adicionado sendgamepeermsg (gamepaticipantName, "/rejeição"); tente {ClosClient (); } catch (exceção ez) {ez.printStackTrace (); }}} else if (msGreceived.startswith ("/[Inchess]")) {// A mensagem recebida é int primeiroLocation = 0, lastLocation; lastLocation = msgreceived.indexof ("", 0); Peername = msgreceived.substring ((FirstLocation + 1), lastLocation); msGreCeived = msgreceived.substring ((lastLocation + 1)); if (sendgamepeMermsg (Peername, msgreceived)) {feedback ("/erro"); }} else if (msgreceived.startswith ("/giveUp")) {// A mensagem recebida é quando você desiste da string de jogo chessClientName = msgreceived.substring (8); if (chesspeerhash.containsKey (chessclientName) &&! ((string) chesspeerhash.get (chessclientName)) .equals ("wait")) {// o vencedor é o jogo de jogo, envie o jogo de jogo; sincronizado (chesspeerhash) {// exclua o usuário, saia do jogo chesspeerhash.remove (xadlientName); }} if (chesspeerhash.containsValue (ChessClientName)) {// O vencedor é o criador do jogo e envia a mensagem da vitória sendgamepeermsg ((string) gethashkey (chesspeerhash, chessclientname), "/youwin"); Sincronizado (ChesspeerHash) {// Exclua o usuário Desative o jogo chesspeerhash.remove ((string) gethashKey (chesspeerhash, chessclientName)); }}} else {// Quando as informações recebidas são outras informações int lastLocation = msGreCeived.indexof ("", 0); if (lastLocation == -1) {feedback ("comando inválido"); retornar; }}} else {msGreCeived = clientNamehash.get (clusterSocket) + ">" + msGreCeived; servermsgpanel.msgtextarea.append (msgreceived + "/n"); sendpublicmsg (MSGREVEIDO); servermsgpanel.msgtextarea.setCaretPosition (servermsgPanel.msgtextarea.getText () .Length ()); }} // Envie public void sendpublicmsg (string publicmsg) {synchronized (clientDataHash) {for (enumeração ENU = clientDataHash.Elements (); enu .hasMoreElements ();) {DataOutputStream OutputA = (DataOutStream) uu.nextElements (); tente {outputData.WriteUtf (publicmsg); } catch (ioexception es) {es.printStackTrace (); }}}}} // Envie informações ao usuário no jogo especificado público booleano sendgamepeermsg (string gamePeerTarget, string gamePeermsg) {para (enumeração enu = clientdatahash.keys (); enu.hmoreElements (); enu.nextElement (); if (gamePeerTarget.equals (((string) clientNamehash.get (userClient)) &&! gamepeerTarget.equals (((string) clientNameHash .get (clientSocket))) {// synchronized (clientDataHash) {// criar stream de saída dataOutstream PEERROTDATA = (DataDataHash) {// Criar saída de saída de dados tente {// envie informações peeroutdata.writeutf (gamepeermsg); } catch (IOException es) { es.printStackTrace(); }} retornar false; }} retornar 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.开发服务器端
import java.io.*; import java.net.*; import java.awt.*; importar 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); } }); pacote(); setVisible(true); setSize(400, 300); setResizable(false); validar(); 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.*; import java.io.*; import java.net.*; import 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; // Whether the game is 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); pacote(); 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; retornar true; } catch (IOException ex) { userChatPad.chatTextArea .setText("Cannot connect!/n"); } return 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.开发客户端线程
importar 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){} } }至此,网络版五子棋就算是开发完成了。关于这么多类和包的关系如下图:
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.