📄 server.java
字号:
import java.net.*;
import java.io.*;
import java.awt.List;
import java.util.ArrayList;
import java.util.Hashtable;
import java.awt.Color;
import javax.swing.JOptionPane;
public class Server extends Thread
{
ServerSocket server=null;
List onLineUsersList=null;
List chatContentList=null;
ArrayList onLineUsers=new ArrayList();
ArrayList chatContent=new ArrayList();
boolean isClosed=false;
//在服务器端维护一个hashtable,用来存放各客户端的IP地址与用户昵称之间的对照关系映射。
Hashtable ip2nickname=new Hashtable();
ArrayList allService=new ArrayList();
public Server(int port,List onLineUsersList,List chatContentList) throws IOException
{
this.server=new ServerSocket(port);
this.onLineUsersList=onLineUsersList;
this.chatContentList=chatContentList;
this.start();
}
public void run()
{
while(!isClosed)
{
try
{
Socket client=null;
if(!server.isClosed())
{
client = server.accept();
}
String clientIP=client.getInetAddress().getHostAddress();
//判断该客户端已经连接的话,提示退出
if(ip2nickname.get(clientIP)!=null)
{
ChatTookit.sendInfo(client,"已经有客户端从该ip地址连接服务器,本次连接将退出!");
break;
}
//把新建连接的用户加入当前用户列表
onLineUsers.add(client);
//默认情况下,即在还没有收到用户自定义昵称的清空下,把用户的IP地址做为其昵称维护入ip2nickname
ip2nickname.put(clientIP,clientIP);
//在服务器端提示有新的客户连接
this.onLineUsersList.add(clientIP);
this.chatContentList.add(clientIP+" 来了");
//对所有已连接的客户端,发送两条信息,1提示有新用户连接,2最新在线用户昵称列表
ChatTookit.sendInfoToAll(onLineUsers,ChatTookit.getAllNickname(ip2nickname));
ChatTookit.sendInfoToAll(onLineUsers,clientIP+" 来了");
//针对每个client连接启动其特定服务线程
Service service=new Service(client,ip2nickname,onLineUsersList,chatContentList,onLineUsers,chatContent);
this.allService.add(service);;
}
catch (IOException ex)
{
JOptionPane.showMessageDialog(null,"接收客户端连接时出现问题!", "提示",JOptionPane.INFORMATION_MESSAGE);
}
}
}
public void destroy()
{
for(int i=0;i<onLineUsers.size();i++)
{
Socket c=(Socket)onLineUsers.get(i);
try
{
c.close();
}
catch (IOException ex)
{
JOptionPane.showMessageDialog(null, "关闭客户端连接时候出现问题!", "提示",JOptionPane.INFORMATION_MESSAGE);
}
}
try
{
this.isClosed=true;
server.close();
}
catch (IOException ex1)
{
JOptionPane.showMessageDialog(null, "关闭服务器时出现问题!", "提示",JOptionPane.INFORMATION_MESSAGE);
}
}
public void send(String word) throws IOException
{
if (word.startsWith("SPECIAL:"))
{
word = word.substring(8);
String toNickname = word.substring(0, word.indexOf("$SPECIAL$"));
word = word.substring(word.indexOf("$SPECIAL$") + 9);
//根据昵称找到该客户端
Socket client = ChatTookit.getSocketByIP(onLineUsers,
ChatTookit.getIP(ip2nickname, toNickname));
ChatTookit.sendInfo(client, "系统管理员 悄悄对你说:" + word);
}
else
{
chatContentList.add("系统管理员:" + word);
ChatTookit.sendInfoToAll(onLineUsers, "系统管理员:" + word);
}
chatContentList.select(chatContentList.getItemCount()-1);
}
//强制更改用户的昵称
public void changeNickname(String oldName,String newName)
{
//如果该昵称已经被别人使用则不进行更改
if(ip2nickname.contains(newName))
{
chatContent.add("该昵称已经有人使用,所以不做任何更改");
this.chatContentList.select(this.chatContentList.getItemCount()-1);
return;
}
//找到旧昵称所在的ip地址
String ip=ChatTookit.getIP(ip2nickname,oldName);
//用新昵称更新旧昵称
ip2nickname.put(ip,newName);
//将负责该用户的Service里的昵称变量进行修改
Service service=ChatTookit.getServiceByIP(allService,ip);
service.changeNickname(newName);
//刷新服务器端的显示
chatContentList.add("系统管理员 将 "+oldName+" 的昵称改为 "+newName);
this.chatContentList.select(this.chatContentList.getItemCount()-1);
ChatTookit.updateOnLineUsersList(onLineUsersList,ip2nickname);
//刷新各客户端的显示
try
{
ChatTookit.sendInfoToAll(onLineUsers,"系统管理员 将 " + oldName + " 的昵称改为 " + newName);
ChatTookit.sendInfoToAll(onLineUsers,ChatTookit.getAllNickname(ip2nickname));
}
catch (IOException ex)
{
JOptionPane.showMessageDialog(null, "发送信息时出错!", "提示",JOptionPane.INFORMATION_MESSAGE);
}
}
public void tickSocket(String nickname)
{
//先找到该昵称对应的socket,service,ip等信息
String ip=ChatTookit.getIP(ip2nickname,nickname);
Socket client=ChatTookit.getSocketByIP(onLineUsers,ip);
Service service=ChatTookit.getServiceByIP(allService,ip);
//从几个arraylist里把该客户端对应的信息都删除
this.allService.remove(service);
this.onLineUsers.remove(client);
this.ip2nickname.remove(ip);
//关闭该客户端
try
{
//先给该客户端提供提示信息
ChatTookit.sendInfo(client,"你已经被系统管理员踢出聊天室");
client.close();
}
catch (IOException ex)
{
JOptionPane.showMessageDialog(null, "关闭客户端"+ip+"时出错!", "提示",JOptionPane.INFORMATION_MESSAGE);
}
//刷新服务器端的显示
chatContentList.add("系统管理员 将 "+nickname+" 踢出聊天室!");
this.chatContentList.select(this.chatContentList.getItemCount()-1);
ChatTookit.updateOnLineUsersList(onLineUsersList,ip2nickname);
//刷新各客户端的显示
try
{
ChatTookit.sendInfoToAll(onLineUsers,"系统管理员 将 " +nickname+" 踢出聊天室!");
ChatTookit.sendInfoToAll(onLineUsers,ChatTookit.getAllNickname(ip2nickname));
}
catch (IOException ex)
{
JOptionPane.showMessageDialog(null, "发送信息出错!", "提示",JOptionPane.INFORMATION_MESSAGE);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -