В этой статье используется конкретный код для реализации Java Goziqi Online Version для вашей ссылки. Конкретный контент заключается в следующем
Анализ требований:
Для онлайн -Goji необходимо добавить следующие функции на основе обычного Goji:
1. Иметь серверную сторону и клиент. После того, как пользователи войдут на сервер через клиента, они могут играть в игры с другими введенными в систему пользователей.
2. Сервер поддерживает несколько групп пользователей для игры в игры одновременно
3. Пользователи могут создавать новые игры на сервере или присоединиться к созданным играм
4. Пользователи могут общаться и общаться во время игры в шахматы
Из вышесказанного мы можем знать функции, которые необходимо реализовать:
・ Предоставление сервер и клиентских функций
・ Сервер будет следить за состоянием входа клиента и позволит нескольким клиентам входить в систему
・ Пользователи могут войти на сервер через клиента, а затем они могут увидеть других пользователей сервера в настоящее время онлайн и общаться с ними и т. Д.
・ После входа на сервер пользователи могут создать новую игру Gozi или присоединиться к игре Catence Gozi.
・ Пользователи могут играть в игры с другими пользователями, такими как обычные Goji через клиент
Согласно функции, сеть Gochi разделен на 4 модуля: а именно модуль панели пользователя, модуль панели платы, модуль сервера Gochi и клиент Gochi Client
Давайте начнем собирать модуль панели пользователя:
1. Разработать панель списка пользователей
Импорт java.awt.*; /*** Создано администратором 2016/11/21. */// В начальном состоянии 10 информаций с именем «Нет пользователя» будет добавлена в список, указывающая, что сервер поддерживает до 10 пользователей в Интернете одновременно .///me List добавляется на панель, используя «Borderlayout» формата макета Public Class Pellispad Extends {public list userlist = new List (10); public userListPad () {setLayout (new BorderLayout ()); for (int i = 0; i <10; i ++) {userlist.add (i+"."+"Нет пользователя"); } add (userlist, borderlayout.center); }} 2. Разработать панель чата пользователя
импортировать javax.swing.*; Импорт java.awt.*; /*** Создано администратором 2016/11/21. */// Панель чата представляет собой управление представлением Textarea с вертикальной полосой прокрутки. // Textarea добавляется на панель, используя формат макета «Borderlayout». открытый класс userChatpad Extends jPanel {public jTextArea ChatTextarea = new JTextArea ("Командная область", 18,20); public userChatpad () {setLayout (new BorderLayout ()); chattextarea.setautoscrolls (true); chattextarea.setlinewrap (true); Добавить (ChatTextArea, BorderLayout.center); }} 3. Разработка панели ввода пользователя
импортировать javax.swing.*; Импорт java.awt.*; /*** Создано администратором 2016/11/21. */// Панель содержит два элемента управления представлением // contentInpated - это управление TextField, где пользователи могут ввести информацию в чате открытый класс userInputPad Extends 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+"."+"нет пользователя"); } userChoice.setSize (60,24); добавить (userChoice); добавить (contentInputed); }} 4. Разработка панели работы пользователя
импортировать javax.swing.*; Импорт java.awt.*; /*** Создано администратором 2016/11/21. */ public class usercontrolpad extends jpanel {public jlabel iplabel = new jlabel ("ip", jlabel.left); public jtextfield ipinputted = new jtextfield ("localhost", 10); public jbutton connectbutton = new jbutton («подключиться к серверу»); public jbutton createbutton = new jbutton ("Create Game"); public jbutton joinbutton = new jbutton ("присоединиться к игре"); public jbutton cancelbutton = new jbutton ("сдаться в игру"); public jbutton exitbutton = new jbutton ("exit game"); public usercontrolpad () {setlayout (new flowlayout (flowlayout.left)); Betbackground (color.light_gray); добавить (iplabel); добавить (ipinpated); Добавить (ConnectButton); добавить (createButton); добавить (joinbutton); Добавить (Cancelbutton); добавить (exitbutton); }} Начните разработать модуль панели платы ниже
1. Разработать черные шахматы
Импорт java.awt.*; /*** Создано администратором 2016/11/21. */ public class firpointblack расширяет Canvas {firpad padbelonged; // Правление, к которой черные шахматы принадлежат публичный FirpointBlack (Firpad padbelonged) {setsize (20, 20); // Установить размер шахматного куска this.padbelonged = padbelonged; } public void Paint (Graphics G) {// Нарисуйте шахматную часть g.setcolor (color.black); G.Filloval (0, 0, 14, 14); }} 2. Разработать категорию белых шахмат
Импорт java.awt.*; /*** Создано администратором 2016/11/21. */ открытый класс firpointwhite расширяет Canvas {firpad padbelonged; // Правление, к которой белые шахматы принадлежат публичному Firpointwhite (Firpad padbelonged) {setsize (20, 20); this.padbelonged = padbelonged; } public void Paint (Graphics 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 Extends Панель реализует MouseListener, ActionListener {// Можно ли использовать мышью общедоступную логин iSmouseEenabled = false; // выиграть ли открытый логический iswinned = false; // будь то играть в шахмат общественного логического ижаминга = false; // координата оси x бита шахматного произведения public int schessx_pos = -1; // координата оси Y Биты шахматного произведения public int Chessy_pos = -1; // цвет шахматного произведения public int chesscolor = 1; // Черная координата по оси X // Черная координата оси y // белая ось Y-ось координат битов Array Public int Chesswhite_xpos [] = new int [200]; // белые шахматы y-ось координат цифр // количество черных шахмат public int chessblackcount = 0; // количество белых шахматов Public int ChesswhiteCount = 0; // Количество черных шахмат выигрывает Public int Chessblackvictimes = 0; // количество белых шахмат выигрывает публичные int chesswhitevictimes = 0; // количество белых шахмат выигрывает публичные int chesswhitevictimes = 0; // интерфейс рукав общедоступный розетка; public DataInputStream inputData; public DataOutputStream outputData; public String ShesselfName = null; public String Chesspeername = null; public String host = null; Public Int Port = 4331; public Textfield statustext = new Textfield («Пожалуйста, подключитесь к серверу!»); Public Firthread Firthread = New Firthread (это); public firpad () {setSize (440, 440); setlayout (null); Betbackground (color.light_gray); AddMouseListener (это); добавить (statustext); statustext.setBounds (новый прямоугольник (40, 5, 360, 24)); statustext.setEdable (false); } // Подключиться к хосту Public Boolean ConnectServer (String Serverip, Int Serverport) Throws Exception {try {// Получить хост -порт chesssocket = new Socket (Serverip, ServerPort); // Получить входной поток inputData = new DataInputStream (ChessSocket.getInputStream ()); // получить outputData = new DataOutputStream (ChessSocket.getOutputStream ()); firthread.start (); вернуть истину; } catch (ioException ex) {statustext.settext ("Неудача соединения! /n"); } вернуть false; } // Установите статус доски при победе Public void setVicStatus (int vicesscolor) {// очистить доску 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; } // Очистить количество черных шахмат на плате SchessBlackCount = 0; // Очистить количество белых шахмат на доске шахматчики = 0; добавить (statustext); statustext.setBounds (40, 5, 360, 24); if (vicesscolor == 1) {// черные шахматы выигрывают Chessblackvictimes ++; statustext.settext ("черный, черный: белый" + шахматблаквитамм + ":" + шахмат -белые цвета + ", перезапуск игры, ждать белых ..."); } else if (vicesscolor == -1) {// белые шахматы выигрывают Chesswhitevictimes ++; statustext.settext («черный: белый» + шахматблаквитамм + »:« + chesswhitevictimes + », перезапуск игры, подождите черного ...»); }} // Получить позицию указанного шахматного произведения public void setlocation (int xpos, int ypos, int chesscolor) {if (chesscolor == 1) {// Когда шахмат черный, Chessblack_xpos [chessblackcount] = xpos * 20; chessblack_ypos [schessblackcount] = ypos * 20; SchessblackCount ++; } else if (chesscolor == -1) {// Когда шахмат белый, chesswhite_xpos [chesswhitecount] = xpos * 20; ChesswhiteCount ++; }} // Определите, является ли текущее состояние победителем государственного общественного логического контроля CheckVicStatus (int xpos, int ypos, int chesscolor) {int ChesslinkedCount = 1; // Количество подключенного к шахматному скольжению = 1; // используется для сравнения, хотите ли вы продолжить пересечение произведения int ChesstocompareIndex = 0; // Положение индекса кусочки, которое будет сравнивать int closegrid = 1; // положение соседней сетки if (chesscolor == 1) {// ChesslinkedCount = 1; // If the chess piece itself is counted, the initial number of connections is 1 //Each pair of for loop statements below is a group, because the position of the next period can be in the middle rather than at both ends for (closeGrid = 1; closeGrid <= 4; closeGrid++) { //Transipate through 4 adjacent grids for (chessToCompareIndex = 0; chessToCompareIndex <= chessBlackCount; chesstocompareindex ++) {// транспорт через все черные шахматные пьесы на плате if if (((xpos+closegrid) * 20 == schessblack_xpos [chesstocompareindex]) && (ypos * 20) == Chessblack_ypos [chesstocompareex]) (// Определите, как на четырех темпах, как на четве = ChesslinkedCount + 1; // Добавить 1 к количеству соединений, если (ChesslinkedCount == 5) {// Когда пять частей соединены, победа возвращает True; }}}} if (ChesslinkedCount == (ChesslinkedCompare+1)) {ChesslinkedCompare ++; } else {// Если в середине есть шахматный кусок, который не черный, он войдет в эту ветвь, и в это время нет необходимости снова пересекаться; }} for (closeGrid = 1; closeGrid <= 4; CloseGrid ++) {for (chesstocompareIndex = 0; chesstocompareindex <= chessblackcount; chesstocompareindex ++) {if ((xpos - closegrid) * 20 == chessblack_xpos [chesstocomparex) * 20 == = chessblack_xpos. chessblack_ypos [chesstocompareindex])) {// определить, являются ли четыре шахматные части слева от в настоящее время играют в ChesslinkedCount ++; if (ChesslinkedCount == 5) {return true; }}}} if (ChesslinkedCount == (ChesslinkedCompare+1)) {ChesslinkedCompare ++; } else {break; }} // При вводе нового набора для петлей сбросить количество соединений и т. Д. ChesslinkedCompare = 1; for (closeGrid = 1; closeGrid <= 4; CloseGrid ++) {for (chessTocompareIndex = 0; chesstocompareIndex <= Chessblackcount; ChessTocompareIndex ++) {if (xpos * 20 == chessblack_xpos [chesstocompareDex]) && (ypos+closblack_xpos [chesstocompareindex]) && (ypos+newgrid) * (ypos+newgrid). chessblack_ypos [chesstocompareindex])) {// определить, являются ли 4 лучших произведения в данный момент воспроизводимого ChesslinkedCount ++; if (ChesslinkedCount == 5) {return true; }}} if (ChesslinkedCount == (ChesslinkedCompare+1)) {ChesslinkedCompare ++; } else {break; }} for (closeGrid = 1; closeGrid <= 4; closeGrid ++) {for (chessTocompareIndex = 0; chesstocompareindex <= chassblackcount; chesstocompareindex ++) {if ((xpos * 20 == chessblack_xpos [chesstocpareindex] и (xpos * 20 == hessgrid_xpos [chesstocpareindex] & chessblack_ypos [chesstocompareindex])) {// определить, являются ли четыре пьесы ниже в настоящее время воспроизводится ChesslinkedCount ++; 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 <= ChessBlackCount; ChessTocompareIndex ++) {if (((xpos - closeGrid) * 20 == CHESSBLACK_XPOS [chesstocompareXomparex) chessblack_ypos [chesstocompareindex]) {// определить, четыре шахматистики в левом направлении в настоящее время играют в ChesslinkedCount ++; }} for (closeGrid = 1; closeGrid <= 4; closeGrid ++) {for (chesstocompareIndex = 0; chesstocompareindex <= chessblackcount; chesstocompareindex ++) {if ((xpos+closegrid) * 20 == chessblack_xpos 20 == Shessblack_ypos [chesstocompareindex])) {// Определите, являются ли четыре шахматные части в нижнем правом направлении текущего шахматного произведения чернокожие ChesslinkedCount ++; } else {break; chessblack_xpos [chesstocompareindex]) && ((ypos+blosegrid) * 20 == chessblack_ypos [chesstocompareindex])) {// определить, являются ли четыре шахматные части в верхнем правом направлении текущего часа 5). (ChesslinkedCount == (ChesslinkedCompare+1)) {ChesslinkedCompare ++; ((xpos - closegrid) * 20 == chessblack_xpos [chesstocompareindex]) && ((ypos - blosegrid) * 20 == chessblack_ypos [chesstocompareindex]) {// определить, являются ли четыре чашки в нижнем левом направлении) chesse peat chessedcount; вернуть true; (chesstocompareindex = 0; chesstocompareindex <= chesswhitecount; chesstocompareindex ++) {if (((xpos+closegrid) * 20 == chesswhite_xpos [chesstocompareindex]) && (ypos * 20 == chesswos_ypos [chesstocomparexex]) в настоящее время играет в ChesslinkedCount ++; (chesstocompareindex = 0; chesstocompareindex <= chesswhitecount; chesstocompareindex ++) {if (((xpos - closegrid) * 20 == chesswhite_xpos [chesstocompareindex]) && (ypos * 20 == chesswos_ypos [chesstocomparexex]) В настоящее время играет в ShasslinkedCount ++; <= 4; chesswhite_ypos [chesstocompareindex]) {// Определите, 4 лучших произведения в настоящее время играют в ChesslinkedCount ++; (CloseGrid = 1; CloseGrid <= 4; CloseGrid ++) {for (chesstocompareIndex = 0; chesstocompareindex <= chesswhitecount; chesstocompareindex ++) {if (xpos * 20 == chesswhite_xpos [chesstocompareindex]) && (ypos -nectgrid) * 20 = 20 = 20 = 20 = 20 = 20 = 20 = 20 = 20 = 20 = 20 = 20 = 20 =. chesswhite_ypos [chesstocompareindex]) {// определить, четыре пьесы ниже в настоящее время воспроизводится ChesslinkedCount = 1; chesswhite_xpos [chesstocompareindex]) && ((ypos+closegrid) * 20 == chesswhite_ypos [chesstocompareindex])) {// определить, являются ли все 4 части в верхнем левом направлении текущего шахмата. (ChesslinkedCount == (ChesslinkedCompare+1)) {ChesslinkedCompare ++; ((xpos+closegrid) * 20 == chesswhite_xpos [chesstocompareindex]) && ((ypos - closegrid) * 20 == chesswhite_ypos [chesstocompareindex]) {// определить, являются ли четыре шахматные части в нижнем направлении текущего часа chessedcuout); вернуть true; chesstocompareindex <= chesswhitecount; Шахматы - это белая шахматная связь ++; (chesstocompareindex = 0; chesstocompareindex <= chesswhitecount; chesstocompareindex ++) {if (((xpos - closegrid) * 20 == chesswhite_xpos [chesstocompareIndex]) && ((ypos - closegrid) * 20 == chesswhite_ypospos [chesstextmoppos) Четыре пьесы в левом нижнем направлении в настоящее время играют Paint (Graphics g) {для (int i = 40; i <= 380; i = i + 20) {g.drawline (40, i, 400, i); 400, 400); // Нарисуйте Chesspawn public void paintfirpoint (int xpos, int ypos, int chesscolor) {firpointblack firpblack = new Firpointblack (это); ypos, chesscolor); this.add (firpblack); // Установите мышь на недоступность} else {// Статус WIN FIRTHREAD.SENDMESSAGE (" /" + Chesspeername + " /Шахматы" + xpos + "" + ypos + "" + Chesscolor); SetVicStatus (1); (Iswinned == false) {firthread.sendmessage (" /" + chesspeername + " /chank" + xpos + "" + ypos + "" + chesscolor); Chesswhitecount + «Шаг)" + xpos + "" + ypos + " firpwhite.setbounds (xpos * 20 - 7, ypos * 20 - 7, 16, 16); Firpointblack (это); firepblack.setbounds (xpos * 20 - 7, ypos * 20 - 7, 16, 16); " + chesscolor); // djr this.add (firpblack); firpblack.setbounds (xpos * 20 - 7, ypos * 20 - 7, 16, 16); setVicStatus (1); ismouseEenabled = true;}} else if (chesscolor = -1) {isWinned = cheard = xpos, xpos, xpos, xpos. chesscolor); } else {firthread.sendmessage (" /" + chesspeername + " /victory" + chesscolor); MousePressed (Mouseevent E) {if (e.getModifiers () == inputevent.button1_mask) {chessx_pos = (int) e.getx (); Chessy_pos / 20 <2 || schessx_pos / 20> 19 || e) {} public void mouseexited (mouseevent e) {} public void mouseclicked (mouseevent e) {} public void actionperformed (actionevent e) {}} 4. Разработать нити шахматной доски
импортировать java.util.stringtokenizer; импортировать java.io.ioexception; /*** Создано администратором 2016/11/21. */ открытый класс Firthread Extends Thread {firpad currpad; // Шахматная плата текущего потока публично Firthread (Firpad Currpad) {this.currpad = currpad; } // Обработайте полученную информацию public void dealwithmsg (string msgreceived) {if (msgreceived.startswith ("/chance")) {// Полученная информация - это шахматный stringtokingizer usermsgtoken = new Stringtokenizer (msgreceived, ");"); // массив информации о шахматах и 0 индексов: x координата; 1 Индексный бит: y координата; 2 Индексный бит: ChessInfo = {"-1", "-1", "0"}; int i = 0; // флаг битов строки ChessInfotoken; while (usermsgtoken.hasmoretokens ()) {chessinfotoken = (string) usermsgtoken.nexttoken (""); if (i> = 1 && i <= 3) {chssInfo [i - 1] = chessInfotoken; } i ++; } currpad.paintnetfirpoint (integer.parseint (chessinfo [0]), integer .parseint (chessinfo [1]), integer.parseint (chessinfo [2])); } else if (msgreceived.startswith ("/yourname")) {// полученное сообщение переименовано в currpad.chesselfname = 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 extends panel {public textarea msgtextarea = new Textarea ("", 22, 50, textarea.scrollbars_vertical_only); public jlabel satternlabel = new jlabel («Текущие соединения:», label.left); Общественная панель msgpanel = new Panel (); Public Panel StatusPanel = New Panel (); public servermsgpanel () {setSize (350, 300); Betbackground (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); добавить (msgpanel, borderlayout.center); добавить (statuspanel, borderlayout.north); }} 2. Разработка серверного процесса
импортировать java.io.datainputstream; импортировать java.io.dataoutputstream; импортировать java.io.ioexception; импортировать java.net.socket; Импорт java.util.enumeration; импортировать java.util.hashtable; импортировать java.util.stringtokenizer; /*** Создано администратором 2016/11/21. */ public Class firserverthread Extends Thread {Socket Clientsocket; // Сохранить информацию о клиентском сокете хэштетабельный клиентдатахаш; // Сохранить хэш -хэш -хештибельный клиент, соответствующий порту клиента и выходного потока; // Сохранить хэш -хэш -хештибильный Chesspeerhash, соответствующий клиентскому сокету и имени клиента; // Сохранить хэш -серверсгпанель, соответствующий создателю игры и игре; логический isclientClosed = false; Public Firserverthread (Socket Clientsocket, Hashtable ClientDatahash, Hashtable ClientNamehash, Hashtable ChessPeerHash, ServerMsgPanel Server) {this.clientsocket = clientocketocket; this.clientdatahash = clientDatahash; this.clientnamehash = clientNamehash; this.chesspeerhash = chesspeerhash; this.servermsgpanel = server; } public void dealwithmsg (string msgreceived) {string clientName; String peername; if (msgreceived.startswith ("/")) {if (msgreceived.equals ("/list")) {// Полученная информация должна обновить обратную связь с списком пользователей (getUserList ()); } else if (msgreceived.startswith ("/creategame [inchess]")) {// Полученное сообщение - создать игровую строку gamecreaterame = msgreceived.substring (20); // Получение имени сервера Synchronized (clientNameHash) {// Поместите пользовательский порт в список пользователей clientNameHash.put (clientocket, msgreceived.substring (11)); } synchronized (chesspeerhash) {// Установить хост на состояние ожидания chesspeerhash.put (gamecreatername, "wait"); } Обратная связь ("/yourname" + clientNameHash.get (clientocket)); sendgamepeermsg (gamecreatername, "/ok"); SendPublicmsg (getUserList ()); } else if (msgreceived.startswith ("/joingame")) {// Полученное сообщение - при присоединении к игре 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; // Получить жизнь игрока} nameindex ++; } gamecReatorname = playernames [0]; GamePaticiPantName = PlayerNames [1]; if (chesspeerhash.containskey (gamecreatorname) && chesspeerhash.get (gamecreatorname) .equals ("wat")) {// игра была создана синхронизированной (clientNameHash) {// Добавить соответствующий клиентский namehash.put (clientsocket, ("inchess]" + GamePaticipname); } synchronized (chesspeerhash) {// добавить или изменить соответствующий chesspeerhash.put (gamecreatorname, gamepaticipantname); } sendPublicmsg (getUserList ()); // отправить сообщение в Game Joiner SendGamePeermsg (GamePaticiPantName, ("/peer" + "[inchess]" + gamecreatorname)); // Отправить игру создателю игры Sendgamepeermsg (GameCreatorName, ("/peer" + "[inchess]" + gamePaticiPantName)); } else {// Если игра не создана, игре отказывается быть добавленной SendGamePeermsg (GamePaticiPantName, "/disjuct"); try {closeClient (); } catch (Exception ez) {ez.printstackTrace (); }}} else if (msgreceived.startswith ("/[inchess]")) {// полученное сообщение int firstlocation = 0, lastlocation; lastLocation = msgreceived.indexof ("", 0); peername = msgreceived.substring ((первая кладовая + 1), последнее время); msgreceived = msgreceived.substring ((lastlocation + 1)); if (sendgamepeermsg (peername, msgreceived)) {обратная связь ("/ошибка"); }} else if (msgreceived.startswith ("/distup")) {// полученное сообщение - это когда вы отказываетесь от игры в String ChessclientName = msgreceived.substring (8); if (chesspeerhash.containskey (chessclientname) &&! ((String) chesspeerhash.get (chessclientname)) .equals ("wate")) {// Победитель - это Joiner, отправьте сообщение Sendgamepeermsg ((String) chesspeerhash.get (chessclientname); синхронизированный (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) {обратная связь ("неверная команда"); возвращаться; }}} else {msgreceived = clientNamehash.get (clientocket) + ">" + msgreceived; servermsgpanel.msgtextarea.append (msgreceived + "/n"); sendpublicmsg (msgreceived); servermsgpanel.msgtextarea.setcaretposition (servermsgpanel.msgtextarea.getText () .length ()); }} // Отправить public void sendpublicmsg (string publicmsg) {synchronized (clientdatahash) {for (enumeration enu = clientDatahash.elements (); enu .hasmoreElements ();) {DataOutputStream outputData = (DataOutputStream) enu.NextElement (); try {outputdata.writeutf (publicmsg); } catch (ioException es) {es.printstacktrace (); } } } } } // Send information to the user in the specified game public boolean sendGamePeerMsg(String gamePeerTarget, String gamePeerMsg) { for (Enumeration enu = clientDataHash.keys(); enu.hasMoreElements();) { // traverse to obtain the socket interface of the user in the game Socket userClient = (Socket) enu.nextelement (); if (gamepeertarget.equals ((string) clientnamehash.get (userclient)) &&! Gamepeertarget.equals ((string) clientNameHash .get (clientocket))) {// synchronized (clientDatahash) {// Создание выходного потока DataOutpream peeroutData = (dataOutputputeReam) clientDataShashshashshashshashshashshashshashshash. 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; // 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); пакет(); 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; вернуть истину; } 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.开发客户端线程
import 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 ")) { // 若取得的信息为用户列表StringTokenizer userToken = new StringTokenizer(msgReceived, " "); int userNumber = 0; // 清空客户端用户列表firClient.userListPad.userList.removeAll(); // 清空客户端用户下拉框firClient.userInputPad.userChoice.removeAll(); // 给客户端用户下拉框添加一个选项firClient.userInputPad.userChoice.addItem("所有用户"); while (userToken.hasMoreTokens()) { // 当收到的用户信息列表中存在数据时String user = (String) userToken.nextToken(" "); // 取得用户信息if (userNumber > 0 && !user.startsWith("[inchess]")) { // 用户信息有效时firClient.userListPad.userList.add(user);// 将用户信息添加到用户列表中firClient.userInputPad.userChoice.addItem(user); // 将用户信息添加到用户下拉框中} userNumber++; } firClient.userInputPad.userChoice.setSelectedIndex(0);// 下拉框默认选中所有人} else if (msgReceived.startsWith("/yourname ")) { // 收到的信息为用户本名时firClient.chessClientName = msgReceived.substring(10); // 取得用户本名firClient.setTitle("Java 五子棋客户端" + "用户名:" + firClient.chessClientName); // 设置程序Frame的标题} else if (msgReceived.equals("/reject")) { // 收到的信息为拒绝用户时try { firClient.firPad.statusText.setText("不能加入游戏!"); 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 ")) { // 收到信息为游戏中的等待时firClient.firPad.chessPeerName = msgReceived.substring(6); if (firClient.isCreator) { // 若用户为游戏建立者firClient.firPad.chessColor = 1; // 设定其为黑棋先行firClient.firPad.isMouseEnabled = true; firClient.firPad.statusText.setText("黑方下..."); } else if (firClient.isParticipant) { // 若用户为游戏加入者firClient.firPad.chessColor = -1; // 设定其为白棋后性firClient.firPad.statusText.setText("游戏加入,等待对手."); } } else if (msgReceived.equals("/youwin")) { // 收到信息为胜利信息firClient.isOnChess = false; firClient.firPad.setVicStatus(firClient.firPad.chessColor); firClient.firPad.statusText.setText("对手退出"); firClient.firPad.isMouseEnabled = false; } else if (msgReceived.equals("/OK")) { // 收到信息为成功创建游戏firClient.firPad.statusText.setText("游戏创建等待对手"); } else if (msgReceived.equals("/error")) { // 收到信息错误firClient.userChatPad.chatTextArea.append("错误,退出程序./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状态message = firClient.inputStream.readUTF(); dealWithMsg(message); } } catch (IOException es){} } }至此,网络版五子棋就算是开发完成了。关于这么多类和包的关系如下图:
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.