package org.shan.server;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import org.jvnet.substance.SubstanceLookAndFeel;
import org.jvnet.substance.skin.SubstanceOfficeBlue2007LookAndFeel;
/**
* 显示服务器及用户信息的Panel类
*/
class MessageServerPanel extends Panel {
TextArea messageBoard = new TextArea("", 22, 50,
TextArea.SCROLLBARS_VERTICAL_ONLY);
JLabel statusLabel = new JLabel("当前连接数:", Label.LEFT);
JPanel boardPanel = new JPanel();// 主显示区Panel
JPanel statusPanel = new JPanel();// 连接状态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("/r")) {
// 获取修改后的用户名
clientName = message.substring(2);
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++;
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
基于JAVA的网络五子棋对战系统ECLIPSE导出包 (1285个子文件)
SubstanceCoreUtilities.class 56KB
SubstanceScrollBarUI.class 55KB
SubstanceTabbedPaneUI.class 50KB
SubstanceLookAndFeel.class 47KB
SubstanceImageCreator.class 40KB
SubstanceTheme.class 38KB
SubstanceTableUI.class 34KB
SubstanceTitlePane.class 32KB
SubstanceSliderUI.class 26KB
ColorWheelPanel.class 25KB
SubstanceTreeUI.class 24KB
SubstanceComboBoxUI.class 20KB
FadeTracker.class 20KB
SubstanceTableHeaderUI.class 19KB
XMLElement.class 19KB
SubstanceProgressBarUI.class 17KB
MenuUtilities.class 17KB
SubstanceButtonUI.class 16KB
SubstanceComplexTheme.class 16KB
SubstanceListUI.class 16KB
SubstanceInternalFrameTitlePane.class 15KB
TransitionLayout.class 15KB
SubstanceToggleButtonUI.class 15KB
ButtonBackgroundDelegate.class 14KB
SubstanceRadioButtonUI.class 14KB
QuaquaUtilities.class 14KB
SubstanceRootPaneUI.class 13KB
ScrollPaneSelector.class 13KB
JCarouselMenu.class 13KB
SubstanceColorUtilities.class 13KB
ColorSliderUI.class 12KB
HTMLChooser.class 12KB
LafWidgetUtilities.class 11KB
PairwiseButtonBackgroundDelegate.class 11KB
SubstanceSplitPaneDivider.class 11KB
SubstanceSpinnerUI.class 11KB
ServerThread.class 10KB
SubstanceScrollPaneUI.class 10KB
TreeDragAndDropWidget$TreeDropTargetListener.class 10KB
SubstanceScrollBarUI$SubstanceTrackListener.class 10KB
CaroselLayout.class 10KB
ChessPanel.class 10KB
SubstanceLabelUI.class 10KB
CMYKChooser.class 9KB
ColorWheelPanel$ColorWheel.class 9KB
BasePlugin.class 9KB
GrayChooser.class 9KB
SubstanceMenuUI.class 9KB
SubstanceCheckBoxUI.class 9KB
SwatchesChooser.class 9KB
Methods.class 9KB
ChessClient.class 9KB
SubstanceSizeUtils.class 9KB
TreeDragAndDropWidget.class 9KB
SubstanceImageWatermark.class 8KB
HSBChooser.class 8KB
SubstanceRadioButtonMenuItemUI.class 8KB
SubstanceIconFactory$SliderVerticalIcon.class 8KB
MenuSearchWidget.class 8KB
LafWidgetRepository.class 8KB
Quaqua15ColorPicker.class 8KB
ColorPicker.class 8KB
GhostPaintingUtils.class 8KB
SubstanceIconFactory$SliderHorizontalIcon.class 8KB
SubstanceMetalWallWatermark.class 8KB
SubstanceCheckBoxMenuItemUI.class 8KB
Quaqua13ColorChooserUI.class 8KB
ReflectedImageLabel.class 8KB
SubstanceIconFactory$SliderRoundIcon.class 8KB
ColorPalettesChooser.class 8KB
RGBChooser.class 7KB
SubstanceRootPaneUI$MouseInputHandler.class 7KB
SubstanceTabbedPaneUI$MouseRolloverHandler.class 7KB
SubstanceThemeUtilities.class 7KB
SubstancePopupMenuSeparatorUI.class 7KB
MemoryAnalyzer.class 7KB
SubstanceSeparatorUI.class 7KB
ImageWrapperDecorationPainter.class 7KB
SubstanceMenuItemUI.class 7KB
SubstanceOptionPaneUI.class 7KB
TabPagerManager.class 7KB
SubstanceDesktopIconUI.class 7KB
SubstanceTextAreaUI.class 7KB
TweakedScrollPaneLayout.class 7KB
ComboboxAutoCompletionWidget.class 7KB
SubstancePasswordFieldUI$SubstancePasswordView.class 7KB
LafWidgetSupport.class 7KB
JCarosel.class 7KB
ClassicHighlightPainter.class 7KB
DesktopIconHoverPreviewWidget.class 7KB
SubstanceDefaultTableHeaderCellRenderer.class 7KB
TabPreviewThread.class 7KB
SubstanceWidgetSupport.class 6KB
MenuSearchWidget$SearchPanel.class 6KB
SubstanceMenuBackgroundDelegate.class 6KB
SubstanceDefaultTreeCellRenderer.class 6KB
SubstanceDefaultLookAndFeel$SubstanceDefaultSkin.class 6KB
ShadowPopup.class 6KB
GlassHighlightPainter.class 6KB
Options.class 6KB
共 1285 条
- 1
- 2
- 3
- 4
- 5
- 6
- 13
资源评论
sorry194
- 粉丝: 0
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功