📄 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 + -