📄 chatroomserver.java
字号:
/**
* 服务端
*
* @author Yang
*
*/
package com.wczy.chatroom.server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import com.wczy.chatroom.Protocal;
import com.wczy.chatroom.server.database.User;
import com.wczy.chatroom.server.database.UserDAO;
public class ChatRoomServer {
private int port;
private ServerSocket serverSocket;
private List<OnlineUser> userList = new ArrayList<OnlineUser>(); // 在线列表
private List<OnlineListUpdateListener> onlineListUpdateListeners = new ArrayList<OnlineListUpdateListener>();
private List<PublicMessageListener> messageReceiveListeners = new ArrayList<PublicMessageListener>();
public void addOnlineListUpdateListener(OnlineListUpdateListener listener) {
onlineListUpdateListeners.add(listener);
}
public void addMessageReceiveListener(PublicMessageListener listener) {
messageReceiveListeners.add(listener);
}
public ChatRoomServer(int port) {
this.port = port;
}
// 启动服务器
public void start() throws IOException {
serverSocket = new ServerSocket(port);
Thread listenThread = new Thread() {
@Override
public void run() {
listen();
}
};
listenThread.setDaemon(true);
listenThread.start();
}
// 开始接受请求
private void listen() {
try {
while (true) {
final Socket socket = serverSocket.accept();
Thread communicateWithClientThread = new Thread() {
@Override
public void run() {
communicateWithClient(socket);
}
};
communicateWithClientThread.setDaemon(true);
communicateWithClientThread.start();
}
} catch (IOException e) {
}
}
private boolean register(String nickName, String password) {
/*
* 此处需要编写验证注册是否成功的代码以替换下面这些代码
*
*/
UserDAO dao = new UserDAO();
if( dao.findByUserName(nickName) != null)return false;
User user = new User();
user.setUserName(nickName);
user.setPassword(password);
int i = dao.insert(user);
return i>0;
}
private boolean login(String nickName, String password) {
/*
* 此处需要编写验证登陆是否成功的代码以替换下面这些代码
*
*/
for(OnlineUser u : userList){
if(u.getNickName().equals(nickName))
{
return false;
}
}
UserDAO dao = new UserDAO();
User user = dao.findByUserName(nickName);
if(user != null && user.getPassword().equals(password))
return true;
else
return false;
}
// 与某个客户端交互
private void communicateWithClient(Socket socket) {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
String firstData = reader.readLine();
if (!firstData.startsWith(Protocal.LOGIN_FLAG)
&& !firstData.startsWith(Protocal.REGISTER_FLAG)) {
socket.close();
return;
}
if (firstData.startsWith(Protocal.REGISTER_FLAG)) {
// 格式: REGISTER_FLAG昵称#密码
String[] arr = firstData.substring(
Protocal.REGISTER_FLAG.length()).split(
Protocal.SEPARATOR);
if (register(arr[0], arr[1])) {
sendDataToSocket(Protocal.REGISTER_SUCCEED_FLAG, socket);
} else {
sendDataToSocket(Protocal.REGISTER_FAIL_FLAG, socket);
}
socket.close();
return;
}
// 登陆格式: LOGIN_FLAG昵称#密码
String[] loginArr = firstData.substring(
Protocal.LOGIN_FLAG.length()).split(Protocal.SEPARATOR);
// 如果登录不成功
if (!login(loginArr[0], loginArr[1])) {
sendDataToSocket(Protocal.LOGIN_FAIL_FLAG, socket);
socket.close();
return;
}
sendDataToSocket(Protocal.LOGIN_SUCCEED_FLAG, socket);
OnlineUser currentUser = new OnlineUser(loginArr[0], socket);
userList.add(currentUser);
for (OnlineListUpdateListener listener : onlineListUpdateListeners) {
listener.update(userList);
}
Thread.sleep(200);
sendDataToOnlineUsers(Protocal.ONLINELIST_FLAG + userListToString());
String data;
while (!(data = reader.readLine()).equals(Protocal.BYE_FLAG)) {
if (data.startsWith(Protocal.PUBLIC_MESSAGE_FLAG)) {// 是一条公聊消息
// 格式: PUBLIC_MESSAGE_FLAG消息
String message = data
.substring(Protocal.PUBLIC_MESSAGE_FLAG.length());
for (PublicMessageListener listener1 : messageReceiveListeners) {
listener1.receive(currentUser.getNickName(), message);
}
sendDataToOnlineUsers(Protocal.PUBLIC_MESSAGE_FLAG
+ currentUser.getNickName() + Protocal.SEPARATOR
+ message);
} else if (data.startsWith(Protocal.PRIVATE_MESSAGE_FLAG)) {// 是一条私聊消息
// 格式: PRIVATE_MESSAGE_FLAG接受方昵称#消息
String[] arr = data.substring(
Protocal.PRIVATE_MESSAGE_FLAG.length()).split(
Protocal.SEPARATOR);
for (OnlineUser user : userList) {
if (user.getNickName().equals(arr[0])) {
sendDataToUser(Protocal.PRIVATE_MESSAGE_FLAG
+ currentUser.getNickName()
+ Protocal.SEPARATOR + arr[1], user);
break;
}
}
} else if (data.startsWith(Protocal.ACCEPT_FILE_FLAG)) { // 接受方表示愿意接受文件并告知IP端口,服务器转告发送方
// 格式: ACCEPT_FILE_FLAG准备发送文件方昵称#准备接收文件方端口
String[] arr = data.substring(
Protocal.ACCEPT_FILE_FLAG.length()).split(
Protocal.SEPARATOR);
for (OnlineUser user : userList) {
if (user.getNickName().equals(arr[0])) {
sendDataToUser(Protocal.ACCEPT_FILE_FLAG
+ currentUser.getSocket().getInetAddress().getHostAddress()
+ Protocal.SEPARATOR + arr[1]
+ Protocal.SEPARATOR
+ currentUser.getNickName(), user);
break;
}
}
} else if (data.startsWith(Protocal.SEND_FILE_REQUEST_FLAG)) {// 发送方发出文件传送请求,服务器转告给接受方
// 格式: SEND_FILE_REQUEST_FLAG文件接收方昵称#文件名
String[] arr = data.substring(
Protocal.SEND_FILE_REQUEST_FLAG.length()).split(
Protocal.SEPARATOR);
for (OnlineUser user : userList) {
if (user.getNickName().equals(arr[0])) {
sendDataToUser(Protocal.SEND_FILE_REQUEST_FLAG
+ currentUser.getNickName()
+ Protocal.SEPARATOR + arr[1], user);
break;
}
}
} else if (data.startsWith(Protocal.REJECT_FILE_FLAG)) {// 接受方拒绝接受文件,服务器转告发送方
// 格式: REJECT_FILE_FLAG准备发送文件方昵称
String toNick = data.substring(Protocal.REJECT_FILE_FLAG
.length());
for (OnlineUser user : userList) {
if (user.getNickName().equals(toNick)) {
sendDataToUser(Protocal.REJECT_FILE_FLAG
+ currentUser.getNickName(), user);
break;
}
}
}
}
currentUser.getSocket().close();
userList.remove(currentUser);
for (OnlineListUpdateListener listener : onlineListUpdateListeners) {
listener.update(userList);
}
sendDataToOnlineUsers(Protocal.ONLINELIST_FLAG + userListToString());
} catch (IOException e) {
for (OnlineUser user : userList) {
if (user.getSocket() == socket) {
userList.remove(user);
for (OnlineListUpdateListener listener : onlineListUpdateListeners) {
listener.update(userList);
}
sendDataToOnlineUsers(Protocal.ONLINELIST_FLAG
+ userListToString());
break;
}
}
} catch (InterruptedException e) {
// TODO 自动生成 catch 块
e.printStackTrace();
}
}
// 把在线列表转成字符串
private String userListToString() {
StringBuffer sb = new StringBuffer();
for (OnlineUser user : userList) {
sb.append(user.getNickName());
sb.append(Protocal.SEPARATOR);
}
return sb.toString();
}
// 发送消息到某个Socket
private void sendDataToSocket(String data, Socket socket) {
try {
PrintWriter writer = new PrintWriter(socket.getOutputStream());
writer.println(data);
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
// 发送在线列表到某个在线用户
private void sendDataToUser(String data, OnlineUser user) {
Socket socket = user.getSocket();
sendDataToSocket(data, socket);
}
// 发送在线列表到所有在线用户
private void sendDataToOnlineUsers(String data) {
for (OnlineUser user : userList) {
sendDataToUser(data, user);
}
}
public void stop() throws IOException {
for (OnlineUser user : userList) {
user.getSocket().close();
}
userList.clear();
serverSocket.close();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -