⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chessserver.java

📁 Eclipse 编程技术与实例,讲解了Eclipse编辑器的使用方法
💻 JAVA
📖 第 1 页 / 共 2 页
字号:

package com.fivechess.server;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.util.*;
import java.awt.event.*;
/**
 * 显示服务器及用户信息的Panel类
 */
class MessageServerPanel extends Panel 
{
	TextArea messageBoard = new TextArea("", 22, 50,
			TextArea.SCROLLBARS_VERTICAL_ONLY);

	Label statusLabel = new Label("当前连接数:", Label.LEFT);

	Panel boardPanel = new Panel();//主显示区Panel

	Panel statusPanel = new Panel();//连接状态Panel

	MessageServerPanel() {
		setSize(350, 300);
		setBackground(new Color(204,204,204));
		setLayout(new BorderLayout());
		boardPanel.setLayout(new FlowLayout());
		boardPanel.setSize(210, 210);
		statusPanel.setLayout(new BorderLayout());
		statusPanel.setSize(210, 50);
		boardPanel.add(messageBoard);
		statusPanel.add(statusLabel, BorderLayout.WEST);
		add(boardPanel, BorderLayout.CENTER);
		add(statusPanel, BorderLayout.NORTH);
	}
}
/**
 * 服务器线程,主要用于服务器与客户端的通信
 */
class ServerThread extends Thread {
	Socket clientSocket;

	Hashtable clientDataHash;//Socket与发送数据的流的映射

	Hashtable clientNameHash;//Socket与用户名的映射

	Hashtable chessPeerHash;//对弈的两个客户端用户名的映射

	MessageServerPanel server;

	boolean isClientClosed = false;
    /**
     * 服务器端线程的构造函数,用于初始化一些对象。
     */
	ServerThread(Socket clientSocket, Hashtable clientDataHash,
			Hashtable clientNameHash, Hashtable chessPeerHash,
			MessageServerPanel server) {
		this.clientSocket = clientSocket;
		this.clientDataHash = clientDataHash;
		this.clientNameHash = clientNameHash;
		this.chessPeerHash = chessPeerHash;
		this.server = server;
	}
/**
 * 对客户端发来的消息处理的函数,处理后转发回客户端。处理消息的过程比较复杂,
 * 要针对很多种情况分别处理。
 */
	public void messageTransfer(String message) {
		String clientName, peerName;
     //如果消息以“/”开头,表明是命令消息。
		if (message.startsWith("/")) {
        //消息以“/changename”开头的几种情况.
			if (message.startsWith("/changename ")) {
				//获取修改后的用户名
				clientName = message.substring(12);
				if (clientName.length() <= 0 || clientName.length() > 20
						|| clientName.startsWith("/")
						|| clientNameHash.containsValue(clientName)
						|| clientName.startsWith("changename")
						|| clientName.startsWith("list")
						|| clientName.startsWith("[inchess]")
						|| clientName.startsWith("creatgame")
						|| clientName.startsWith("joingame")
						|| clientName.startsWith("yourname")
						|| clientName.startsWith("userlist")
						|| clientName.startsWith("chess")
						|| clientName.startsWith("OK")
						|| clientName.startsWith("reject")
						|| clientName.startsWith("peer")
						|| clientName.startsWith("peername")
						|| clientName.startsWith("giveup")
						|| clientName.startsWith("youwin")
						|| clientName.startsWith("所有人")) {
					//如果名字不合规则,则向客户端发送信息“无效命令”。
					message = "无效命令";
					Feedback(message);
				} else {
					if (clientNameHash
							.containsValue(("[inchess]" + (String) clientNameHash
									.get(clientSocket)))) {
				    //如果用户正在对弈中,则直接修改Socket和名字的映射Hash表。
						synchronized (clientNameHash) {
							clientNameHash.put((Socket) getHashKey(
									clientNameHash,
									("[inchess]" + clientNameHash
											.get(clientSocket))),
									("[inchess]" + clientName));
							chessPeerTalk(("[inchess" + clientName),
									("/yourname " + ("[inchess]" + clientName)));
						}
					} 
					//如果用户在对弈双方的客户端,做如下处理。
					else if (chessPeerHash.containsKey(clientNameHash
							.get(clientSocket))) {
						//将客户端的新名字映射到clientNameHash
						synchronized (clientNameHash) {
							clientNameHash.put((Socket) getHashKey(
									clientNameHash,
									("[inchess]" + clientNameHash
											.get(clientSocket))),
									("[inchess]" + clientName));
						}

						synchronized (chessPeerHash) {
							//chessPeerHash添加新名字映射
							chessPeerHash.put(clientName, chessPeerHash
									.get(clientNameHash.get(clientSocket)));
							//chessPeerHash删除旧映射
							chessPeerHash.remove(clientNameHash
									.get(clientSocket));
						}
						//向游戏客户端发送新名字
						chessPeerTalk(("[inchess]" + clientName),
								("/yourname " + ("[inchess]" + clientName)));
						//向peer游戏客户端发送
						chessPeerTalk((String) chessPeerHash.get(clientName),
								("/peer " + "[inchess]" + clientName));

					} 
//					如果用户在对弈双方的服务端,做如下处理。
					else if (chessPeerHash.containsValue(clientNameHash
							.get(clientSocket))) {
						synchronized (clientNameHash) {
							//游戏客户端改名字
							clientNameHash.put((Socket) getHashKey(
									clientNameHash,
									("[inchess]" + clientNameHash
											.get(clientSocket))),
									("[inchess]" + clientName));
						}
						synchronized (chessPeerHash) {
							//chessPeerHash重新映射
							chessPeerHash.put((String) getHashKey(
									chessPeerHash, clientNameHash
											.get(clientSocket)), clientName);
							//向游戏客户端发送新名字
							chessPeerTalk(("[inchess]" + clientName),
									("/yourname " + ("[inchess]" + clientName)));
						}
						//向peer游戏客户端发送
						chessPeerTalk((String) getHashKey(chessPeerHash,
								clientName),
								("/peer " + "[inchess]" + clientName));

					}
                    //将改名消息封装好以备发送
					message = clientNameHash.get(clientSocket) + "改名为:"
							+ clientName;
					synchronized (clientNameHash) {
						clientNameHash.put(clientSocket, clientName);
					}
					//向所有的客户端发送消息
					publicTalk(message);
					//回馈到改名的客户端
					Feedback("/yourname "
							+ (String) clientNameHash.get(clientSocket));
					//刷新用户列表
					publicTalk(getUserList());

				}

			} 
			//如果消息以“/list”开头,则将其回馈到客户端以更新用户列表
			else if (message.equals("/list")) {
				Feedback(getUserList());
			} 
			//如果消息以"/creatgame [inchess]"开头,则修改clientNameHash映射
			//和chessPeerHash映射。
			else if (message.startsWith("/creatgame [inchess]")) {
				String chessServerName = message.substring(20);
				synchronized (clientNameHash) {
					clientNameHash.put(clientSocket, message.substring(11));
				}
				synchronized (chessPeerHash) {
					chessPeerHash.put(chessServerName, "wait");
				}
				Feedback("/yourname " + clientNameHash.get(clientSocket));
				chessPeerTalk(chessServerName, "/OK");
				publicTalk(getUserList());
			} 
			//如果消息以“/joingame”开头,则将消息的服务端名字和本地用户名提取出来,
			//然后修改clientNameHash表和chessPeerHash表。
			else if (message.startsWith("/joingame ")) {
				StringTokenizer userToken = new StringTokenizer(message, " ");
				String getUserToken, serverName, selfName;
				String[] chessNameOpt = { "0", "0" };
				int getOptNum = 0;
            //提取服务端用户名和本地用户名
				while (userToken.hasMoreTokens()) {
					getUserToken = (String) userToken.nextToken(" ");
					if (getOptNum >= 1 && getOptNum <= 2) {
						chessNameOpt[getOptNum - 1] = getUserToken;
					}
					getOptNum++;
				}
				serverName = chessNameOpt[0];
				selfName = chessNameOpt[1];
                //如果有服务端在等待开始棋局
				if (chessPeerHash.containsKey(serverName)
						&& chessPeerHash.get(serverName).equals("wait")) {
					//修改Socket和名字映射
					synchronized (clientNameHash) {
						clientNameHash.put(clientSocket,
								("[inchess]" + selfName));
					}
					//修改chessPeerHash映射
					synchronized (chessPeerHash) {
						chessPeerHash.put(serverName, selfName);
					}
					publicTalk(getUserList());
					chessPeerTalk(selfName,
							("/peer " + "[inchess]" + serverName));
					chessPeerTalk(serverName,
							("/peer " + "[inchess]" + selfName));
				} else {
					chessPeerTalk(selfName, "/reject");
					try {
						clientClose();
					} catch (Exception ez) {
					}
				}
			} 
			//如果消息以“/[inchess]”开头,则获取要发送消息的用户名和发送的消息
			//然后发送出去。
			else if (message.startsWith("/[inchess]")) {
				int firstLocation = 0, lastLocation;

				lastLocation = message.indexOf(" ", 0);

				peerName = message.substring((firstLocation + 1), lastLocation);
				message = message.substring((lastLocation + 1));
				if (chessPeerTalk(peerName, message)) {
					Feedback("/error");
				}
			} 
			//如果消息以“/giveup”开头,则判断是对弈双方哪方放弃了。
			else if (message.startsWith("/giveup ")) {
				String chessClientName = message.substring(8);
				if (chessPeerHash.containsKey(chessClientName)
						&& !((String) chessPeerHash.get(chessClientName))
								.equals("wait")) {
					//如果服务方放弃,则发送消息“/youwin”表明对方获胜
					chessPeerTalk((String) chessPeerHash.get(chessClientName),
							"/youwin");
					synchronized (chessPeerHash) {
						chessPeerHash.remove(chessClientName);
					}
				}
				if (chessPeerHash.containsValue(chessClientName)) {
					//如果客户方放弃,也发送消息“/youwin”表明对方获胜
					chessPeerTalk((String) getHashKey(chessPeerHash,
							chessClientName), "/youwin");
					synchronized (chessPeerHash) {
						chessPeerHash.remove((String) getHashKey(chessPeerHash,
								chessClientName));
					}
				}
			} 
			//如果找不到发送消息的用户,则输出消息说“没有这个用户”
			else {

				int firstLocation = 0, lastLocation;

				lastLocation = message.indexOf(" ", 0);
				if (lastLocation == -1) {
					Feedback("无效命令");
					return;
				} else {
					peerName = message.substring((firstLocation + 1),
							lastLocation);
					message = message.substring((lastLocation + 1));
					message = (String) clientNameHash.get(clientSocket) + ">"
							+ message;
					if (peerTalk(peerName, message)) {
						Feedback("没有这个用户:" + peerName + "\n");
					}
				}

			}

		}
       //如果不以“/”开头,表明是普通消息,直接发送
		else {
			message = clientNameHash.get(clientSocket) + ">" + message;
			server.messageBoard.append(message + "\n");
			publicTalk(message);
			server.messageBoard.setCaretPosition(server.messageBoard.getText()
					.length());
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -