------- android培训、java培训、期待与您交流! ----------
package along.chatserver.common;
import java.io.Serializable;
import java.util.Date;
import java.util.Vector;
public class MessageInfo implements Serializable{
private static final long serialVersionUID = 1L;
private int msgType;
private String sender;
private String receiver;
private String content;
private Vector<Vector<String>>rowVector;
private Vector<String>columnVector;
private Vector<String>friendVector;
private Date messageCreateTime;
private boolean isOnline;
private Object object;
public MessageInfo() {
messageCreateTime=new Date(System.currentTimeMillis());
}
public int getMsgType() {
return msgType;
}
public void setMsgType(int msgType) {
this.msgType = msgType;
}
public String getSender() {
return sender;
}
public void setSender(String sender) {
this.sender = sender;
}
public String getReceiver() {
return receiver;
}
public void setReceiver(String receiver) {
this.receiver = receiver;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Vector<Vector<String>> getRowVector() {
return rowVector;
}
public void setRowVector(Vector<Vector<String>> rowVector) {
this.rowVector = rowVector;
}
public Vector<String> getColumnVector() {
return columnVector;
}
public void setColumnVector(Vector<String> columnVector) {
this.columnVector = columnVector;
}
public Vector<String> getFriendVector() {
return friendVector;
}
public void setFriendVector(Vector<String> friendVector) {
this.friendVector = friendVector;
}
public Date getMessageCreateTime() {
return messageCreateTime;
}
public boolean isOnline() {
return isOnline;
}
public void setOnline(boolean isOnline) {
this.isOnline = isOnline;
}
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
}
package along.chatserver.common;
public interface MessageType {
/**
* 登陆成功
*/
public static final int TYPE_1=1;
/**
* 登录失败
*/
public static final int TYPE_2=2;
/**
* 普通消息
*/
public static final int TYPE_3=3;
/**
* 请求在线好友
*/
public static final int TYPE_4=4;
/**
* 返回在线好友
*/
public static final int TYPE_5=5;
/**
* 新用户登陆,发送上线通知给好友
*/
public static final int TYPE_6=6;
/**
* 用户离线,发送离线通知给好友
*/
public static final int TYPE_7=7;
/**
* 返回好友列表
*/
public static final int TYPE_8=8;
/**
* 请求好友列表
*/
public static final int TYPE_9=9;
/**
* 服务器返回查询用户信息的结果给查询对话框
*/
public static final int TYPE_10=10;
/**
* 查询用户信息
*/
public static final int TYPE_11=11;
/**
* 请求添加用户为好友
*/
public static final int TYPE_12=12;
/**
* 服务器返回添加好友的结果给查询对话框
*/
public static final int TYPE_13=13;
/**
* 通知客户端添加好友成功,更新好友列表
*/
public static final int TYPE_14=14;
/**
* 通知客户端删除好友成功,更新好友列表
*/
public static final int TYPE_15=15;
/**
* 客户端请求删除好友
*/
public static final int TYPE_16=16;
/**
* 用户申请进入聊天室,若成功,给聊天室每位成员发送广播
*/
public static final int TYPE_17=17;
/**
* 用户离开聊天室
*/
public static final int TYPE_18=18;
/**
* 用户发送信息到聊天室
*/
public static final int TYPE_19=19;
/**
* 服务器返回用户申请进入聊天室的结果
*/
public static final int TYPE_20=20;
/**
* 进入聊天室失败,服务器返回失败原因
*/
public static final int TYPE_21=21;
/**
* 用户申请创建新聊天室
*/
public static final int TYPE_22=22;
/**
* 返回用户申请创建新聊天室的结果
*/
public static final int TYPE_23=23;
/**
* 用户请求查询已存在的聊天室
*/
public static final int TYPE_24=25;
/**
* 返回用用户对已存在的聊天室的查询结果
*/
public static final int TYPE_25=25;
}
package along.chatserver.common;
import java.io.Serializable;
public class UserInfo implements Serializable{
private static final long serialVersionUID = 1L;
private String userAccount;
private String userPasswd;
private String[]regInfo;
private int type;
public String getUserAccount() {
return userAccount;
}
public void setUserAccount(String userAccount) {
this.userAccount = userAccount;
}
public String getUserPasswd() {
return userPasswd;
}
public void setUserPasswd(String userPasswd) {
this.userPasswd = userPasswd;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String[] getRegInfo() {
return regInfo;
}
public void setRegInfo(String[] regInfo) {
this.regInfo = regInfo;
}
}
package along.chatserver.datasort;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Vector;
import along.chatserver.dbaccess.SqlHelper;
public class DataSort {
private ResultSet rs=null;
private Vector<Vector<String>> rowVector=null;
private Vector<String> colum=null;
private String[]columnNames={"账号","姓名","昵称","性别","出生日期","家庭住址","电子邮件","账号注册时间"};
private String[]columnTokens=
{"userAccount","userName","nickName","userSex","userBirth","userAddress","userEmail","regTime"};
public DataSort() {
}
public void closeConnection() {
}
/**
* 更新数据库
* @param sql 带占位符的SQL语句
* @param paras 用来填充占位符的参数
* @return 若更新成功,返回 true 否则返回 false
*/
public boolean updateData(String sql,String[]paras){
SqlHelper helper=new SqlHelper();
boolean isSuccess=false;
try {
helper.updateDatabase(sql, paras);
isSuccess=true;
} catch (SQLException e) {
e.printStackTrace();
}finally{
helper.closeConnection();
}
return isSuccess;
}
/**
* 查询数据库
* @param sql 带占位符的SQL语句
* @param paras 用来填充占位符的参数
* @return Vector<Vector<String>> 从数据库取得的所有行的所有内容
*/
public Vector<Vector<String>> queryData(String sql,String[]paras) {
SqlHelper helper=null;
ResultSetMetaData rsd=null;
try {
helper=new SqlHelper();
rs=helper.queryDatabase(sql, paras);
rsd=rs.getMetaData();
int columnCount=rsd.getColumnCount();
createColumn(columnCount,rsd);
rowVector=new Vector<Vector<String>>();
while(rs.next()){
Vector<String> temp2=new Vector<String>();
for(int i=0;i<columnCount;i++){
temp2.add(rs.getString(i+1));
}
rowVector.add(temp2);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
if(rs!=null)
helper.closeConnection();
rsd=null;
rs=null;
helper=null;
}
return rowVector;
}
public Vector<String> sortedColumn() {
return colum;
}
/**
* 处理数据库返回数据的字段名称
* @return 返回整理并更新过的数据字段 Vector<String>,以便于调用者根据这些字段来初始化表格的列名称
* @throws SQLException
*/
private void createColumn(int columnCount,ResultSetMetaData rsd) throws SQLException{
colum=new Vector<String>(6);
String columnToken;
int len=columnTokens.length;
for(int i=0;i<columnCount;i++){
columnToken=rsd.getColumnName(i+1);
for(int j=0;j<len;j++){
if(columnToken.equalsIgnoreCase(columnTokens[j])){
columnToken=columnNames[j];
}
}
colum.add(columnToken);
}
}
}
package along.chatserver.datasort;
import java.util.Vector;
/**
* @author Along
*
*/
public class EventProcess {
private Vector<String>colum;
// private String match=" where ?=(select u_account from login where u_id=?)";
private String match="";
public Vector<Vector<String>> getLoginProcess(String[]paras) {
String sql=null;
Vector<Vector<String>>rowVector=null;
//因为登陆查询是在服务器端进行,因此只会返回字符串数组,不会包含任何服务器数据库信息,因此不需
//担心因返回的数据导致登录表名泄露的问题
sql="select u.userAccount,u.nickName,l.userId from login l,userInfo u where (l.userAccount=? and
l.userPassword=?) and(u.userAccount=l.userAccount)";
DataSort dSort=new DataSort();
rowVector=dSort.queryData(sql, paras);
return rowVector;
}
public Vector<Vector<String>> queryData(String sql,String[]paras) {
Vector<Vector<String>>rowVector=null;
sql+=match;
DataSort dataSort=new DataSort();
rowVector=dataSort.queryData(sql, paras);
colum=dataSort.sortedColumn();
return rowVector;
}
public boolean updateData(String sql,String[]paras) {
sql+=match;
DataSort dataSort=new DataSort();
dataSort.updateData(sql, paras);
return dataSort.updateData(sql, paras);
}
public boolean createData(String sql,String[]paras,String[]paras2) {
sql+=match;
DataSort dataSort=new DataSort();
dataSort.updateData(sql, paras);
dataSort=new DataSort();
boolean isSuccess=dataSort.updateData("insert into login (u_account,u_password) values (?,?)", paras2);
dataSort=null;
return isSuccess;
}
public boolean deleteDate(String sql,String[]paras,String para) {
sql+=match;
DataSort dataSort=new DataSort();
dataSort.updateData("delete from login where u_account in ("+para+")", paras);
dataSort=new DataSort();
boolean isSuccess=dataSort.updateData(sql, paras);
dataSort=null;
return isSuccess;
}
public Vector<String> getColumn() {
return colum;
}
}
package along.chatserver.dbaccess;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class SqlHelper {
private Connection conn=null;
private PreparedStatement ps=null;
private ResultSet rs=null;
private String sqlDriver="com.microsoft.jdbc.sqlserver.SQLServerDriver";
private String serverIp="//127.0.0.1:1433";
// private String serverIp="//adsl.haiyualong.10dig.net:1433";
private String dbIp="jdbc:microsoft:sqlserver:"+serverIp+";databaseName=I_M";
private String account="sa";
private String passwd="n";
public SqlHelper() {
try {
Class.forName(sqlDriver);
conn=DriverManager.getConnection(dbIp,account,passwd);
} catch (Exception e) {
e.printStackTrace();
}
}
public ResultSet queryDatabase(String sql,String[]paras) {
try {
int len=paras.length;
ps=conn.prepareStatement(sql);
for(int i=0;i<len;i++){
ps.setString(i+1, paras[i]);
}
rs=ps.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
return rs;
}
public void updateDatabase(String sql,String[]paras) throws SQLException {
int len=paras.length;
ps=conn.prepareStatement(sql);
for(int i=0;i<len;i++){
ps.setString(i+1, paras[i]);
}
ps.executeUpdate();
}
public void closeConnection() {
try {
if(rs!=null) rs.close();
rs=null;
if(ps!=null) ps.close();
ps=null;
if(conn!=null) conn.close();
conn=null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
package along.chatserver.model;
import java.io.IOException;
import java.util.Vector;
import along.chatserver.common.MessageInfo;
import along.chatserver.tools.ServerTools;
public class ChatRoom {
private String roomName;
private Vector<String>roomUserAccount;
private String password;
private String owner;
private int len=0;
private Vector<String>tempVector;
public ChatRoom(String roomName,String password,String owner) {
this.roomName=roomName;
this.password=password;
this.owner=owner;
tempVector=new Vector<String>();
tempVector.add(roomName);
tempVector.add(owner);
tempVector.add(ServerTools.getCurrentTime(null));
ServerTools.getChatRoomVector().add(tempVector);
ServerTools.getServerUI().updateChatRoomTable();
roomUserAccount=new Vector<String>();
}
public String getRoomName() {
return roomName;
}
public Vector<String> getRoomUserAccount() {
return roomUserAccount;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public void sendMessages(MessageInfo messageInfo) {
for(int i=0;i<len;i++){
if(messageInfo.getSender().equals(roomUserAccount.get(i)))
continue;
try {
ClientSocketThreads.getAllClientSockets().get(roomUserAccount.get(i)).getOos().writeObject
(messageInfo);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void setLen() {
this.len = roomUserAccount.size();
if(len<1){
ChatRoomsManage.getAllChatRoom().remove(roomName);
ServerTools.getChatRoomVector().remove(tempVector);
ServerTools.getServerUI().updateChatRoomTable();
ServerTools.getServerUI().logRecord("聊天室 "+roomName+" 剩余 "+len+" 人,将被系统自动关
闭!",ServerTools.getCurrentTime(null));
}
}
public String getOwner() {
return owner;
}
}
package along.chatserver.model;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;
public class ChatRoomsManage {
private static HashMap<String, ChatRoom> allChatRoom=new HashMap<String, ChatRoom>();
public static HashMap<String, ChatRoom> getAllChatRoom() {
return allChatRoom;
}
public static Vector<String> getAllChatRoomNames() {
Iterator<String>iterator=allChatRoom.keySet().iterator();
Vector<String>roomNames=new Vector<String>();
while (iterator.hasNext()) {
roomNames.add(iterator.next());
}
return roomNames;
}
}
package along.chatserver.model;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;
import along.chatserver.common.MessageInfo;
import along.chatserver.common.MessageType;
import along.chatserver.common.UserInfo;
import along.chatserver.datasort.DataSort;
import along.chatserver.datasort.EventProcess;
import along.chatserver.tools.ServerTools;
public class ChatServer {
private ServerSocket ss;
public ChatServer() {
new Thread(new ServerThread()).start();
}
public void stopServer() {
try {
String[]onlineUsers=ClientSocketThreads.getOnlineUser();
int len=onlineUsers.length;
for(int i=0;i<len;i++){
try {
ClientSocketThreads.getAllClientSockets().get(onlineUsers[i]).closeConnection();
} catch (Exception e) {}
}
ClientSocketThreads.getAllClientSockets().clear();
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void checkUserLogin(Socket socket) throws IOException, ClassNotFoundException {
ObjectInputStream ois=new ObjectInputStream(socket.getInputStream());
ObjectOutputStream oos=new ObjectOutputStream(socket.getOutputStream());
MessageInfo messageInfo=new MessageInfo();
UserInfo info=(UserInfo)ois.readObject();
if(info.getType()==3){
regApply(socket,oos,info);
ois.close();
return;
}
String[]paras={info.getUserAccount(),info.getUserPasswd()};
EventProcess eProcess=new EventProcess();
Vector<Vector<String>>user=eProcess.getLoginProcess(paras);
if(user.size()>0){
messageInfo.setMsgType(MessageType.TYPE_1);
oos.writeObject(messageInfo);
ClientSocketThread socketThread=new ClientSocketThread(socket,info.getUserAccount());
new Thread(socketThread).start();
ClientSocketThreads.getAllClientSockets().put(info.getUserAccount(), socketThread);
}
else {
messageInfo.setMsgType(MessageType.TYPE_2);
oos.writeObject(messageInfo);
oos.close();
ois.close();
socket.close();
}
}
private void regApply(Socket socket,ObjectOutputStream oos,UserInfo info) throws IOException {
String[]regInfo=info.getRegInfo();
String sql="select userAccount from userInfo where userAccount=?";
String[]paras={regInfo[0]};
DataSort dataSort=new DataSort();
MessageInfo messageInfo=new MessageInfo();
String regTime=ServerTools.getCurrentTime(null);
if(dataSort.queryData(sql, paras).size()<1){
sql="insert into userInfo values (?,?,?,?,?,?,?,?)";
paras=new String[8];
for(int i=0;i<7;i++){
paras[i]=regInfo[i];
}
paras[7]=regTime;
boolean b=false;
dataSort=new DataSort();
if(dataSort.updateData(sql, paras)){
sql="insert into login values (?,?)";
paras=new String[2];
paras[0]=regInfo[0];
paras[1]=regInfo[7];
dataSort=new DataSort();
b=dataSort.updateData(sql, paras);
}
if(b){
ServerTools.getServerUI().logRecord("用户注册新账号 "+paras[0]+" 成功",regTime);
ServerTools.getServerUI().updateAllUserTable();
messageInfo.setContent("注册账号成功!");
}else
messageInfo.setContent("数据库读写错误,注册账号失败!");
}else{
messageInfo.setContent("该账号已存在,请重新输入一个不同的账号");
}
oos.writeObject(messageInfo);
oos.close();
socket.close();
}
class ServerThread implements Runnable{
@Override
public void run() {
try {
ss=new ServerSocket(3002);
while (true) {
try {
Socket socket=ss.accept();
checkUserLogin(socket);
} catch (Exception e) {
if(ss.isClosed())
return;
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
package along.chatserver.model;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Vector;
import along.chatserver.common.MessageInfo;
import along.chatserver.common.MessageType;
import along.chatserver.datasort.DataSort;
import along.chatserver.tools.ServerTools;
import along.chatserver.tools.UserInfoManage;
public class ClientSocketThread implements Runnable{
private Socket socket;
private String myAccount,logTime;
private ObjectOutputStream oos;
private ObjectInputStream ois;
private Vector<String> friendsVector=null;
private Vector<String>myChatRooms;
private Vector<String>onlineTemp;
public ClientSocketThread(Socket socket,String account) {
this.socket=socket;
this.myAccount=account;
logTime=ServerTools.getCurrentTime(null);
onlineTemp=new Vector<String>();
String sql="select userAccount,userName from userInfo where userAccount=?";
String[]paras={myAccount};
onlineTemp=new DataSort().queryData(sql, paras).get(0);
onlineTemp.add(logTime);
ServerTools.getOnlineRowVector().add(onlineTemp);
ServerTools.getServerUI().updateOnlineTable();
myChatRooms=new Vector<String>();
try {
ois=new ObjectInputStream(socket.getInputStream());
oos=new ObjectOutputStream(socket.getOutputStream());
sendFriendList();
getOfflineMessage();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 读取用户离线消息文件,若有离线消息,发送给用户,并将离线消息文件清空.
* @throws IOException
*/
private void getOfflineMessage() throws IOException {
Vector<MessageInfo>offlineMessages=UserInfoManage.readOfflineMessages(myAccount);
int len=offlineMessages.size();
if(len>0){
for(int i=0;i<len;i++){
oos.writeObject(offlineMessages.get(i));
}
offlineMessages.removeAllElements();
UserInfoManage.writeOfflineMessage(myAccount, offlineMessages);
}
}
@Override
public void run() {
try {
while (true) {
MessageInfo messageInfo=(MessageInfo)ois.readObject();
switch (messageInfo.getMsgType()) {
case MessageType.TYPE_3:
processMSG3(messageInfo);
break;
case MessageType.TYPE_4:
processMSG4();
break;
case MessageType.TYPE_6:
processMSG6();
break;
case MessageType.TYPE_11:
processMSG11(messageInfo);
break;
case MessageType.TYPE_12:
processMSG12(messageInfo);
break;
case MessageType.TYPE_16:
processMSG16(messageInfo);
break;
case MessageType.TYPE_17:
processMSG17(messageInfo);
break;
case MessageType.TYPE_18:
processMSG18(messageInfo);
break;
case MessageType.TYPE_19:
processMSG19(messageInfo);
break;
case MessageType.TYPE_22:
processMSG22(messageInfo);
break;
case MessageType.TYPE_24:
processMSG24(messageInfo);
break;
}
}
} catch (IOException e) {
notifyOffline();
if(socket.isConnected()){
quitClientLeaveChatRoom();
closeConnection();
return;
}
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 用户给好友发送普通信息
* @param messageInfo
* @throws IOException
*/
private void processMSG3(MessageInfo messageInfo) throws IOException{
if(ClientSocketThreads.getAllClientSockets().get(messageInfo.getReceiver())==null){
Vector<MessageInfo>offlineMessages=UserInfoManage.readOfflineMessages(messageInfo.getReceiver());
offlineMessages.add(messageInfo);
UserInfoManage.writeOfflineMessage(messageInfo.getReceiver(), offlineMessages);
return;
}
ClientSocketThreads.getAllClientSockets().get(messageInfo.getReceiver()).getOos().writeObject(messageInfo);
}
/**
* 用户登陆并请求在线好友
* @throws IOException
*/
private void processMSG4() throws IOException{
ServerTools.getServerUI().logRecord("用户 "+myAccount+" 登陆服务器",logTime);
MessageInfo messageInfo5=new MessageInfo();
messageInfo5.setMsgType(MessageType.TYPE_5);
int len4=friendsVector.size();
Vector<String>onlineFriendAccounts=new Vector<String>();
for(int i=0;i<len4;i++){
ClientSocketThread temp=ClientSocketThreads.getAllClientSockets().get(friendsVector.get(i));
if(temp!=null)
onlineFriendAccounts.add(friendsVector.get(i));
}
messageInfo5.setFriendVector(onlineFriendAccounts);
oos.writeObject(messageInfo5);
}
/**
* 用户广播好友上线通知
*/
private void processMSG6() {
MessageInfo messageInfo6=new MessageInfo();
messageInfo6.setMsgType(MessageType.TYPE_6);
messageInfo6.setContent(myAccount);
int len6=friendsVector.size();
for(int i=0;i<len6;i++){
ClientSocketThread temp=ClientSocketThreads.getAllClientSockets().get(friendsVector.get(i));
if(temp!=null){
try {
temp.getOos().writeObject(messageInfo6);
} catch (Exception e) {}
}
}
}
/**
* 用户查询用户信息
* @param messageInfo
* @throws IOException
*/
private void processMSG11(MessageInfo messageInfo) throws IOException{
String[] paras={messageInfo.getContent()};
String sql="select *from userInfo where userAccount=?";
DataSort dataSort=new DataSort();
Vector<Vector<String>>userInfo=dataSort.queryData(sql, paras);
Vector<String>column=dataSort.sortedColumn();
MessageInfo messageInfo10=new MessageInfo();
messageInfo10.setMsgType(MessageType.TYPE_10);
messageInfo10.setRowVector(userInfo);
messageInfo10.setColumnVector(column);
oos.writeObject(messageInfo10);
}
/**
* 用户发送添加好友的申请
* @param messageInfo
* @throws IOException
*/
private void processMSG12(MessageInfo messageInfo) throws IOException {
String targetAccount=messageInfo.getContent();
MessageInfo messageInfo13=new MessageInfo();
messageInfo13.setMsgType(MessageType.TYPE_13);
if(friendsVector.contains(targetAccount)){
messageInfo13.setContent(targetAccount+" 已经是你的好友,不需要再次添加");
oos.writeObject(messageInfo13);
return;
}
friendsVector.add(targetAccount);
UserInfoManage.writeFriendList(myAccount, friendsVector);
Vector<String>targetFriendsVector=UserInfoManage.readFriendList(targetAccount);
if(!targetFriendsVector.contains(myAccount)){
targetFriendsVector.add(myAccount);
UserInfoManage.writeFriendList(targetAccount, targetFriendsVector);
ClientSocketThread temp=ClientSocketThreads.getAllClientSockets().get(targetAccount);
if(temp!=null){
MessageInfo messageInfo14=new MessageInfo();
messageInfo14.setMsgType(MessageType.TYPE_14);
messageInfo14.setOnline(true);
messageInfo14.setContent(myAccount);
temp.updateFriendsVector();
try {
temp.getOos().writeObject(messageInfo14);
} catch (Exception e) {}
}
}
messageInfo13.setContent("已成功添加 "+targetAccount+" 为好友!");
oos.writeObject(messageInfo13);
MessageInfo messageInfo14=new MessageInfo();
messageInfo14.setMsgType(MessageType.TYPE_14);
messageInfo14.setOnline(false);
if(ClientSocketThreads.getAllClientSockets().containsKey(targetAccount))
messageInfo14.setOnline(true);
messageInfo14.setContent(targetAccount);
oos.writeObject(messageInfo14);
}
/**
* 用户发送删除好友的申请
* @param messageInfo
* @throws IOException
*/
private void processMSG16(MessageInfo messageInfo) throws IOException{
friendsVector.remove(messageInfo.getContent());
UserInfoManage.writeFriendList(myAccount, friendsVector);
Vector<String>targetFriendVector=UserInfoManage.readFriendList(messageInfo.getContent());
targetFriendVector.remove(myAccount);
UserInfoManage.writeFriendList(messageInfo.getContent(), targetFriendVector);
MessageInfo messageInfo15;
if(ClientSocketThreads.getAllClientSockets().containsKey(messageInfo.getContent())){
messageInfo15=new MessageInfo();
messageInfo15.setMsgType(MessageType.TYPE_15);
messageInfo15.setContent(myAccount);
ClientSocketThreads.getAllClientSockets().get(messageInfo15.getContent()).updateFriendsVector();
try {
ClientSocketThreads.getAllClientSockets().get(messageInfo.getContent()).getOos
().writeObject(messageInfo15);
} catch (Exception e) {}
}
messageInfo15=new MessageInfo();
messageInfo15.setMsgType(MessageType.TYPE_15);
messageInfo15.setContent(messageInfo.getContent());
oos.writeObject(messageInfo15);
}
/**
* 用户申请进入聊天室
* @param messageInfo
* @throws IOException
*/
private void processMSG17(MessageInfo messageInfo) throws IOException {
ChatRoom chatRoom=ChatRoomsManage.getAllChatRoom().get(messageInfo.getReceiver());
if(chatRoom==null){
messageInfo=new MessageInfo();
messageInfo.setMsgType(MessageType.TYPE_20);
messageInfo.setReceiver(null);
messageInfo.setContent("进入聊天室失败,没有找到此聊天室,可能已经关闭");
oos.writeObject(messageInfo);
return;
}
if(chatRoom.getRoomUserAccount().contains(myAccount)){
messageInfo=new MessageInfo();
messageInfo.setMsgType(MessageType.TYPE_20);
messageInfo.setReceiver(null);
messageInfo.setContent("你已经在该聊天室中,不能再次进入!");
oos.writeObject(messageInfo);
return;
}
if(!chatRoom.getPassword().equals(messageInfo.getContent())){
messageInfo=new MessageInfo();
messageInfo.setMsgType(MessageType.TYPE_20);
messageInfo.setReceiver(null);
messageInfo.setContent("你输入的聊天室密码错误,无法进入聊天室");
oos.writeObject(messageInfo);
return;
}
chatRoom.getRoomUserAccount().add(myAccount);
chatRoom.setLen();
myChatRooms.add(messageInfo.getReceiver());
ServerTools.getServerUI().logRecord("用户 "+myAccount+" 进入聊天室 "+messageInfo.getReceiver(),
ServerTools.getCurrentTime(null));
chatRoom.sendMessages(messageInfo);
messageInfo=new MessageInfo();
messageInfo.setMsgType(MessageType.TYPE_20);
messageInfo.setSender(chatRoom.getRoomName());
messageInfo.setReceiver(myAccount);
messageInfo.setObject(chatRoom.getRoomUserAccount());
oos.writeObject(messageInfo);
}
/**
* 用户离开聊天室
* @param messageInfo
* @throws IOException
*/
private void processMSG18(MessageInfo messageInfo) {
myChatRooms.remove(messageInfo.getReceiver());
if(!ChatRoomsManage.getAllChatRoom().containsKey(messageInfo.getReceiver()))
return;
if(!ChatRoomsManage.getAllChatRoom().get(messageInfo.getReceiver()).getRoomUserAccount().contains
(myAccount)){
ServerTools.getServerUI().logRecord("用户 "+myAccount+" 非法操作,未在聊天室的情况下发送离开消息到聊
天室 "+messageInfo.getReceiver(),ServerTools.getCurrentTime(null));
return;
}
ChatRoom chatRoom=ChatRoomsManage.getAllChatRoom().get(messageInfo.getReceiver());
ServerTools.getServerUI().logRecord("用户"+myAccount+"离开聊天室"+messageInfo.getReceiver
(),ServerTools.getCurrentTime(null));
chatRoom.getRoomUserAccount().remove(messageInfo.getSender());
chatRoom.setLen();
if(chatRoom.getRoomUserAccount().size()<1){
chatRoom=null;
return;
}
chatRoom.sendMessages(messageInfo);
}
/**
* 用户发送信息到聊天室
* @param messageInfo
* @throws IOException
*/
private void processMSG19(MessageInfo messageInfo) throws IOException {
if(!ChatRoomsManage.getAllChatRoom().containsKey(messageInfo.getReceiver())){
messageInfo=new MessageInfo();
messageInfo.setMsgType(MessageType.TYPE_19);
messageInfo.setSender("系统消息:");
messageInfo.setContent("聊天室已经关闭....");
oos.writeObject(messageInfo);
return;
}
if(!ChatRoomsManage.getAllChatRoom().get(messageInfo.getReceiver()).getRoomUserAccount().contains
(myAccount)){
ServerTools.getServerUI().logRecord("用户 "+myAccount+" 非法操作,未在聊天室的情况下发送消息到聊天室
"+messageInfo.getReceiver(),ServerTools.getCurrentTime(null));
messageInfo=new MessageInfo();
messageInfo.setMsgType(MessageType.TYPE_19);
messageInfo.setSender("系统消息:");
messageInfo.setContent("你并未在该聊天室中,不能给该聊天室发送信息!!");
oos.writeObject(messageInfo);
return;
}
ChatRoomsManage.getAllChatRoom().get(messageInfo.getReceiver()).sendMessages(messageInfo);
}
/**
* 用户申请创建新聊天室
* @param messageInfo
* @throws IOException
*/
private void processMSG22(MessageInfo messageInfo) throws IOException {
if(messageInfo.getReceiver().toCharArray().length<3){
messageInfo=new MessageInfo();
messageInfo.setMsgType(MessageType.TYPE_23);
messageInfo.setSender(null);
messageInfo.setContent("聊天室的名称不能少于三个字符!\n你的客户端出现异常,请不要使用修改版的客户端,
以防盗号");
oos.writeObject(messageInfo);
return;
}
if(ChatRoomsManage.getAllChatRoom().containsKey(messageInfo.getReceiver())){
ServerTools.getServerUI().logRecord("用户 "+myAccount+" 申请创建新聊天室:
"+messageInfo.getReceiver()+" 失败,原因是该聊天室已存在!",ServerTools.getCurrentTime(null));
String receiver=messageInfo.getReceiver();
messageInfo=new MessageInfo();
messageInfo.setMsgType(MessageType.TYPE_23);
messageInfo.setSender(null);
messageInfo.setContent("聊天室的名称"+receiver+"已被使用,请修改你所创建的聊天室的名字");
oos.writeObject(messageInfo);
return;
}
ChatRoom chatRoom=new ChatRoom(messageInfo.getReceiver(), messageInfo.getContent(),messageInfo.getSender
());
ChatRoomsManage.getAllChatRoom().put(messageInfo.getReceiver(), chatRoom);
myChatRooms.add(messageInfo.getReceiver());
chatRoom.getRoomUserAccount().add(myAccount);
chatRoom.setLen();
messageInfo=new MessageInfo();
messageInfo.setMsgType(MessageType.TYPE_23);
messageInfo.setSender(chatRoom.getRoomName());
messageInfo.setReceiver(myAccount);
messageInfo.setObject(chatRoom.getRoomUserAccount());
oos.writeObject(messageInfo);
ServerTools.getServerUI().logRecord("用户"+myAccount+" 创建了聊天室 "+chatRoom.getRoomName
(),ServerTools.getCurrentTime(null));
}
/**
* 用户请求根据所发送的关键字查询所有已存在的聊天室
* @param messageInfo
* @throws IOException
*/
private void processMSG24(MessageInfo messageInfo) throws IOException {
String content =messageInfo.getContent();
messageInfo=new MessageInfo();
messageInfo.setMsgType(MessageType.TYPE_25);
Vector<String>columnVector=new Vector<String>();
columnVector.add("房间名称");
columnVector.add("有无密码");
columnVector.add("创建者");
Vector<Vector<String>>chatRooms=new Vector<Vector<String>>();
if(content.equals("")){
Vector<String>roomNamesVector=ChatRoomsManage.getAllChatRoomNames();
int len=roomNamesVector.size();
for(int i=0;i<len;i++){
Vector<String>tempRow=new Vector<String>();
tempRow.add(roomNamesVector.get(i));
if(ChatRoomsManage.getAllChatRoom().get(roomNamesVector.get(i)).getPassword().equals(""))
tempRow.add("无密码");
else
tempRow.add("有密码");
tempRow.add(ChatRoomsManage.getAllChatRoom().get(roomNamesVector.get(i)).getOwner());
chatRooms.add(tempRow);
}
messageInfo.setSender(myAccount);
messageInfo.setRowVector(chatRooms);
messageInfo.setColumnVector(columnVector);
oos.writeObject(messageInfo);
return;
}
ChatRoom chatRoom=ChatRoomsManage.getAllChatRoom().get(content);
if(chatRoom==null){
messageInfo.setSender(null);
messageInfo.setContent("未找到与所提供的关键字 "+content+" 相匹配的聊天室!");
oos.writeObject(messageInfo);
return;
}
Vector<String>tempRow=new Vector<String>();
tempRow.add(chatRoom.getRoomName());
if(chatRoom.getPassword().equals(""))
tempRow.add("无密码");
else
tempRow.add("有密码");
tempRow.add(chatRoom.getOwner());
chatRooms.add(tempRow);
messageInfo.setSender("");
messageInfo.setRowVector(chatRooms);
messageInfo.setColumnVector(columnVector);
oos.writeObject(messageInfo);
}
/**
* 用户广播下线通知给好友
*/
private void notifyOffline() {
MessageInfo messageInfo7=new MessageInfo();
messageInfo7.setMsgType(MessageType.TYPE_7);
messageInfo7.setContent(myAccount);
int len=friendsVector.size();
for(int i=0;i<len;i++){
ClientSocketThread temp=ClientSocketThreads.getAllClientSockets().get(friendsVector.get(i));
if(temp!=null){
try {
temp.getOos().writeObject(messageInfo7);
} catch (Exception e2) {}
}
}
}
/**
* 更新用户服务器端的好友列表
*/
public void updateFriendsVector() {
friendsVector=UserInfoManage.readFriendList(myAccount);
}
/**
* 发送用户的好友列表给用户
* @throws IOException
*/
public void sendFriendList() throws IOException {
friendsVector=UserInfoManage.readFriendList(myAccount);
Vector<String>tempFriendVector=new Vector<String>();
tempFriendVector.addAll(friendsVector);
MessageInfo messageInfo=new MessageInfo();
messageInfo.setMsgType(MessageType.TYPE_8);
messageInfo.setFriendVector(tempFriendVector);
oos.writeObject(messageInfo);
}
public ObjectOutputStream getOos() {
return oos;
}
/**
* 用户退出客户端程序,检测用户是否处于聊天室中,若处于聊天室,也一并退出聊天室
* @throws IOException
*/
public void quitClientLeaveChatRoom() {
int len=myChatRooms.size();
for(int i=0;i<len;){
MessageInfo messageInfo=new MessageInfo();
messageInfo.setMsgType(MessageType.TYPE_18);
messageInfo.setReceiver(myChatRooms.get(i));
messageInfo.setSender(myAccount);
processMSG18(messageInfo);
len-=1;
}
}
/**
* 用户退出程序,关闭服务器与客户端的连接,并将用户从上线用户列表中移除
*/
public void closeConnection() {
ClientSocketThreads.getAllClientSockets().remove(myAccount);
try {
oos.close();
ois.close();
socket.close();
ServerTools.getServerUI().logRecord("用户 "+myAccount+" 退出服务器",ServerTools.getCurrentTime
(null));
ServerTools.getOnlineRowVector().remove(onlineTemp);
ServerTools.getServerUI().updateOnlineTable();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package along.chatserver.model;
import java.util.HashMap;
import java.util.Iterator;
public class ClientSocketThreads {
private static HashMap<String, ClientSocketThread> allClientSockets=new HashMap<String, ClientSocketThread>();
public ClientSocketThreads() {
}
public static HashMap<String, ClientSocketThread> getAllClientSockets() {
return allClientSockets;
}
public static String[] getOnlineUser() {
Iterator<String> account=allClientSockets.keySet().iterator();
int len=allClientSockets.size();
String []accounts=new String[len];
int i=0;
while (account.hasNext()) {
accounts[i]=account.next();
i++;
}
return accounts;
}
}
package along.chatserver.model;
import java.util.Vector;
import javax.swing.table.AbstractTableModel;
import along.chatserver.datasort.DataSort;
/**
* 查询数据,并将数据显示在列表中
* @author Along
*
*/
public class DataModel extends AbstractTableModel{
/**
*
*/
private static final long serialVersionUID = 1L;
private Vector<Vector<String>> rowVector=null;
private Vector<String> colum=null;
public DataModel(Vector<Vector<String>> rowVector,Vector<String> colum) {
this.rowVector=rowVector;
this.colum=colum;
}
public Vector<Vector<String>> queryData(String sql,String[]paras){
DataSort dataSort=new DataSort();
rowVector=dataSort.queryData(sql, paras);
colum=dataSort.sortedColumn();
dataSort=null;
return rowVector;
}
@Override
public int getColumnCount() {
if(colum==null)
return 0;
return colum.size();
}
@Override
public int getRowCount() {
if(rowVector==null)
return 0;
return rowVector.size();
}
@Override
public Object getValueAt(int row, int colum) {
//返回第 row 行,第 colum 列的内容给JTable对象用以填充相对应的单元格
return rowVector.get(row).get(colum);
}
@Override
public String getColumnName(int column) {
//返回第 column列的值用作 JTable 对象相对应位置的标题
return this.colum.get(column);
}
}
package along.chatserver.tools;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Vector;
import along.chatserver.view.ServerUI;
public class ServerTools {
private static ServerUI serverUI;
private static Vector<Vector<String>>onlineRowVector=new Vector<Vector<String>>();
private static Vector<Vector<String>>chatRoomVector=new Vector<Vector<String>>();
public static ServerUI getServerUI() {
return serverUI;
}
public static void setServerUI(ServerUI serverUI) {
ServerTools.serverUI = serverUI;
}
public static Vector<Vector<String>> getOnlineRowVector() {
return onlineRowVector;
}
public static String getCurrentTime(Date date){
if(date==null)
date=new Date(System.currentTimeMillis());
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("HH:mm:ss ' 'yyyy'-'MM'-'dd");
String time=simpleDateFormat.format(date);
return time;
}
public static Vector<Vector<String>> getChatRoomVector() {
return chatRoomVector;
}
}
package along.chatserver.tools;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Vector;
import along.chatserver.common.MessageInfo;
public class UserInfoManage {
@SuppressWarnings("unchecked")
public static Vector<String> readFriendList(String account) {
Vector<String>friends=null;
ObjectInputStream ois=null;
try {
ois=new ObjectInputStream(new FileInputStream("user_files"+File.separator+account
+"_files"+File.separator+account+"_friend_list"));
friends=(Vector<String>)ois.readObject();
} catch (FileNotFoundException e) {
System.out.println("未找到用户好友文档");
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally{
try {
if(ois!=null)
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(friends==null)
return new Vector<String>();
return friends;
}
public static void writeFriendList(String account,Vector<String> friends) {
ObjectOutputStream oos=null;
File file=new File("user_files"+File.separator+account+"_files");
if(!file.exists()||!file.isDirectory()){
file.mkdirs();
}
try {
oos=new ObjectOutputStream(new FileOutputStream("user_files"+File.separator+account
+"_files"+File.separator+account+"_friend_list"));
oos.writeObject(friends);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(oos!=null)
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@SuppressWarnings("unchecked")
public static Vector<MessageInfo> readOfflineMessages(String targeAccount) {
Vector<MessageInfo>offlineMessages=null;
ObjectInputStream ois=null;
try {
ois=new ObjectInputStream(new FileInputStream("user_files"+File.separator+targeAccount
+"_files"+File.separator+targeAccount+"_offline_messages"));
offlineMessages=(Vector<MessageInfo>)ois.readObject();
} catch (FileNotFoundException e) {
System.out.println("未找到用户离线消息文档");
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally{
try {
if(ois!=null)
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(offlineMessages==null)
return new Vector<MessageInfo>();
return offlineMessages;
}
public static void writeOfflineMessage(String targeAccount,Vector<MessageInfo> offlineMessages) {
ObjectOutputStream oos=null;
File file=new File("user_files"+File.separator+targeAccount+"_files");
if(!file.exists()||!file.isDirectory()){
file.mkdirs();
}
try {
oos=new ObjectOutputStream(new FileOutputStream("user_files"+File.separator+targeAccount
+"_files"+File.separator+targeAccount+"_offline_messages"));
oos.writeObject(offlineMessages);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(oos!=null)
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
package along.chatserver.view;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;
import along.chatserver.model.ChatServer;
import along.chatserver.model.DataModel;
import along.chatserver.tools.ServerTools;
public class ServerUI extends JFrame implements ActionListener{
private static final long serialVersionUID = 1L;
private JButton startServerButton,stopServerButton;
private ChatServer server;
private JPanel ctrlPanel,onlineUserPanel,allUserPanel,chatRoomPanel,logPanel;
private JTabbedPane tabbedPane;
private JTable onlineUserTable,allUserTable,chatRoomTable;
private JTextArea logArea;
private JScrollBar scrollBar;
private Vector<String>usersColumnVector,chatRoomColumnVector;
public ServerUI() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
tabbedPane=new JTabbedPane();
initCtrlPanel();
initOnlineUserPanel();
initAllUserPanel();
initChatRoomPanel();
initLogPanel();
add(tabbedPane);
setSize(800, 600);
setLocation(200, 100);
setIconImage(new ImageIcon("image/qq.gif").getImage());
setVisible(true);
}
private void initCtrlPanel() {
startServerButton=new JButton("启动服务器");
startServerButton.addActionListener(this);
stopServerButton=new JButton("关闭服务器");
stopServerButton.addActionListener(this);
stopServerButton.setEnabled(false);
ctrlPanel=new JPanel();
ctrlPanel.add(startServerButton);
ctrlPanel.add(stopServerButton);
tabbedPane.add("控制面板",ctrlPanel);
}
private void initOnlineUserPanel() {
usersColumnVector=new Vector<String>();
usersColumnVector.add("用户账号");
usersColumnVector.add("用户姓名");
usersColumnVector.add("上线时间");
onlineUserPanel=new JPanel(new BorderLayout());
onlineUserTable=new JTable();
JScrollPane scrollPane=new JScrollPane(onlineUserTable);
onlineUserTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
onlineUserPanel.add(scrollPane);
tabbedPane.add("在线用户列表",onlineUserPanel);
}
private void initAllUserPanel() {
allUserPanel=new JPanel(new BorderLayout());
allUserTable=new JTable();
JScrollPane scrollPane=new JScrollPane(allUserTable);
allUserTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
allUserPanel.add(scrollPane);
tabbedPane.add("所有用户列表",allUserPanel);
}
private void initChatRoomPanel() {
chatRoomColumnVector=new Vector<String>();
chatRoomColumnVector.add("聊天室名称");
chatRoomColumnVector.add("聊天室创建人");
chatRoomColumnVector.add("聊天室创建时间");
chatRoomPanel=new JPanel(new BorderLayout());
chatRoomTable=new JTable();
JScrollPane scrollPane=new JScrollPane(chatRoomTable);
chatRoomTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
chatRoomPanel.add(scrollPane);
tabbedPane.add("聊天室列表",chatRoomPanel);
}
private void initLogPanel() {
logPanel=new JPanel();
logArea=new JTextArea(30,70);
logArea.setEditable(false);
JScrollPane scrollPane=new JScrollPane(logArea);
scrollBar=scrollPane.getVerticalScrollBar();
logPanel.add(scrollPane);
tabbedPane.add("日志",logPanel);
}
public void logRecord(String logInfo,String time) {
logArea.append(time+"\t"+logInfo+"\n");
setJScrollBar();
}
private void setJScrollBar() {
scrollBar.setValue(scrollBar.getMaximum());
}
public void updateOnlineTable() {
DataModel dataModel=new DataModel(ServerTools.getOnlineRowVector(),usersColumnVector);
onlineUserTable.setModel(dataModel);
}
public void updateAllUserTable() {
String sql="select * from userInfo";
String[]paras=new String[0];
DataModel dataModel=new DataModel(null, null);
dataModel.queryData(sql, paras);
allUserTable.setModel(dataModel);
dataModel=null;
}
public void updateChatRoomTable() {
DataModel dataModel=new DataModel(ServerTools.getChatRoomVector(),chatRoomColumnVector);
chatRoomTable.setModel(dataModel);
}
public static void main(String[]args) {
ServerTools.setServerUI(new ServerUI());
}
@Override
public void actionPerformed(ActionEvent e) {
Object obj=e.getSource();
if(obj==startServerButton){
server=new ChatServer();
startServerButton.setEnabled(false);
stopServerButton.setEnabled(true);
logRecord("聊天服务器已启动运行",ServerTools.getCurrentTime(null));
updateAllUserTable();
}
else if (obj==stopServerButton) {
server.stopServer();
stopServerButton.setEnabled(false);
startServerButton.setEnabled(true);
server=null;
logRecord("聊天服务器已关闭运行",ServerTools.getCurrentTime(null));
}
}
}