대망의 하이라이트 소켓 통신 부분입니다.


client

package Socket_pkg;

import java.awt.*;
import java.net.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;

import Login_pkg.*;
import Puzzle_pkg.*;
import Ranking_pkg.*;

class PuzzleBoard extends Container {

	private boolean running = false; // 게임이 진행 중인가를 나타내는 변수

	private PrintWriter writer; // 상대편에게 메시지를 전달하기 위한 스트림
	private JButton changebtn; // 빈칸과 바꿀 칸 변경
	private JButton[][] numbtn = new JButton[4][4]; // 15 까지의 버튼
	private int[][] numcount = new int[4][4]; // 15까지의 숫자
	private int row = 0, col = 0;
	private int getrownum = 0, getcolnum = 0;
	protected static String timerBuffer; // 경과 시간 문자열이 저장될 버퍼 정의

	public PuzzleBoard() {
		
		// 배치
		setSize(480, 480);
		setLayout(new GridLayout(4, 4));

		int k = 1;
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				numbtn[i][j] = new JButton(String.valueOf(k));
				numbtn[i][j].setFont(new Font("굴림체", Font.BOLD, 30));
				add(numbtn[i][j]);
				numbtn[i][j].addKeyListener(new MyKeyListener());
				k++;
			}
		}

		setVisible(false);
		getNum();
		display();
	}

	// 0~16 난수발생
	public void getNum() {
		int[] num = new int[16];
		int n = 0;
		boolean Check = false;
		for (int i = 0; i < 16; i++) {
			Check = true;
			while (Check) {
				n = (int) (Math.random() * 16);
				Check = false;
				for (int j = 0; j < i; j++) {
					if (n == num[j]) // 같은 수 저장 방지
					{
						Check = true;
						break;
					}
				}
			}
			num[i] = n;
			numcount[i / 4][i % 4] = n;
			if (n == 15) { // 랜덤 칸 생성
				row = i / 4;
				col = i % 4;
			}

		}
	}

	// 디스플레이
	public void display() {

		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				if (i == row && j == col) {
					numbtn[i][j].setText(String.valueOf(""));

					numbtn[i][j].setEnabled(false);
				} else {
					System.out.println("numcount[" + i + "]" + "[" + j + "] " + numcount[i][j] + " ");
					numbtn[i][j].setText(String.valueOf(numcount[i][j] + 1));
					numbtn[i][j].setEnabled(true);
				}
			}
		}
	}

	// 종료 여부 확인 numbtn 과 k 가 같으면 종료
	public boolean isEnd() {

		int k = 1;
		try {
			for (int i = 0; i < 4; i++) {
				for (int j = 0; j < 4; j++) {
					if (Integer.parseInt(numbtn[i][j].getText()) != k)
						return false;
					System.out.println("k :" + k);
					k++;
				}
			}
		} catch (NumberFormatException e) {

		}

		if (k == 15)
			return true;

		return false;

	}

	private class MyKeyListener extends KeyAdapter {

		public void keyPressed(KeyEvent e) {

			boolean isEnd = false;
			char keyCode = e.getKeyChar();
			switch (keyCode) {
			case 'w':
				if (row == 0) {
					break;
				} else {
					changebtn = numbtn[row - 1][col]; // 변경할 위 버튼
					numbtn[row][col].setText(String.valueOf(changebtn.getText())); // 변경할 버튼 입력
					numbtn[row][col].setEnabled(true);

					setrow(row);
					setcol(col);
					row = row - 1; // 위에를 다시 가리킴

					changebtn = numbtn[row][col]; // 빈칸 버튼 지정
					numbtn[row][col].setText("");
					numbtn[row][col].setEnabled(false);

					if (isEnd()) {

						writer.println("[WIN]");

					}
					break;
				}

			case 's':
				if (row == 3) {
					break;
				} else {
					changebtn = numbtn[row + 1][col];
					numbtn[row][col].setText(String.valueOf(changebtn.getText()));
					System.out.println("row : " + row + " col : " + col);
					numbtn[row][col].setEnabled(true);

					setrow(row);
					setcol(col);
					row = row + 1;

					changebtn = numbtn[row][col];
					numbtn[row][col].setText("");
					numbtn[row][col].setEnabled(false);

					if (isEnd()) {

						writer.println("[WIN]");

					}

					break;
				}
			case 'd':
				if (col == 3) {
					break;
				} else {
					changebtn = numbtn[row][col + 1];
					numbtn[row][col].setText(String.valueOf(changebtn.getText()));
					System.out.println("row : " + row + " col : " + col);
					numbtn[row][col].setEnabled(true);

					setrow(row);
					setcol(col);
					col = col + 1;

					changebtn = numbtn[row][col];
					numbtn[row][col].setText("");
					numbtn[row][col].setEnabled(false);

					if (isEnd()) {

						writer.println("[WIN]");

					}
				}
				break;
			case 'a':
				if (col == 0) {
					break;
				} else {
					changebtn = numbtn[row][col - 1];
					numbtn[row][col].setText(String.valueOf(changebtn.getText()));
					System.out.println("row : " + row + " col : " + col);
					numbtn[row][col].setEnabled(true);

					setrow(row);
					setcol(col);
					col = col - 1;

					changebtn = numbtn[row][col];
					numbtn[row][col].setText("");
					numbtn[row][col].setEnabled(false);

					if (isEnd()) {

						writer.println("[WIN]");

					}

					break;
				}
			}
		}

	}

	public int setrow(int row) {
		getrownum = row;
		return getrownum;
	}

	public int getrow() {
		return getrownum;
	}

	public int setcol(int col) {
		getcolnum = col;
		return getcolnum;
	}

	public int getcol() {
		return getcolnum;
	}



	public static String getTimes() {
		return timerBuffer;
	}

	public boolean isRunning() { // 게임의 진행 상태를 반환한다.

		return running;

	}

	public void startGame(String col) { // 게임을 시작한다.

		running = true;

	}

	public void stopGame() { // 게임을 멈춘다.

		writer.println("[STOPGAME]"); // 상대편에게 메시지를 보낸다.

		running = false;

	}

	public void setWriter(PrintWriter writer) {

		this.writer = writer;

	}

}

public class PuzzleClient extends Frame implements Runnable, ActionListener {

	private TextArea msgView = new TextArea("", 1, 1, 1); // 메시지를 보여주는 영역

	private TextField sendBox = new TextField(""); // 보낼 메시지를 적는 상자

	private TextField nameBox = new TextField(); // 사용자 이름 상자

	private TextField roomBox = new TextField(""); // 방 번호 상자

	// 방에 접속한 인원의 수를 보여주는 레이블

	private Label pInfo = new Label("대기실:  명");

	private java.awt.List pList = new java.awt.List(); // 사용자 명단을 보여주는 리스트

	private Button startButton = new Button("게임 시작"); // 시작 버튼

	private Button stopButton = new Button("기권"); // 기권 버튼

	private Button enterButton = new Button("입장하기"); // 입장하기 버튼

	private Button exitButton = new Button("대기실로"); // 대기실로 버튼

	private Button SignUpButton = new Button("회원가입");
	
	private Button RankButton = new Button("랭킹");

	private PuzzleBoard puzzleBoard = new PuzzleBoard(); // Puzzle 화면

	private Ranking_WindowBuilder ranking = new Ranking_WindowBuilder();
	private PuzzleDB Pdb = new PuzzleDB();

	// 각종 정보를 보여주는 레이블

	private Label infoView = new Label("퍼즐 게임", 1);

	private BufferedReader reader; // 입력 스트림

	private PrintWriter writer; // 출력 스트림

	private Socket socket; // 소켓

	private int roomNumber = -1; // 방 번호

	private String userName = null; // 사용자 이름
	
	private static int oldTime; // 타이머 시작 시각을 기억하고 있는 변수
	protected static String timerBuffer; // 경과 시간 문자열이 저장될 버퍼 정의

	public PuzzleClient(String title) { // 생성자

		super(title);

		setLayout(null); // 레이아웃을 사용하지 않는다.

		// 각종 컴포넌트를 생성하고 배치한다.

		msgView.setEditable(false);

		infoView.setBounds(10, 30, 480, 30);

		infoView.setBackground(new Color(200, 200, 255));

		puzzleBoard.setLocation(10, 70);

		add(infoView);

		add(puzzleBoard);

		Panel p = new Panel();

		p.setBackground(new Color(200, 255, 255));

		p.setLayout(new GridLayout(4, 4));

		p.add(new Label("이     름:", 2));
		p.add(nameBox);

		p.add(new Label("방 번호:", 2));
		p.add(roomBox);

		p.add(enterButton);
		p.add(exitButton);
		p.add(SignUpButton);
		p.add(RankButton);

		enterButton.setEnabled(false);

		p.setBounds(500, 30, 250, 70);

		Panel p2 = new Panel();

		p2.setBackground(new Color(255, 255, 100));

		p2.setLayout(new BorderLayout());

		Panel p2_1 = new Panel();

		p2_1.add(startButton);
		p2_1.add(stopButton);

		p2.add(pInfo, "North");
		p2.add(pList, "Center");
		p2.add(p2_1, "South");

		startButton.setEnabled(false);
		stopButton.setEnabled(false);

		p2.setBounds(500, 110, 250, 180);

		Panel p3 = new Panel();

		p3.setLayout(new BorderLayout());

		p3.add(msgView, "Center");

		p3.add(sendBox, "South");

		p3.setBounds(500, 300, 250, 250);

		add(p);
		add(p2);
		add(p3);

		// 이벤트 리스너를 등록한다.

		sendBox.addActionListener(this);

		enterButton.addActionListener(this);

		exitButton.addActionListener(this);

		SignUpButton.addActionListener(this);
		
		RankButton.addActionListener(this);

		startButton.addActionListener(this);

		stopButton.addActionListener(this);

		// 윈도우 닫기 처리

		addWindowListener(new WindowAdapter() {

			public void windowClosing(WindowEvent we) {

				System.exit(0);

			}

		});

	}

	// 컴포넌트들의 액션 이벤트 처리

	public void actionPerformed(ActionEvent ae) {

		if (ae.getSource() == sendBox) { // 메시지 입력 상자이면

			String msg = sendBox.getText();

			if (msg.length() == 0)
				return;

			if (msg.length() >= 30)
				msg = msg.substring(0, 30);

			try {

				writer.println("[MSG]" + msg);

				sendBox.setText("");

			} catch (Exception ie) {
			}

		}

		else if (ae.getSource() == enterButton) { // 입장하기 버튼이면

			try {

				if (Integer.parseInt(roomBox.getText()) < 1) {

					infoView.setText("방번호가 잘못되었습니다. 1이상");

					return;

				}

				writer.println("[ROOM]" + Integer.parseInt(roomBox.getText()));

				msgView.setText("");

			} catch (Exception ie) {

				infoView.setText("입력하신 사항에 오류가 았습니다.");

			}

		}

		else if (ae.getSource() == exitButton) { // 대기실로 버튼이면

			try {

				goToWaitRoom();

				startButton.setEnabled(false);

				stopButton.setEnabled(false);
				
				SignUpButton.setEnabled(false);

			} catch (Exception e) {
			}

		}
		
		else if (ae.getSource() == SignUpButton) { // 회원가입 버튼이면
			
			Login_WindowBuilder login = new Login_WindowBuilder();
			login.frame.setVisible(true); login.frame.setResizable(false);
			
		}
		
		else if (ae.getSource() == RankButton) { // 랭킹 버튼이면
			
			ranking.setVisible(true);
			
		}

		else if (ae.getSource() == startButton) { // 게임 시작 버튼이면
		
			
			
			try {
				
				writer.println("[START]");

				infoView.setText("상대의 결정을 기다립니다.");

				startButton.setEnabled(false);
				
			} catch (Exception e) {
			}
			
		}

		else if (ae.getSource() == stopButton) { // 기권 버튼이면

			try {

				writer.println("[DROPGAME]");

				endGame("기권하였습니다.");

				puzzleBoard.setVisible(false);

			} catch (Exception e) {
			}

		}

	}

	void goToWaitRoom() { // 대기실로 버튼을 누르면 호출된다.

		String name = nameBox.getText().trim();

		LoginDB ldb = new LoginDB();

		System.out.println(ldb.LoginOX(new LoginData(name)));
		if (ldb.LoginOX(new LoginData(name)) == 1) {

			userName = name;

			writer.println("[NAME]" + userName);

			nameBox.setText(userName);

			nameBox.setEditable(false);

			msgView.setText("");

			writer.println("[ROOM]0");

			infoView.setText("대기실에 입장하셨습니다.");

			roomBox.setText("0");

			enterButton.setEnabled(true);

			exitButton.setEnabled(false);

		}

		else {
			JOptionPane.showMessageDialog(null, "등록되지 않은 ID입니다.");
		}

	}

	public void run() {

		String msg; // 서버로부터의 메시지

		try {

			while ((msg = reader.readLine()) != null) {

				if (msg.startsWith("[STONE]")) { // 상대편이 움직인 위치의 좌표

					String temp = msg.substring(7);

					int x = Integer.parseInt(temp.substring(0, puzzleBoard.getrow()));

					int y = Integer.parseInt(temp.substring(0, puzzleBoard.getcol()));

				}

				else if (msg.startsWith("[ROOM]")) { // 방에 입장

					if (!msg.equals("[ROOM]0")) { // 대기실이 아닌 방이면

						enterButton.setEnabled(false);

						exitButton.setEnabled(true);

						infoView.setText(msg.substring(6) + "번 방에 입장하셨습니다.");

					}

					else
						infoView.setText("대기실에 입장하셨습니다.");

					roomNumber = Integer.parseInt(msg.substring(6)); // 방 번호 지정

					if (puzzleBoard.isRunning()) { // 게임이 진행중인 상태이면

						puzzleBoard.stopGame(); // 게임을 중지시킨다.

					}

				}

				else if (msg.startsWith("[FULL]")) { // 방이 찬 상태이면

					infoView.setText("방이 차서 입장할 수 없습니다.");

				}

				else if (msg.startsWith("[PLAYERS]")) { // 방에 있는 사용자 명단

					nameList(msg.substring(9));

				}

				else if (msg.startsWith("[ENTER]")) { // 손님 입장

					pList.add(msg.substring(7));

					playersInfo();

					msgView.append("[" + msg.substring(7) + "]님이 입장하였습니다.\n");

				}

				else if (msg.startsWith("[EXIT]")) { // 손님 퇴장

					pList.remove(msg.substring(6)); // 리스트에서 제거

					playersInfo(); // 인원수를 다시 계산하여 보여준다.

					msgView.append("[" + msg.substring(6) +

							"]님이 다른 방으로 입장하였습니다.\n");

					if (roomNumber != 0)

						endGame("상대가 나갔습니다.");

				}

				else if (msg.startsWith("[DISCONNECT]")) { // 손님 접속 종료

					pList.remove(msg.substring(12));

					playersInfo();

					msgView.append("[" + msg.substring(12) + "]님이 접속을 끊었습니다.\n");

					if (roomNumber != 0)

						endGame("상대가 나갔습니다.");

				}

				else if (msg.startsWith("[READY]")) {
					String str = msg.substring(7);
					puzzleBoard.startGame(str);
					
					if (str.equals("사용자1")) {
						infoView.setText("게임시작");
						puzzleBoard.requestFocus();
						puzzleBoard.setVisible(true);
					} else {
						infoView.setText("게임시작");
						puzzleBoard.requestFocus();
						puzzleBoard.setVisible(true);
					}
					stopwatch(1);
					stopButton.setEnabled(true);
				}

				else if (msg.startsWith("[DROPGAME]")) { // 상대가 기권하면
					
					endGame("상대가 기권하였습니다.");
					puzzleBoard.setVisible(false);
				}

				else if (msg.startsWith("[WIN]")) { // 이겼으면
					stopwatch(0);
					endGame("이겼습니다.");
					puzzleBoard.setVisible(false);
					Pdb.InsertPuzzleDB(new PuzzleData(nameBox.getText().trim(), getTimes()));
					ranking.select(); // 중첩으로 나옴 변경해야됨
				}

				else if (msg.startsWith("[LOSE]")) { // 졌으면

					endGame("졌습니다.");
					puzzleBoard.setVisible(false);
				}

				// 약속된 메시지가 아니면 메시지 영역에 보여준다.

				else
					msgView.append(msg + "\n");

			}

		} catch (IOException ie) {

			msgView.append(ie + "\n");

		}

		msgView.append("접속이 끊겼습니다.");
		

	}

	private void endGame(String msg) { // 게임의 종료시키는 메소드

		infoView.setText(msg);

		startButton.setEnabled(false);

		stopButton.setEnabled(false);

		try {
			Thread.sleep(2000);
		} catch (Exception e) {
		} // 2초간 대기

		if (puzzleBoard.isRunning())
			puzzleBoard.stopGame();

		if (pList.getItemCount() == 2)
			startButton.setEnabled(true);

	}

	private void playersInfo() { // 방에 있는 접속자의 수를 보여준다.

		int count = pList.getItemCount();

		if (roomNumber == 0)

			pInfo.setText("대기실: " + count + "명");

		else
			pInfo.setText(roomNumber + " 번 방: " + count + "명");

		// 대국 시작 버튼의 활성화 상태를 점검한다.

		if (count == 2 && roomNumber != 0)

			startButton.setEnabled(true);

		else
			startButton.setEnabled(false);

	}

	// 사용자 리스트에서 사용자들을 추출하여 pList에 추가한다.

	private void nameList(String msg) {

		pList.removeAll();

		StringTokenizer st = new StringTokenizer(msg, "\t");

		while (st.hasMoreElements())

			pList.add(st.nextToken());

		playersInfo();

	}

	private void connect() { // 연결

		try {

			msgView.append("서버에 연결을 요청합니다.\n");

			socket = new Socket("127.0.0.1", 7777);

			msgView.append("---연결 성공--.\n");

			msgView.append("이름을 입력하고 대기실로 입장하세요.\n");

			reader = new BufferedReader(

					new InputStreamReader(socket.getInputStream()));

			writer = new PrintWriter(socket.getOutputStream(), true);

			new Thread(this).start();

			puzzleBoard.setWriter(writer);

		} catch (Exception e) {

			msgView.append(e + "\n\n연결 실패..\n");

		}
		
		

	}
	
	
	public static void stopwatch(int onOff) {
		if (onOff == 1) // 타이머 on
			oldTime = (int) System.currentTimeMillis() / 1000;

		if (onOff == 0) // 타이머 off, 시분초 timerBuffer 에 저장
			secToHHMMSS(((int) System.currentTimeMillis() / 1000) - oldTime);

	}

	// 정수로 된 시간을 초단위(sec)로 입력 받고, 문자열로 시분초를 저장
	public static void secToHHMMSS(int secs) {
		int hour, min, sec;

		sec = secs % 60;
		min = secs / 60 % 60;
		hour = secs / 3600;

		timerBuffer = String.format("%02d%02d%02d", hour, min, sec);
		System.out.println(timerBuffer);
	}
	
	public static String getTimes() {
		return timerBuffer;
	}

	public static void main(String[] args) {

		PuzzleClient client = new PuzzleClient("네트워크 퍼즐게임");

		client.setSize(760,560);

		client.setVisible(true);

		client.connect();

	}

}

Server

package Socket_pkg;

import java.net.*;

import java.io.*;

import java.util.*;

public class PuzzleServer {

	private ServerSocket server;

	private BManager bMan = new BManager(); // 메시지 방송자

	private Random rnd = new Random();

	public PuzzleServer() {
	}

	void startServer() { // 서버를 실행한다.

		try {

			server = new ServerSocket(7777);

			System.out.println("서버소켓이 생성되었습니다.");

			while (true) {

				// 클라이언트와 연결된 스레드를 얻는다.

				Socket socket = server.accept();

				// 스레드를 만들고 실행시킨다.

				Puzzle_Thread ot = new Puzzle_Thread(socket);

				ot.start();

				// bMan에 스레드를 추가한다.

				bMan.add(ot);

				System.out.println("접속자 수: " + bMan.size());

			}

		} catch (Exception e) {

			System.out.println(e);

		}

	}

	// 클라이언트와 통신하는 스레드 클래스

	class Puzzle_Thread extends Thread {

		private int roomNumber = -1; // 방 번호

		private String userName = null; // 사용자 이름

		private Socket socket; // 소켓

		// 게임 준비 여부, true이면 게임을 시작할 준비가 되었음을 의미한다.

		private boolean ready = false;

		private BufferedReader reader; // 입력 스트림

		private PrintWriter writer; // 출력 스트림

		Puzzle_Thread(Socket socket) { // 생성자

			this.socket = socket;

		}

		Socket getSocket() { // 소켓을 반환한다.

			return socket;

		}

		int getRoomNumber() { // 방 번호를 반환한다.

			return roomNumber;

		}

		String getUserName() { // 사용자 이름을 반환한다.

			return userName;

		}

		boolean isReady() { // 준비 상태를 반환한다.

			return ready;

		}

		public void run() {

			try {

				reader = new BufferedReader(

						new InputStreamReader(socket.getInputStream()));

				writer = new PrintWriter(socket.getOutputStream(), true);

				String msg; // 클라이언트의 메시지

				while ((msg = reader.readLine()) != null) {

					// msg가 "[NAME]"으로 시작되는 메시지이면

					if (msg.startsWith("[NAME]")) {

						userName = msg.substring(6); // userName을 정한다.

					}

					// msg가 "[ROOM]"으로 시작되면 방 번호를 정한다.

					else if (msg.startsWith("[ROOM]")) {

						int roomNum = Integer.parseInt(msg.substring(6));

						if (!bMan.isFull(roomNum)) { // 방이 찬 상태가 아니면

							// 현재 방의 다른 사용에게 사용자의 퇴장을 알린다.

							if (roomNumber != -1)

								bMan.sendToOthers(this, "[EXIT]" + userName);

							// 사용자의 새 방 번호를 지정한다.

							roomNumber = roomNum;

							// 사용자에게 메시지를 그대로 전송하여 입장할 수 있음을 알린다.

							writer.println(msg);

							// 사용자에게 새 방에 있는 사용자 이름 리스트를 전송한다.

							writer.println(bMan.getNamesInRoom(roomNumber));

							// 새 방에 있는 다른 사용자에게 사용자의 입장을 알린다.

							bMan.sendToOthers(this, "[ENTER]" + userName);

						}

						else
							writer.println("[FULL]"); // 사용자에 방이 찼음을 알린다.

					}

					// "[STONE]" 메시지는 상대편에게 전송한다.

					else if (roomNumber >= 1 && msg.startsWith("[STONE]"))

						bMan.sendToOthers(this, msg);

					// 대화 메시지를 방에 전송한다.

					else if (msg.startsWith("[MSG]"))

						bMan.sendToRoom(roomNumber,

								"[" + userName + "]: " + msg.substring(5));

					// "[START]" 메시지이면

					else if (msg.startsWith("[START]")) {

						ready = true; // 게임을 시작할 준비가 되었다.

						// 다른 사용자도 게임을 시작한 준비가 되었으면

						if (bMan.isReady(roomNumber)) {

							int a = rnd.nextInt(2);

							if (a == 0) {
								writer.println("[READY]사용자1");

								bMan.sendToOthers(this, "[READY]사용자2");
							}

							else {
								writer.println("[READY]사용자2");

								bMan.sendToOthers(this, "[READY]사용자1");
							}

						}

					}

					// 사용자가 게임을 중지하는 메시지를 보내면

					else if (msg.startsWith("[STOPGAME]"))

						ready = false;

					// 사용자가 게임을 기권하는 메시지를 보내면

					else if (msg.startsWith("[DROPGAME]")) {

						ready = false;

						// 상대편에게 사용자의 기권을 알린다.

						bMan.sendToOthers(this, "[DROPGAME]");

					}

					// 사용자가 이겼다는 메시지를 보내면

					else if (msg.startsWith("[WIN]")) {

						ready = false;

						// 사용자에게 메시지를 보낸다.

						writer.println("[WIN]");

						// 상대편에는 졌음을 알린다.

						bMan.sendToOthers(this, "[LOSE]");

					}

				}

			} catch (Exception e) {

			} finally {

				try {

					bMan.remove(this);

					if (reader != null)
						reader.close();

					if (writer != null)
						writer.close();

					if (socket != null)
						socket.close();

					reader = null;
					writer = null;
					socket = null;

					System.out.println(userName + "님이 접속을 끊었습니다.");

					System.out.println("접속자 수: " + bMan.size());

					// 사용자가 접속을 끊었음을 같은 방에 알린다.

					bMan.sendToRoom(roomNumber, "[DISCONNECT]" + userName);

				} catch (Exception e) {
				}

			}

		}

	}

	class BManager extends Vector { // 메시지를 전달하는 클래스

		BManager() {
		}

		void add(Puzzle_Thread ot) { // 스레드를 추가한다.

			super.add(ot);

		}

		void remove(Puzzle_Thread ot) { // 스레드를 제거한다.

			super.remove(ot);

		}

		Puzzle_Thread getOT(int i) { // i번째 스레드를 반환한다.

			return (Puzzle_Thread) elementAt(i);

		}

		Socket getSocket(int i) { // i번째 스레드의 소켓을 반환한다.

			return getOT(i).getSocket();

		}

		// i번째 스레드와 연결된 클라이언트에게 메시지를 전송한다.

		void sendTo(int i, String msg) {

			try {

				PrintWriter pw = new PrintWriter(getSocket(i).getOutputStream(), true);

				pw.println(msg);

			} catch (Exception e) {
			}

		}

		int getRoomNumber(int i) { // i번째 스레드의 방 번호를 반환한다.

			return getOT(i).getRoomNumber();

		}

		synchronized boolean isFull(int roomNum) { // 방이 찼는지 알아본다.

			if (roomNum == 0)
				return false; // 대기실은 차지 않는다.

			// 다른 방은 2명 이상 입장할 수 없다.

			int count = 0;

			for (int i = 0; i < size(); i++)

				if (roomNum == getRoomNumber(i))
					count++;

			if (count >= 2)
				return true;

			return false;

		}

		// roomNum 방에 msg를 전송한다.

		void sendToRoom(int roomNum, String msg) {

			for (int i = 0; i < size(); i++)

				if (roomNum == getRoomNumber(i))

					sendTo(i, msg);

		}

		// ot와 같은 방에 있는 다른 사용자에게 msg를 전달한다.

		void sendToOthers(Puzzle_Thread ot, String msg) {

			for (int i = 0; i < size(); i++)

				if (getRoomNumber(i) == ot.getRoomNumber() && getOT(i) != ot)

					sendTo(i, msg);

		}

		// 게임을 시작할 준비가 되었는가를 반환한다.

		// 두 명의 사용자 모두 준비된 상태이면 true를 반환한다.

		synchronized boolean isReady(int roomNum) {

			int count = 0;

			for (int i = 0; i < size(); i++)

				if (roomNum == getRoomNumber(i) && getOT(i).isReady())

					count++;

			if (count == 2)
				return true;

			return false;

		}

		// roomNum방에 있는 사용자들의 이름을 반환한다.

		String getNamesInRoom(int roomNum) {

			StringBuffer sb = new StringBuffer("[PLAYERS]");

			for (int i = 0; i < size(); i++)

				if (roomNum == getRoomNumber(i))

					sb.append(getOT(i).getUserName() + "\t");

			return sb.toString();

		}

	}

	public static void main(String[] args) {

		PuzzleServer server = new PuzzleServer();

		server.startServer();

	}

}

실행결과

서버 생성 후 접속자 연결
Client GUI 화면
이름 입력 후 대기실 버튼 클릭 화면
방 입장 후 게임 시작 화면


Part 1. 로그인 바로가기
Part 2. 퍼즐 바로가기
Part 3. 랭킹 바로가기

전체 소스코드 바로가기

 

 

참고 바로가기

+ Recent posts