?? omokserver.java
字號:
import java.net.*;
import java.io.*;
import java.util.*;
public class OmokServer {
private ServerSocket server;
private BManager bMan = new BManager(); //消息廣播者
private Random rnd = new Random(); //隨機確定黑棋或白棋
public OmokServer() {
}
void startServer() { //啟動服務器
try {
server = new ServerSocket(7777);
System.out.println("服務器套接字已被創建");
while (true) {
//獲取與客戶端連接的套接字
Socket socket = server.accept();
//創建并啟動線程
Omok_Thread ot = new Omok_Thread(socket);
ot.start();
//向bMain添加線程
bMan.add(ot);
System.out.println("連接數:" + bMan.size());
}
} catch (Exception e) {
System.out.println(e);
}
}
public static void main(String[] args) {
OmokServer server = new OmokServer();
server.startServer();
}
//負責與客戶端通信的線程類
class Omok_Thread extends Thread {
private int roomNumber = -1;
private String userName = null; //用戶名
private Socket socket; //套接字
//游戲準備是否就緒
private boolean ready = false;
private BufferedReader reader;
private PrintWriter writer;
Omok_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);
} //若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));
}
//若msg以【START】開始
else if (msg.startsWith("[START]")) {
//游戲開始準備完畢
ready = true;
//若其他用戶也做好了游戲開始的準備
if (bMan.isReady(roomNumber)) {
//確定黑子與白子并向用戶及對手傳送
int a = rnd.nextInt(2);
if (a == 0) {
writer.println("[COLOR]BLACK");
bMan.sendToOthers(this, "[COLOR]WHITE");
} else {
writer.println("[COLOR]WHITE");
bMan.sendToOthers(this, "[COLOR]BLACK");
}
}
}
//若用戶發送終止游戲的消息
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) {
e.printStackTrace();
} 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(Omok_Thread ot) {
super.add(ot);
}
void remove(Omok_Thread ot) {
super.remove(ot);
}
//獲取第i個線程
Omok_Thread getOT(int i) {
return (Omok_Thread) elementAt(i);
}
//獲取第i個線程的套接字
Socket getSocket(int 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) {
}
}
//獲取第i個線程的房間號
int getRoomNumber(int 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(Omok_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();
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -