服务器端源代码:packageorg.shan.server;importjava.awt.BorderLayout;importjava.awt.Color;importjava.awt.FlowLayout;importjava.awt.Frame;importjava.awt.Label;importjava.awt.Panel;importjava.awt.TextArea;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.awt.event.WindowAdapter;importjava.awt.event.WindowEvent;importjava.io.DataInputStream;importjava.io.DataOutputStream;importjava.io.IOException;importjava.net.ServerSocket;importjava.net.Socket;importjava.util.Enumeration;importjava.util.Hashtable;importjava.util.StringTokenizer;importjavax.swing.JButton;importjavax.swing.JLabel;importjavax.swing.JPanel;importjavax.swing.UIManager;importorg.jvnet.substance.SubstanceLookAndFeel;importorg.jvnet.substance.skin.SubstanceOfficeBlue2007LookAndFeel;/***显示服务器及用户信息的Panel类*/classMessageServerPanelextendsPanel{TextAreamessageBoard=newTextArea(,22,50,TextArea.SCROLLBARS_VERTICAL_ONLY);JLabelstatusLabel=newJLabel(当前连接数:,Label.LEFT);JPanelboardPanel=newJPanel();//主显示区PanelJPanelstatusPanel=newJPanel();//连接状态PanelMessageServerPanel(){setSize(350,300);setBackground(newColor(204,204,204));setLayout(newBorderLayout());boardPanel.setLayout(newFlowLayout());boardPanel.setSize(210,210);statusPanel.setLayout(newBorderLayout());statusPanel.setSize(210,50);boardPanel.add(messageBoard);statusPanel.add(statusLabel,BorderLayout.WEST);add(boardPanel,BorderLayout.CENTER);add(statusPanel,BorderLayout.NORTH);}}/***服务器线程,主要用于服务器与客户端的通信*/classServerThreadextendsThread{SocketclientSocket;HashtableclientDataHash;//Socket与发送数据的流的映射HashtableclientNameHash;//Socket与用户名的映射HashtablechessPeerHash;//对弈的两个客户端用户名的映射MessageServerPanelserver;booleanisClientClosed=false;/***服务器端线程的构造函数,用于初始化一些对象。*/ServerThread(SocketclientSocket,HashtableclientDataHash,HashtableclientNameHash,HashtablechessPeerHash,MessageServerPanelserver){this.clientSocket=clientSocket;this.clientDataHash=clientDataHash;this.clientNameHash=clientNameHash;this.chessPeerHash=chessPeerHash;this.server=server;}/***对客户端发来的消息处理的函数,处理后转发回客户端。处理消息的过程比较复杂,要针对很多种情况分别处理。*/publicvoidmessageTransfer(Stringmessage){StringclientName,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)));}}//如果用户在对弈双方的客户端,做如下处理。elseif(chessPeerHash.containsKey(clientNameHash.get(clientSocket))){//将客户端的新名字映射到clientNameHashsynchronized(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));}//如果用户在对弈双方的服务端,做如下处理。elseif(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”开头,则将其回馈到客户端以更新用户列表elseif(message.equals(/list)){Feedback(getUserList());}//如果消息以/creatgame[inchess]开头,则修改clientNameHash映射//和chessPeerHash映射。elseif(message.startsWith(/creatgame[inchess])){Stringchess