📄 serverframe.java
字号:
if (head.equalsIgnoreCase("PEOPLE")) {
if (stinfo.hasMoreTokens()) {
name = stinfo.nextToken();
//关键字的第二个分段字符串是客户的名称
}
if (stinfo.hasMoreTokens()) {
psword = stinfo.nextToken();
//关键字的第三个分段字符串是客户的密码
}
if (stinfo.hasMoreTokens()) {
ip = stinfo.nextToken();
//关键字的第四个分段字符串是客户的IP地址
}
}
//此处为用户注册请求
else if (head.equalsIgnoreCase("REGISTER")) {
//注册规则: REGISTER:用户设置的密码:用户设置的密码保护
//调用Ramedon构造方法
Ramdon();
//获取Statement对象
Statement stmt = linkData.getStatement();
//获取用户传来的新密码
String password = stinfo.nextToken();
//获取用户传来的密码保护
String pasforget = stinfo.nextToken();
try {
//执行号码添加
stmt.executeUpdate(
"INSERT INTO clients VALUES('" +
mothzNumber + "','" + password + "','" + pasforget +
"')");
//向用户返回注册成功 和 注册成功的号码
StringBuffer message = new
StringBuffer("REGISTEROK:");
message.append(mothzNumber);
send(message.toString());
}
catch (SQLException ex) {
ex.printStackTrace();
//向用户返回注册失败
StringBuffer message = new
StringBuffer("REGISTERFALSE");
send(message.toString());
}
}
//密码重设请求
else if (head.equalsIgnoreCase("FORGET")) {
//规则: FORGET:用户ID:用户的密码保护:用户设置的新密码
//获取Statement对象
Statement stmt = linkData.getStatement();
//获取用户传入的ID
String id = stinfo.nextToken();
//获取用户传入的密码保护
String forget = stinfo.nextToken();
//获取用户传入的新密码
String newpassword = stinfo.nextToken();
try {
//查询用户ID
rs = stmt.executeQuery(
"SELECT * FROM clients WHERE id='" + id + "'");
if (rs.next()) {
//号码存在则进行密码保护的匹对
//密码保护匹配判断
if (rs.getString(3).equals(forget)) {
//正确则修改旧密码
stmt.executeUpdate(
"UPDATE clients SET password='" +
newpassword + "'WHERE id='" + id + "'");
//向用户发送重设密码成功的消息
send("AMENDOK");
}
else {
//密码保护不正确,向用户发送重设失败的消息
send("AMENDFALSE");
}
}
else {
//号码不存在则向用户发送密码重设失败的消息
send("AMENDFALSE");
}
}
catch (SQLException ex1) {
ex1.printStackTrace();
//重设密码意外 发送失败消息
send("AMENDFALSE");
}
}
//密码修改请求
else if (head.equalsIgnoreCase("XIUGAI")) {
//规则: XIUGAI:用户ID:用户的旧密码:用户的新密码
//获取用户传入的ID
String id = stinfo.nextToken();
//获取用户传入的旧密码
String oldpassword = stinfo.nextToken();
//获取用户传入的新密码
String newpassword = stinfo.nextToken();
//获取Statement对象
Statement stmt = linkData.getStatement();
try {
//查询用户传入的ID
rs = stmt.executeQuery(
"SELECT * FROM clients WHERE id='" + id + "'");
if (rs.next()) {
//号码存在
//对旧密码的匹配,正确则修改旧密码
if (rs.getString(2).equals(oldpassword)) {
//执行修改
stmt.executeUpdate(
"UPDATE clients SET password='" +
newpassword + "'WHERE id='" + id + "'");
//向用户发送修改成功消息
send("XIUGAIOK");
}
else {
//旧密码不匹配,向用户发送修改失败的消息
send("XIUGAIFALSE");
}
}
else {
//号码不存在,向用户发送修改失败消息
send("XIUGAIFALSE");
}
}
catch (SQLException ex2) {
ex2.printStackTrace();
//修改意外 发送修改失败消息
send("XIUGAIFALSE");
}
}
}
catch (IOException ex) {
jTextArea1.append("系统消息: 聊天服务器" +
"Error " + ex);
}
}
//send方法是Client类的方法,用于向客户端发送信息
public void send(String msg) {
try {
//用打印流发送信息
dos.writeUTF(msg.toString());
dos.flush();
}
catch (IOException ex) {
ex.printStackTrace();
}
}
//线程类Client的run方法不断接收和处理对应用户发送来的消息
public void run() {
while (true) {
String line = null;
try {
//读取客户端发送的数据流
line = dis.readUTF();
}
catch (IOException e) {
jTextArea1.append("系统消息:" +
" 聊天服务器" +
" Error: " + e);
//断开连接
disconnect(this);
//刷新用户列表
notifyRoom();
return;
}
if (line == null) { //客户已经离开
//断开连接
disconnect(this);
//刷新用户列表
notifyRoom();
return;
}
//使用StringTokenizer设置关键符号
StringTokenizer st = new StringTokenizer
(line, ":");
//初始化keyword和broadcast
String keyword = "";
String broadcast = "";
//取得keyword
if (st.hasMoreTokens()) {
keyword = st.nextToken();
}
//取得broadcast
if (st.hasMoreTokens()) {
broadcast = st.nextToken();
}
//存储关键字,判断消息类型
//存储消息是属于广播,还是属于单播
//如果单播,则记录的是目标用户名
if (keyword.equalsIgnoreCase("MSG")) {
//如果关键字是MSG,则是客户端发送的聊天信息
StringBuffer message = new
StringBuffer("MSG:");
//在服务器端建立一个缓冲区,用于信息的发送
message.append(broadcast + ":");
message.append(st.nextToken("\0"));
if (broadcast.equalsIgnoreCase("BROAD")) {
//向所有在线用户发送消息
sendClients(message);
}
else {
//向指定用户发送消息
sendtoClient(message, broadcast);
}
}
else if (keyword.equalsIgnoreCase("QUIT")) {
//如果关键字是QUIT,则是客户端发送的退出信息
//清除list1中内容
list1.removeAll();
//断开发送断开请求的用户
disconnect(this);
//刷新list1内容
for (int i = 0; i < clients.size(); i++) {
Client listdata1 = (Client) clients.elementAt(i);
list1.add(listdata1.name +
" " +
listdata1.ip + " 已经连接", i);
}
//刷新在线列表
notifyRoom();
//结束用户对应的服务器线程
this.stop();
}
//用户发送在线列表请求
else if (keyword.equalsIgnoreCase("PEOPLE?")) {
notifyRoom();
}
}
}
}
//sendClients是ServerFrame的方法,发送信息到所有用户
public synchronized void sendClients(StringBuffer msg) {
//查询数组中匹配的用户
for (int i = 0; i < clients.size(); i++) {
Client c = (Client) clients.elementAt(i);
c.send(msg.toString());
}
}
//sendtoClient是ServerFrame的方法,
//将信息发送到特定的单个用户
public void sendtoClient
(StringBuffer msg, String name) {
for (int i = 0; i < clients.size(); i++) {
Client c = (Client) clients.elementAt(i);
if (c.name.equalsIgnoreCase(name)) {
c.send(msg.toString());
break;
}
}
}
//disconnect是ServerFrame的方法,与单个用户断开连接
public void disconnect(Client c) {
try {
jTextArea1.append("系统消息: "
+ c.name +
" 断开连接!\n");
//用户数组中移出指定的用户
clients.removeElement(c);
//向所有在线用户发送 请求退出单个的用户
sendClients(new StringBuffer("QUIT" +
":" + c.name));
//断开连接
c.socket.close();
}
catch (IOException e) {
jTextArea1.append("系统消息:" +
" 聊天服务器" +
" Error " + e);
}
finally {
//显示在线人数
online.setText("" + clients.size());
}
}
//notifyRoom是ServerFrame的方法,监视聊天窗口的
//连接变化,不断刷新clients数组并刷新用户列表信息
public void notifyRoom() {
if (clients.size() > 0) {
StringBuffer people = new
StringBuffer("PEOPLE");
//增加PEOPLE表示是客户列表信息
for (int i = 0; i < clients.size(); i++) {
Client c = (Client) clients.elementAt(i);
people.append(":" + c.name);
}
sendClients(people);
}
}
//Watch类是ServerFrame类的另一个内部类
class Watch
extends Thread {
//Watch类的run方法不断监听有没有新的用户连接进来
public void run() {
while (true) {
if (clients.size() < 20)
//当客户数目小于20的时候接受连接
{
try {
//监听端口
socket = serverSocket.accept();
System.out.println(socket.toString());
}
catch (IOException ee) {
jTextArea1.append
("系统消息: 聊天服务器 " +
ee.toString() +
" 用户连接失败!\n");
}
if (socket != null) {
Client c = new Client(socket);
//定义并实例化一个Client线程,
//每一个线程对应一个客户连接
if (checkName(c)) {
clients.addElement(c);
//如果名字不重复,加入到clients数组中
list1.add(c.name + " " +
c.ip +
" 已经连接",
clients.size());
//在list1的第clients.size()行
//显示当前用户信息
jTextArea1.append("系统消息: " +
c.name +
"/" + c.ip +
" 已经连接!\n");
//在jTextArea1中显示连接信息
online.setText("" + clients.size());
//在状态栏中显示目前的活动数目
c.start();
//启动线程
c.send("Welcome");
//提示用户已经成功登录
notifyRoom();
//监视聊天窗口的连接变化
}
else {
try {
c.send("FaultName");
//检查名字不合法,则在发送流中发送FaultName
c.socket.close();
//断开连接
}
catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
else { //如果超过连接数目
try {
Thread.sleep(400); //睡眠400毫秒后重新连接
}
catch (InterruptedException ee) {
}
}
} //end of while
} //end of run
} ////end of watch class
//checkName是ServerFrame的方法,
//检查用户登录时输入的用户信息是否正确
public boolean checkName(Client newClient) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -