이 기사는 참조를 위해 Java 구현 Goziqi 온라인 버전의 특정 코드를 공유합니다. 특정 내용은 다음과 같습니다
요구 사항 분석 :
온라인 Goji의 경우 일반 Goji를 기반으로 다음 기능을 추가해야합니다.
1. 서버 쪽과 클라이언트가 있습니다. 사용자가 클라이언트를 통해 서버에 로그인 한 후에는 다른 로그인 한 사용자와 게임을 할 수 있습니다.
2. 서버는 여러 사용자 그룹이 동시에 게임을하도록 지원합니다.
3. 사용자는 서버에서 새 게임을 만들거나 생성 된 게임에 가입 할 수 있습니다.
4. 사용자는 체스를하는 동안 채팅하고 의사 소통 할 수 있습니다
위에서부터 구현 해야하는 기능을 알 수 있습니다.
server 서버 및 클라이언트 기능 제공
server 서버는 클라이언트의 로그인 상태를 모니터링하고 여러 클라이언트가 로그인 할 수 있습니다.
∎ 사용자는 클라이언트를 통해 서버에 로그인 한 다음 현재 온라인 서버의 다른 사용자를보고 등장 할 수 있습니다.
server 서버에 로그인 한 후 사용자는 새로운 Gozi 게임을 만들거나 생성 된 Gozi 게임에 가입 할 수 있습니다.
∎ 사용자는 클라이언트를 통해 일반 Goji와 같은 다른 사용자와 게임을 할 수 있습니다.
기능에 따르면 네트워크 gochi는 4 개의 모듈로 나뉩니다. 즉, 사용자 패널 모듈, 보드 패널 모듈, Gochi 서버 모듈 및 Gochi 클라이언트 모듈로 나뉩니다.
사용자 패널 모듈 컴파일을 시작하겠습니다.
1. 사용자 목록 패널을 개발하십시오
java.awt.*; /*** 2016/11/21에 관리자가 작성했습니다. */// 초기 상태에서 "No User"라는 10 개의 정보가 목록에 추가됩니다. 이는 서버가 동시에 최대 10 명의 사용자를 동시에 지원 함을 나타냅니다 .// 목록은 "BorderLayout"레이아웃 형식을 사용하여 패널에 추가되어 공개 클래스 userListPad 패널 {public list userList = new List (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가 패널에 추가됩니다. 공개 클래스 userchatpad는 jpanel {public jtextArea chattextArea = new JtextArea ( "Command Area", 18,20); public userchatpad () {setlayout (new BorderLayout ()); chattextArea.setAutoScrolls (true); chatTextArea.SetLineWrap (true); 추가 (chattextArea, BorderLayout.Center); }} 3. 사용자 입력 패널을 개발하십시오
javax.swing을 가져옵니다.*; java.awt.*; /*** 2016/11/21에 관리자가 작성했습니다. *// 패널에는 두 개의 뷰 컨트롤이 포함되어 있습니다. // contentInpitted는 텍스트 필드 컨트롤입니다. 여기서 사용자는 채팅 정보를 입력 할 수 있습니다. 공개 클래스 userInputpad는 jpanel {public jtextfield contentInputted = new JtextField ( "", 26); public jcombobox userchoice = 새로운 jcombobox (); public userInputPad () {setLayout (new FlowLayout (flowLayout.left)); for (int i = 0; i <50; i ++) {userchoice.additem (i+"."+"no user"); } userchoice.setsize (60,24); 추가 (userchoice); 추가 (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 ( "서버에 연결"); Public Jbutton CreateButton = New JButton ( "게임 만들기"); Public Jbutton JoinButton = New JButton ( "게임 조인 게임"); Public Jbutton CancelButton = New JButton ( "Power Game"); Public Jbutton ExitButton = New JButton ( "Exit Game"); public usercontrolpad () {setlayout (new FlowLayout (flowlayout.left)); 좌절장 (color.light_gray); 추가 (iplabel); 추가 (ipinputted); 추가 (ConnectButton); 추가 (CreateButton); 추가 (joinbutton); 추가 (cancelButton); 추가 (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 firpointwhite 확장 캔버스 {firpad padbelonged; // 흰색 체스가 공개 FirPointwhite (FirPad Padbelonged) {setSize (20, 20); this.padbelonged = padbelonged; } public void Paint (그래픽 g) {// 체스 조각을 그리십시오. G.Filloval (0, 0, 14, 14); }} 3. 체스 판 패널을 개발하십시오
java.awt.*; import java.awt.event.*; java.io.*; java.net.*; import javax.swing.jtextfield; /*** 2016/11/21에 관리자가 작성했습니다. */ public class firpad 확장 패널 구현 mouselistener, actionListener {// 마우스를 사용할 수 있습니까? public boolean ismouseEnabled = false; // 공개 부울 iswinned = false; // 체스를 재생하는지 공개 부울 isgaming = false; // 체스 조각의 x- 축 좌표 비트 public int chessx_pos = -1; // 체스 조각의 y 축 좌표 비트 public int chessy_pos = -1; // 체스 조각의 색상 public int chesscolor = 1; // 검은 색 x 축 코디네이션 비트 배열 공개 int chessblack_xpos [] = new int [200]; // 검은 색 y 축 코디네이트 비트 배열 공개 int chessblack_ypos [] = new int [200]; // 흰색 y 축 좌표 비트 배열 공개 int chesswhite_xpos [] = new int [200]; // 흰색 체스 y 축 좌표 숫자 배열 공개 int chesswhite_ypos [] = new int [200]; // 검은 색 체스 수 int chessblackcount = 0; // 흰색 체스 수 int chesswhitecount = 0; // 검은 체스 수가 공개 int chessblackvictimes = 0; // 흰색 체스 수가 공개 int chesswhitevictimes = 0; // 흰색 체스 수가 공개 int chesswhitevictimes = 0; // 슬리브 인터페이스 public Socket ChessSocket; public datainputStream inputData; 공개 DataOutputStream outputData; 공개 문자열 chesselfname = null; 공개 문자열 chesspeername = null; 공개 문자열 호스트 = null; 공개 int 포트 = 4331; Public Textfield Statustext = New Textfield ( "서버에 연결하십시오!"); 공개 Firthread Firthread = New Firthread (this); public firpad () {setsize (440, 440); setLayout (null); 좌절장 (color.light_gray); AddMousElistener (this); 추가 (statustext); statustext.setbounds (새로운 사각형 (40, 5, 360, 24)); statustext.seteditable (false); } // 호스트에 연결 Public Boolean ConnectServer (String Serverip, int ServerPort) 예외 {try {// 호스트 chesssocket = new Socket (Serverip, ServerPort); // 입력 스트림을 가져옵니다. inputData = new DatainputStream (chesssocket.getInputStream ()); // get outputData = new DataOutputStream (chessSocket.getOutputStream ()); firthread.start (); 진실을 반환하십시오. } catch (ioexception ex) {statustext.settext ( "연결 실패! /n"); } false를 반환합니다. } // 공개 void SetVicstatus (int VicchessColor)에서 우승 할 때 보드 상태를 설정합니다. {// 보드를 지우십시오. removeall (); // 검은 체스 위치를 (int i = 0; i <= ChessBlackCount; i ++)로 설정합니다. {ChessBlack_XPOS [i] = 0; Chessblack_ypos [i] = 0; } // 흰색 체스의 위치를 0으로 설정합니다 (int i = 0; i <= chesswhitecount; i ++) {chesswhite_xpos [i] = 0; Chesswhite_ypos [i] = 0; } // 보드에서 검은 체스 수를 지우십시오. ChessBlackCount = 0; // 보드에서 흰색 체스 수를 지우십시오. ChesswhiteCount = 0; 추가 (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 + ", 게임 재시작, 검은 색 대기 ..."); }} // 지정된 체스 조각의 위치를 가져옵니다. public void setlocation (int xpos, int ypos, int chesscolor) {if (chesscolor == 1) {// 체스 조각이 검은 색 일 때, ChessBlack_xpos [chessblackcount] = xpos * 20; Chessblack_ypos [ChessblackCount] = ypos * 20; ChessBlackCount ++; } else if (chesscolor == -1) {// 체스 조각이 흰색 일 때 Chesswhite_xpos [ChesswhiteCount] = xpos * 20; ChesswhiteCount ++; }} // 현재 상태가 우승 한 주 공개 부울 checkvicstatus (int xpos, int ypos, int chesscolor) {int chesslinkedcount = 1; // 연결된 ChessLinkedCompare의 수 = 1; // 조각을 계속 통과할지 여부를 비교하는 데 사용됩니다 int chesstocompareIndex = 0; // 비교할 조각의 인덱스 위치 int closeGrid = 1; // 인접 그리드의 위치 if (chesscolor == 1) {// chesslinkedCount = 1; // 체스 조각 자체가 계산되면, 초기 연결 수는 1입니다. // 아래의 루프 문장의 각 쌍은 그룹입니다. 다음 기간의 위치는 양쪽 끝이 아니라 중간에있을 수 있기 때문에 (CloseGrid = 1; CloseGrid <= 4; CloseGrid ++) {// 4 인접적 인 Grids를 통해 (ChesstoComparount = 0; chessocution <= 0; ChesstOcutoIndex); chesstocompareindex ++) {// 보드의 모든 검은 체스 조각을 통과합니다. if (((XPOS+CloseGrid) * 20 == chessblack_xpos [chesstocompareIndex]) && ((ypos * 20) == ChessBlack_ypos [chesstompareindex]) {// 현재 재생되는 4 가지 작품이 결정되는지 여부를 결정하는지 ChessLinkedCount + 1; // if (chesslinkedCount == 5) {// 5 조각이 연결되면 승리가 참으로 반환됩니다. }}}} if (chessLinkedCount == (ChessLinkedCompare+1)) {chessLinkedCompare ++; } else {// 중간에 검은 색이 아닌 체스 조각이 있다면이 지점에 들어가고 지금은 다시 방향으로 돌릴 필요가 없습니다. }} for (closeGrid = 1; CloseGrid <= 4; CloseGrid ++) {for (chesstocompareIndex = 0; ChesstoCompareIndex <= ChessBlackCount; ChesstoCompareIndex+of) {if ((XPOS -CloseGrid) * 20 == ChessBlack_xpos [ChessTocomparare areindex]) 및 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 <= chessblackcount; chesstocompareindex ++) {if (xpos * 20 == chessblack_xpos [chesstocompareindex]) && (ypos+closeGrid) * 20 == 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 <= chessblackcount; chesstocompareIndex ++) {if ((xpos * 20 == chessblackareIndex] && (ypos - close -grid) * 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 [chesstocompare]) && (YPOS+closeGrid). chessblack_ypos [chesstocompareindex]) {// 현재 연주하는 왼쪽 상단에있는 4 개의 체스 조각 (ChesslinkedCount == 5)} if (chesslinkedcount ==); }} for (closeGrid = 1; CloseGrid <= 4; CloseGrid ++) {for (chesstocompareIndex = 0; ChesstoCompareIndex <= chessBlackCount; chesstocompareIndex+of) {if ((XPOS+CloseGrid) * 20 == ChessBlack_xpos [chesstocompormare -strid)). Chessblack_ypos [ChesstocompareIndex]) {// 현재 체스 조각의 오른쪽 방향이 검은 색 체스 ++인지 결정합니다 {break;} chesslinkedcount = 1; Chessblack_xpos [ChesstocompareIndex]) && (YPOS+CloseGrid) * 20 == chessblack_ypos [chesstocompareIndex]) {// 현재 체스의 오른쪽 방향에있는 4 개의 체스가 검은 색 체스 링크 ++ (ChessLinkedCount == (ChessLinkedCompare+1)) {ChessLinkedCompare ++} else {CloseGrid <= 4; CloseGrid ++) {(ChesstoCompareIndex <= ChessTocomparecount; ((XPOS- CloseGrid) * 20 == ChessBlack_XPOS [ChesstoCompareIndex]) && ((YPOS -CloseGrid) * 20 == ChessBlack_ypos [chesstocompareIndex])) {현재 체스의 왼쪽 하단에있는 4 개의 체스 조각이 검은 색 체스 링크++; }}} if (chesslinkedCount == (ChessLinkedCompare+1)) {chesslinkedcompare ++; = 0; ChesstocompareIndex <= ChesstocompareIndex ++; chesslinkedcount ++; ChesstocompareIndex <= ChesswhiteCount; if ((XPOS -CloseGrid) * 20 == chesswhite * 20 == Chesswhite_ypos [chesstocompareindex]) {// (ChessLinkedCount) {chessLinkedCount+1) {chessLinkedCompare ++} {break}} chesslinked = 1; (chesstocompareindex = 0; chesstocompareindex <= chesswhitecount; chesstocompareindex ++) {if ((xpos * 20 == chesswhite_xpos [chesstocompareIndex]) && (ypos+closegrid) * 20 == Chesstwhite_ [chesstwhite_ypare] chesslinkedcount ++; ChesstocompareIndex <= ChesswhiteCount; if (XPOS * 20 == chesstocompareIndex] && ((ypos -closeGrid) * 20 == Chesswhite_ypos [ChesstoPareIndex]) {// (ChessLinkedCount) {chessLinkedCount+1) {chessLinkedCompare ++} {break}} chesslinked = 1; (chesstocompareindex = 0; chesstocompareindex <= chesswhitecount; chesstocompareindex ++) {if (((xPOS -closeGrid) * 20 == chesswhite_xpos [chesstocompareIndex]) && ((ypos+closeGrid) * 20 == chesswhite_ypos [chesstocompareind west th thes thestocompareind 현재 체스 조각의 왼쪽 방향은 흰색 ChesslinkedCount ++입니다. {for (chesstocompareindex = 0; chesstocompareIndex <= chesswhitecount; chesstocompareindex ++) {if (((xpos+closegrid) * 20 == Chesswhite_xpos [chesstocompareindex]) && ((ypos -closegrid) * 20 == chessitos [chessoforeindex) 현재 체스 조각의 오른쪽 방향은 흰색 체스 링크 ++입니다 = 1; for (closeGrid = 1; CloseGrid <= 4; CloseGrid ++) {for (chesstocompareIndex = 0; chesstocompareIndex <= chesswhiteCount; chesstocompareIndex+of) {if ((XPOS+CloseGrid) * 20 == Chesswhite_xpos [chesstocomporare+fridex]). Chesswhite_ypos [ChesstocompareIndex]) {// 현재 체스 조각의 오른쪽 방향이 흰색 인 경우 (chesslinkedcount == 5) {return} {chesslinkedcount+1). break; == Chesswhite_ypos [ChesstocompareIndex]) {// 현재 재생되는 왼쪽 방향의 네 조각을 결정합니다 {break;}} 거짓말을 반환합니다. 400,} G.Filloval (97, 97, 6, 6); G.Filloval (217, 217, 6, 6); 체스 조각 setlocation (xpos, ypos, chesscolor); add (firpblack). // 보드에 체스 조각을 추가합니다 {// win win win win win wind message.sendmessage 방법과 흑인 체스 승리 ismouseEnabled = false} else (chesscolor == -1 && ismouseenabled) {// white chess setlocation (XPOS, chesscolor); firthread.sendmessage ( " /" + chesspeername + " /chess" + xpos + "" + chesscolor); + ypos + "); setvicstatus (-1); YPOS, Chesscolor) {iswinned = checkvicstatus (iswinned == false) {heplack.settect (16); chessblackcount + " + xpos +" " + ypos +", ismouseenabled = true}; 7, 16, 16); ; firpwhite. 세트 바운드 (xpos * 20-7, ypos * 20-7, 16, 16); e.getx (); chessy_pos = (int) e. int a = (chessx_pos + 10) / 20; Paintfirpoint (A, B, Chesscolor); // 체스 조각 그리기}}} public void MouserEleder (mouseevent e) {} public void mouseexed (mouseevent e) {mouseevent void mouseclicked (mouseeev e). e) {}} 4. 체스 보드 스레드를 개발하십시오
java.util.stringtokenizer 가져 오기; import java.io.ioexception; /*** 2016/11/21에 관리자가 작성했습니다. */ public class firthread는 스레드 {firpad currpad; // 현재 스레드의 체스 보드 공개 firthread (firpad currpad) {this.currpad = currpad; } // 획득 된 정보 공개 void dealwithmsg (String msgreceived) {if (msgreceived.startswith ( "/chess")) {// 수신 된 정보는 체스 stringtokenizer usermsgtoken = new StringTokenizer (msgreceived, ""); // 체스 조각의 배열 정보와 0 인덱스는 다음과 같습니다. x 좌표; 1 인덱스 비트 : Y 좌표; 2 인덱스 비트 : Chessinfo = { "-1", "-1", "0"}; int i = 0; // 플래그 비트 문자열 체스 신호 켄; 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입니다 ( "사용자는 존재하지 않으므로 다시 합류하십시오!"); }} // 메시지 보내기 공개 void sendMessage (string sndmessage) {try {currpad.outputdata.writeutf (sndmessage); } catch (예외 ea) {ea.printstacktrace () ;; }} public void run () {String msgreceived = ""; try {while (true) {// 정보 입력 대기 msgreceived = currpad.inputdata.readutf (); DealWithmsg (msgreceived); }} catch (ioexception es) {}}} 아래 서버 모듈 개발을 시작하십시오
1. 서버 정보 패널을 개발하십시오
java.awt.borderlayout import; import java.awt.color; java.awt.flowlayout 가져 오기; import java.awt.label; import java.awt.panel; Java.awt.TextArea 가져 오기; import javax.swing.jlabel; /*** 2016/11/21에 관리자가 작성했습니다. */ public class servermsgpanel 확장 패널 {public textarea msgtextArea = new TextRea ( "", 22, 50, TextRolea.scrollbars_vertical_only); public jlabel statuslabel = new Jlabel ( "현재 연결 :", label.left); 공개 패널 msgpanel = 새로운 패널 (); public panel statuspanel = 새 패널 (); public servermsgpanel () {setsize (350, 300); 좌절장 (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. 서버 프로세스를 개발하십시오
import java.io.datainputstream; import java.io.dataOutputStream; import java.io.ioexception; import java.net.socket; java.util.enumeration 가져 오기; java.util.hashtable import; java.util.stringtokenizer 가져 오기; /*** 2016/11/21에 관리자가 작성했습니다. */ public class firserverthread는 스레드 {socket clientsocket; // 클라이언트 소켓 정보 저장 hashtable clientDataHash; // 클라이언트 포트 및 출력 스트림에 해당하는 해시 해시 가능한 ClientNameHash를 저장합니다. // 클라이언트 소켓 및 클라이언트 이름에 해당 해시 해시 테이블 Chesspeerhash를 저장합니다. // 게임 제작자 및 게임 조인에 해당하는 해시 ServerMSGPANEL을 저장합니다. 부울 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 = 서버; } public void dealwithmsg (String msgreceived) {문자열 clientName; 문자열 공지 이름; if (msgreceived.startSwith ( "/")) {if (msgreceived.equals ( "/list")) {// 수신 된 정보는 사용자 목록 피드백을 업데이트하는 것입니다 (getUserList ()); } else if (msgreceived.startSwith ( "/creatgame [incons]")) {// 수신 된 메시지는 게임 문자열을 생성하는 것입니다 GameCreatername = msgreceived.substring (20); // 서버 이름 동기화 (clientNameHash) {// 사용자 포트를 사용자 목록에 넣습니다. } synchronized (chesspeerhash) {// 호스트를 대기 상태 Chesspeerhash.put으로 설정합니다 (GameCreaTname, "Wait"); } 피드백 ( "/YourName" + ClientNameHash.get (ClientSocket)); sendgamepeermsg (GameCreaTname, "/OK"); sendpublicmsg (getUserList ()); } else if (msgreceived.startSwith ( "/joingame")) {// 수신 된 메시지는 게임 tokenizer UserTokens = new StringTokenizer (msgreceived ")에 참여할 때입니다. 문자열 usertoken; 문자열 gamecreatorname; 문자열 gamepaticipantName; 문자열 [] 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 = playername [1]; if (chesspeerhash.containskey (gamecreatorname) && chesspeerhash.get (gamecreatorname) .equals ( "wait")) {// 게임이 동기화되었습니다 (clientnamehash) {// 해당 클라이언트를 추가했습니다 (clisendsets, ( "inackess]" + gamepaticipantname) } synchronized (chesspeerhash) {// 해당 Chesspeerhash.put (gamecreatorname, gamepaticipantname)을 추가하거나 수정합니다. } sendpublicmsg (getUserList ()); // 게임에 메시지를 보내는 사람 SendGamepeermsg (GamePaticiPantName, ( "/peer" + "[inchess]" + GameCreatorName); // 게임을 게임 제작자 SendGamePeermsg (GameCreatorName, ( "/peer" + "[incess]" + GamePaticiPantName)으로 보냅니다. } else {// 게임이 생성되지 않으면 게임이 추가되기를 거부합니다 (GamePaticiPantName, "/Reject"); try {closeClient (); } catch (예외 ez) {ez.printstacktrace (); }}} else if (msgreceived.startSwith ( "/[inchess]")) {// 수신 된 메시지는 int firstLocation = 0, lastLocation; lastlocation = msgreceived.indexof ( "", 0); perername = msgreceived.substring ((FirstLocation + 1), lastlocation); msgreceived = msgreceived.SubString ((lastLocation + 1)); if (sendgamepeermsg (peername, msgreceived)) {피드백 ( "/error"); }} else if (msgreceived.startSwith ( "/powup")) {// 수신 된 메시지는 게임 문자열을 포기할 때입니다. chessclientName = msgreceived.substring (8); if (chesspeerhash.containskey (chessclientName) &&! ((String) chesspeerhash.get (chessclientName)) synchronized (chesspeerhash) {// 사용자가 게임을 종료 한 chesspeerhash.remove (chessclientName); }} if (chesspeerhash.containsvalue (chessclientName)) {// 우승자는 게임 제작자이며 승리 메시지를 보냅니다 ((String) gethashkey (Chesspeerhash, ChessclientName), "/youwin"); Synchronized (Chesspeerhash) {// 사용자가 게임을 종료 한 chesspeerhash.remove ((String) gethashkey (Chesspeerhash, ChessclientName); }}} else {// 수신 된 정보가 다른 정보 인 경우 int lastlocation = msgreceived.indexof ( "", 0); if (lastLocation == -1) {피드백 ( "invalid 명령"); 반품; }}} else {msgreceived = clientnamehash.get (clientsocket) + ">" + 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.Element (); enu .HasMoreElements ();) {dataOutputStream outputData = (dataOutputStream) ENU.NEXTELENT (); try {outputdata.writeutf (publicmsg); } catch (ioexception es) {es.printstacktrace (); }}}}} // 지정된 게임에서 사용자에게 정보를 보낸다. public boolean sendgamepeermsg (string gamepeertarget, string string gamepeermsg) {for (enumeration enu = clientDataHash.keys (); enu.hasmoreElements () {// terverse in the userclients = (socket in the useetlient)의 소켓을 얻습니다. enu.nextelement (); if (gamepeertArget.equals ((String) ClientNameHash.get (userClient))) &&! gamePeertArget.equals ((String) ClientNameHash .get (clientsocket))) {// output Stream DataOutputStream PeerOutData = (DataOutStrem) (사용자 datahash); {// 정보 보내기 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.开发服务器端
import 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.*; 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; // 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; 진실을 반환하십시오. } 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 ")) { // 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을 더 지원하기를 바랍니다.