📄 j_fir_server.java
字号:
//服务器端类
import javax.swing.*;
import java.awt.Container;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;
import java.awt.BorderLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
public class J_FIR_Server extends JFrame
{
////////////////////////////////////////////////////////////////////////////////////
private static int MAX_CLIENT_NUM = 50; //最大客户连接数
private ObjectInputStream[] m_input = new ObjectInputStream[MAX_CLIENT_NUM]; //输出流
private ObjectOutputStream[] m_output = new ObjectOutputStream[MAX_CLIENT_NUM]; //输入流
private JTextArea m_display; //显示信息
private int m_clientNumber = 0; //当前连接数
private int[] MatchedClient = new int[MAX_CLIENT_NUM];
//MatchedClient[i]=-1表示没有对手,否则表示对手的编号
private int[] SideChosen = new int[MAX_CLIENT_NUM];
//已经选择黑白棋
private boolean[] ClientOccupied = new boolean[MAX_CLIENT_NUM];
//客户i是否被占用
private boolean[] SideDecided = new boolean[MAX_CLIENT_NUM];
//true表示已经选定黑白棋
private boolean[] SideQSent = new boolean[MAX_CLIENT_NUM];
//true表示已经向该发送选择黑白棋的询问
private boolean[] isReplaying = new boolean[MAX_CLIENT_NUM];
//true表示正在对局
private boolean[] TransportationFinished = new boolean[MAX_CLIENT_NUM];
//供"续下"模式使用,true表示数据传送完毕
private String[] userName = new String[MAX_CLIENT_NUM];
//用户名
private String[] Response = new String[MAX_CLIENT_NUM];
//表示是否有回复及回复内容(用于选棋)
//下面的字符串的意思大体可以从其内容看出,不详细介绍了,用作传输数据的筛选
private String EXIT_NAME = "_EXIT_EXIT_";
private String PLAYING_COMMAND = "_This_is_the_playing_command_";
private String RESTART_COMMAND = "_Restart_Restart_Restart!!!";
private String NAME_COMMAND = "_This_is_my_name...Hello_World!_";
private String NAME_LIST = "_%_ANOTHER_";
private String NAME_LIST_RESPONSE = "_These_are_the_players_online_:-)_";
private String OPPONENT_COMMAND = "_May_I_play_with_you?_";
private String FIND_REQUEST = "_Please_show_me_who_are_online_";
private String REQUEST_REJECTED = "_Sorry_I_am_busy_now!_";
private String REQUEST_ACCEPTED = "_OK_I_accept_your_invitation!_";
private String SIDE_DECISION = "_Do_you_like_black_or_white?_";
private String SIDE_COLOR = "_Use_this_Color:_";
private String YOUR_TURN = "_It_is_your_turn_now!_";
private String PLAY_REQUEST = "_Let's_play_!!!_";
private String WELCOME_INFO = "_Welcom_to_the_world_of_Five_In_Row!_";
private String NO_RESPONSE = "_This_guy_has_not_replied_yet.What_should_we_do?_";
private String WINNER_DECIDED = "_Winner_comes_out!_";
private String I_WANT_TO_GO = "_I_WANNA_GO_NOW._SEE_YOU~_";
private String PLAY_AGAIN = "_HAVE_ANOTHER_GAME,OK?_";
private String EXIT_SERVER = "_I'd_like_to_exit_the_server._";
private String REPLAYING_GAME = "_I'm_watching_the_replay._Don't_disturb_me._";
private String EXIT_REPLAY = "_Now_I_have_exited_the_replay_mode._I'm_back._";
private String DROP_LINE = "_Your_opponent_has_dropped_out_of_the_line._you_win!_";
private String CONTINUE_REQUEST = "_May_I_continue_this_game_with_you?_";
private String STEP_NUM = "_There_are_so_many_steps_in_my_file._";
private String STEP_CONTENT = "_The_position_of_chessmen_in_each_step_is:_";
private String DATA_RECEIVING_COMPLETED = "_I_have_received_all_saved_data_now._";
private String I_REGRET = "_I_regret_my_last_step._";
private String REGRET_AS_YOU_LIKE = "_You_may_get_back_your_last_step._";
private String NO_REGRET = "_You_cannot_regret_anyway._";
//////////////////////////////////////////////////////////////////////////////////////
public J_FIR_Server() //构造函数
{
super("五子棋游戏服务器端");
Container c = getContentPane();
m_display = new JTextArea(); //文本域,显示各种信息,可用于调试
c.add(new JScrollPane(m_display),BorderLayout.CENTER);
}
public void mb_displayAppend(String s) //从书上继承的,在文本域追加信息
{
m_display.append(s+"\n");
m_display.setCaretPosition(m_display.getText().length());
//m_enter.requestFocusInWindow();
}
public void mb_run() //主要运行过程
{
try
{
ServerSocket server = new ServerSocket(5000);
int i;
for (i=0;i<MAX_CLIENT_NUM;i++) {
ClientOccupied[i] = false;
MatchedClient[i] = -1;
} //初始化
while (true)
{
mb_displayAppend("服务器就绪\n等待连接中...");
while (true) {
Socket s = server.accept();
if (m_clientNumber<MAX_CLIENT_NUM) {
for (i=0; i<MAX_CLIENT_NUM; i++)
if (!ClientOccupied[i]) {
new ClientThread(s,i);
m_clientNumber++;
break;
}
//寻找空闲的"客户位"
} else {
mb_displayAppend("服务器已满!");
}
}
/*m_output.close();
m_input.close();
s.close();
mb_displayAppend("连接["+m_clientNumber+"]结束"); */
}
}
catch (Exception e)
{
System.err.println("发生异常:"+e);
e.printStackTrace();
mb_displayAppend("连接["+m_clientNumber+"]发生异常");
}
}
class ClientThread extends Thread //为客户端建的线程
{
private Socket s;
private int Code;
private boolean FindOne;
public ClientThread(Socket soc,int Num) throws IOException
{
Code = Num;
mb_displayAppend("接收到客户端连接["+Code+"]");
s = soc;
m_output[Code] = new ObjectOutputStream(s.getOutputStream());
m_input[Code] = new ObjectInputStream(s.getInputStream());
//为每个客户配置输入输出流
start(); //启动线程
}
public void run()
{
String str;
StringBuffer mBuf;
//信息均用以上两个变量进行处理,str用equals,mBuf用indexOf匹配关键字
int i,u,v; //临时变量,u,v后来分别代表本客户和本客户的对手
int Continue_n = -1; //总步数,用于"续下"模式
int TransportationCount = -1; //已经传递的步数,用于"续下"模式
boolean Disconnected = false; //断线的标志
boolean NewGame = true; // 是新游戏还是"续下"的标志
mb_displayAppend("用户"+Code+"已连接至服务器。");
ClientOccupied[Code] = true;
userName[Code] = EXIT_NAME;
Response[Code] = NO_RESPONSE;
SideDecided[Code] = false;
isReplaying[Code] = false;
TransportationFinished[Code] = true;
//以上初始化
try
{
m_output[Code].writeObject(WELCOME_INFO);
mb_displayAppend("读取用户"+Code+"信息中...");
while (userName[Code].equals(EXIT_NAME)) {
str = (String) m_input[Code].readObject();
mBuf = new StringBuffer(str);
if (mBuf.indexOf(NAME_COMMAND)==0) {
mBuf.delete(0,NAME_COMMAND.length());
userName[Code] = mBuf.toString();
break;
}
} // 读取用户名
mb_displayAppend("用户"+Code+"的名字:"+userName[Code]);
while (true) {
while (ClientOccupied[Code] && MatchedClient[Code]==-1 && !Disconnected) {
//监控已连线未下棋人员的信息
str = (String) m_input[Code].readObject();
mb_displayAppend("来自"+userName[Code]+"的信息:"+str);
mBuf = new StringBuffer(str);
if (str.equals(FIND_REQUEST)) {
//该用户进行了查询操作
mb_displayAppend("用户"+Code+"查询了空闲在线用户情况。");
str = NAME_LIST_RESPONSE;
for (i=0; i<MAX_CLIENT_NUM; i++)
if (i!=Code && ClientOccupied[i]
&& MatchedClient[i]==-1
&& (!userName[i].equals(EXIT_NAME))
&& !isReplaying[i] )
{
str = str + NAME_LIST + userName[i];
}
//以上搜索空闲用户,用NAME_LIST标志隔开不同用户
m_output[Code].writeObject(str);
} else
if (mBuf.indexOf(OPPONENT_COMMAND)==0 || mBuf.indexOf(CONTINUE_REQUEST)==0) {
//该用户发出邀请,前者是正常模式,后者是续下模式
if (mBuf.indexOf(OPPONENT_COMMAND)==0) {
NewGame = true;
mBuf.delete(0,OPPONENT_COMMAND.length());
} else {
NewGame = false;
mBuf.delete(0,CONTINUE_REQUEST.length());
}
str = mBuf.toString();
FindOne = false;
for (i=0; i<MAX_CLIENT_NUM; i++)
if (i!=Code && ClientOccupied[i] && MatchedClient[i]==-1 && (userName[i].equals(str))) {
FindOne = true;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -