
com.langsin.LZChat.client 项目的代码

首先是client包的
1.ClientConServer.java
package client;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import model.ToolsCreateMsg;
import model.ToolsParseMsg;
import msg.MsgHead;
import msg.MsgLogin;
import msg.MsgLoginResp;
import msg.MsgReg;
import msg.MsgRegResp;
import msg.MsgType;
import tools.LogTools;
/***
* 客户端与服务器的即时通信模块
*
* @author Administrator
* 1.登陆,注册接口调用;
* 2.在独立线程中接收服务器消息
* 3.将接受到的信息交给ManageUI管理
*/
public class ClientConServer extends Thread {
private static ClientConServer ccs; // 本类单实例对象
private Socket client; // 与服务器连接对象
private DataOutputStream dous; // 输出流对象
private DataInputStream dis; // 输入流对象
private ArrayList<ClientMsgListener> listeners = new ArrayList<ClientMsgListener>();
/** 不需要创建对象,所以构造器私有 */
private ClientConServer() {
}
public static ClientConServer getCcs() {
if (null == ccs)
ccs = new ClientConServer();
return ccs;
}
/** 连结上服务器, 返回是否连结成功 */
public boolean ConServer() {
try {
client = new Socket(MsgType.serverIP, MsgType.serverPort);
this.dous = new DataOutputStream(client.getOutputStream());
this.dis = new DataInputStream(client.getInputStream());
return true;
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
/**
* 注册服务器
*
* @param pwd
* @param nickname
* @param sex
* @param icon
* @return 注册结果 -1 失败 其他事注册到的qq号
*/
public int regServer(String pwd, String nickname, String sex, byte icon) {
try {
MsgReg mr = new MsgReg();
mr.setTotalLen(4 + 1 + 4 + 4 + 10 + 10 + 10 + 1);
mr.setType(MsgType.command_reg);
mr.setDest(MsgType.SERVER_QQ_NUMBER);
mr.setSrc(0);
mr.setNickname(nickname);
mr.setPwd(pwd);
mr.setSex(sex);
mr.setIcon(icon);
this.sendMsg(mr);
MsgRegResp mrr = (MsgRegResp) readFromServer();
LogTools.INFO(this.getClass(), mrr.toString());
if (mrr.getState() == 0)
return mrr.getDest();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return -1;
}
/**
* 登陆到服务器
*
* @param qq
* @param pwd
* @return 是否登陆成功
*/
public boolean loginServer(int qq, String pwd) {
try {
MsgLogin ml = new MsgLogin();
ml.setTotalLen(4 + 1 + 4 + 4 + 10);
ml.setType(MsgType.command_login);
ml.setDest(MsgType.SERVER_QQ_NUMBER);
ml.setSrc(qq);
ml.setPwd(pwd);
ml.setQq(qq);
this.sendMsg(ml);
MsgLoginResp mlr = (MsgLoginResp) readFromServer();
LogTools.INFO(this.getClass(), mlr.toString());
if (mlr.getState() == 0) {
return true;
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
@Override
public void run() {
while (true) {
try {
MsgHead msg = readFromServer();
for (ClientMsgListener listener : listeners) {
System.out.println("run"+msg.getType());
listener.dealMsg(msg);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
break;
}
}
}
/**
* 加入到监听列表中
* @param lisetener
*/
public void addMsgListener(ClientMsgListener lisetener){
this.listeners.add(lisetener);
}
/**
* 从监控列表中删除
* @param lisetener
*/
public void removwMsgListenner(ClientMsgListener lisetener){
this.listeners.remove(lisetener);
}
/*
* 下面是各个界面中写入类属性的代码 (不应在此处)
*
*/
// public static void Find(){
//
// //command_find
// MsgHead msg = new MsgHead();
// msg.setTotalLen(4+1+4+4);
// msg.setSrc(ClientConServer.ownerQQ);
// msg.setDest(MsgType.SERVER_QQ_NUMBER);
// msg.setType(MsgType.command_find);
//
// //command_addFriend
// MsgAddFriend maf = new MsgAddFriend();
// maf.setTotalLen(4+1+4+4+30+4);
// maf.setSrc(ClientConServer.ownerQQ);
// maf.setDest(要加的人的qq);
// maf.setType(MsgType.command_addFriend);
// maf.setNote("备注");
// maf.setFriendQq(要加的人的qq);
//
// //command_addYouResp
// MsgAddYouResp mayr = new MsgAddYouResp();
// mayr.setTotalLen(4+1+4+4+1);
// mayr.setSrc(ClientConServer.ownerQQ);
// mayr.setDest(要加你的人的qq);
// mayr.setType(MsgType.command_addYouResp);
// mayr.setState((byte)0同意 1不同意);
//
// //command_chatText command_chatFile(最后再说)
// MsgChatText mct = new MsgChatText();
// int changdu = content.getBytes().size(); //计算String的字节长度
// mct.setTotalLen(4+1+4+4+20+changdu);
// mct.setSrc(ClientConServer.ownerQQ);
// mct.setDest(要加你的人的qq);
// mct.setType(MsgType.command_chatText);
// mct.setContent(content); //content是要发送的字符串
// mct.setTime("时间 字符串类型 最长20字节");
//
//
// //最后都调用 ClientConServer的发送方法(sendMse)将类发给服务器
//
// }
/**
* 从输入流上读取一条服务器端发来的消息 这个方法会阻塞,必须在独立线程中
*
* @return:读取到的消息对象
*/
public MsgHead readFromServer() throws Exception {
int totalLen = dis.readInt();
LogTools.INFO(this.getClass(), "客户端读到消息总长为:" + totalLen);
byte[] data = new byte[totalLen - 4];
dis.readFully(data); // 读取数据块
MsgHead msg = ToolsParseMsg.parseMsg(data);// 解包为消息对象
LogTools.INFO(this.getClass(), "客户端收到消息:" + msg);
return msg;
}
/** 发送一条消息到服务器的方法 */
public void sendMsg(MsgHead msg) throws Exception {
LogTools.INFO(this.getClass(), "客户端发出消息:" + msg);
byte[] data = ToolsCreateMsg.packMsg(msg);// 打包对象为数据块
this.dous.write(data);// 发送
this.dous.flush();
}
// 关闭与一个客户机的连结
public void closeMe() {
try {
this.client.close();
} catch (Exception ef) {
}
}
}
2.ClientMsgListener.java
1 package client; 2 3 import msg.MsgHead; 4 5 /*** 6 * 接受消息的接口 7 * @author Administrator 8 * 9 */ 10 public interface ClientMsgListener { 11 12 /** 13 * 从服务器接收到的一条信息 14 */ 15 public void dealMsg(MsgHead msg); 16 }
3.ManageUI
package client; import java.util.HashMap; import javax.swing.JFrame; import msg.MsgAddFriendResp; import msg.MsgAddYou; import msg.MsgChatFile; import msg.MsgChatText; import msg.MsgFindResp; import msg.MsgHead; import msg.MsgTeamList; import msg.MsgType; public class ManageUI { // 聊天界面 String是 “本人qq 他人qq” private static HashMap<String, JFrame> chats = new HashMap<String, JFrame>(); //得到服务器的数据 public static void getMsg(MsgHead msg){ switch (msg.getType()) { case MsgType.command_teamList: MsgTeamList mtl = (MsgTeamList) msg; break; case MsgType.command_chatText: MsgChatText mct = (MsgChatText) msg; // 在此处新建聊天窗口 并加入到chats里 break; case MsgType.command_chatFile: MsgChatFile mcf = (MsgChatFile) msg; // 同上 暂时未做 最后再说 break; case MsgType.command_find_resp: MsgFindResp mfr = (MsgFindResp) msg; // 此处新建 查询好友列表 break; case MsgType.command_addFriend_Resp: MsgAddFriendResp mafr = (MsgAddFriendResp) msg; // 新建添加成功界面 break; case MsgType.command_addYou: MsgAddYou may = (MsgAddYou) msg; // 新建 有人添加你的界面 break; case MsgType.command_onLine: // 提示好友上线 // 此处调用一个 QqClientFriendsList类里的方法 该方法改变界面的显示 break; case MsgType.command_offLine: // 提示好友下线 同上 break; default: break; } } }
model包的
1.TeamInfo.java
package model; import java.io.Serializable; import java.util.ArrayList; /*** * 好友分组 * @author Administrator * */ @SuppressWarnings("serial") public class TeamInfo implements Serializable{ private int id; //分组id private String name; //分组名字 private int ownerUser; //所有者 //在此分组内的好友列表 private ArrayList<UserInfo> friendList = new ArrayList<UserInfo>(); public TeamInfo(int id, String name, int ownerUser) { this.id = id; this.name = name; this.ownerUser = ownerUser; } /** * 为此分组加入一个成员 * @param info */ public void addFriend(UserInfo info){ this.friendList.add(info); } public TeamInfo(String name) { this.name = name; } //get set 方法 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getOwnerUser() { return ownerUser; } public void setOwnerUser(int ownerUser) { this.ownerUser = ownerUser; } public ArrayList<UserInfo> getFriendList() { return friendList; } public void setFriendList(ArrayList<UserInfo> friendList) { this.friendList = friendList; } }
2.ToolsCreateMsg.java
package model; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; import msg.MsgAddFriend; import msg.MsgAddFriendResp; import msg.MsgAddYou; import msg.MsgAddYouResp; import msg.MsgChatFile; import msg.MsgChatText; import msg.MsgFindResp; import msg.MsgHead; import msg.MsgLogin; import msg.MsgLoginResp; import msg.MsgPerData; import msg.MsgReg; import msg.MsgRegResp; import msg.MsgTeamList; import msg.MsgType; import tools.LogTools; /*** * 打包消息 * @author Administrator * */ public class ToolsCreateMsg { /** * 将消息对象打包成字节数组返回 * @param msg 要打包的消息对象 * @return 返回的字节数组 * @throws IOException */ public static byte[] packMsg(MsgHead msg) throws IOException{ ByteArrayOutputStream bous = new ByteArrayOutputStream(); DataOutputStream dous = new DataOutputStream(bous); writeHead(dous, msg); int msgType = msg.getType(); switch (msgType) { //注册 case MsgType.command_reg: MsgReg mr = (MsgReg)msg; writeString(dous, 10, mr.getNickname()); writeString(dous, 10, mr.getPwd()); writeString(dous, 10, mr.getSex()); dous.writeByte((byte)mr.getIcon()); break; //注册应答 case MsgType.command_reg_resp: MsgRegResp mrr = (MsgRegResp)msg; dous.writeByte(mrr.getState()); break; //登陆 case MsgType.command_login: MsgLogin ml = (MsgLogin) msg; writeString(dous, 10, ml.getPwd()); break; //登陆应答 case MsgType.command_login_resp: MsgLoginResp mlr = (MsgLoginResp) msg; dous.writeByte(mlr.getState()); break; //好友列表 case MsgType.command_teamList: MsgTeamList mtl = (MsgTeamList)msg; ArrayList<TeamInfo> teams = mtl.getTeamList(); int listCount = teams.size(); dous.writeInt(listCount); //写入分组个数 for (TeamInfo teamInfo : teams) { writeString(dous, 10, teamInfo.getName()); //写入分组名字 ArrayList<UserInfo> users = teamInfo.getFriendList(); dous.writeByte(users.size()); //写入一个分组的成员个数 for (UserInfo userInfo : users) { dous.writeInt(userInfo.getQq()); //写入qq号 writeString(dous, 10, userInfo.getNickname()); //写入昵称 writeString(dous, 10, userInfo.getSex()); //写入性别 dous.writeByte(userInfo.getIcon()); //写入头像 dous.writeByte(userInfo.getOnLine()); //写入是否在线 } } break; //返回在线qq号码 case MsgType.command_find_resp: MsgFindResp mfr = (MsgFindResp)msg; ArrayList<UserInfo> users = mfr.getUsers(); dous.writeInt(users.size()); //写入在线qq的数量 for (UserInfo userInfo : users) { dous.writeInt(userInfo.getQq()); //写入qq 昵称 性别 头像 writeString(dous, 10, userInfo.getNickname()); writeString(dous, 10, userInfo.getSex()); dous.writeByte(userInfo.getIcon()); } // for (int i = 0; i < count; i++) { // UserInfo userInfo = users.get(i); // dous.writeInt(userInfo.getQq()); // writeString(dous, 10, userInfo.getNickname()); // writeString(dous, 10, userInfo.getSex()); // } break; //添加好友 case MsgType.command_addFriend: MsgAddFriend maf = (MsgAddFriend) msg; dous.writeInt(maf.getFriendQq()); writeString(dous, 30, maf.getNote()); //!!!!!!30字节长度!!!!!! break; //添加好友应答 case MsgType.command_addFriend_Resp: MsgAddFriendResp magr = (MsgAddFriendResp) msg; dous.writeByte(magr.getState()); //对方是否同意 dous.writeInt(magr.getQq()); //对方qq writeString(dous, 10, magr.getNickName()); //对方昵称 writeString(dous, 10, magr.getSex()); //对方的性别 dous.writeByte(magr.getIcon()); break; //有人添加你为好友 case MsgType.command_addYou: MsgAddYou may = (MsgAddYou) msg; writeString(dous, 10, may.getNickname()); //昵称 writeString(dous, 10, may.getSex()); //性别 writeString(dous, 30, may.getNote()); //备注信息 break; //有人添加你为好友 的 回复 case MsgType.command_addYouResp: MsgAddYouResp mayr = (MsgAddYouResp) msg; dous.writeByte(mayr.getState()); break; //聊天信息 case MsgType.command_chatText: MsgChatText mct = (MsgChatText) msg; writeString(dous, 20, mct.getTime()); dous.write(mct.getContent().getBytes()); break; //文件传输 case MsgType.command_chatFile: MsgChatFile mcf = (MsgChatFile) msg; writeString(dous, 20, mcf.getTime()); writeString(dous, 256, mcf.getFileName()); dous.write(mcf.getFileData()); break; case MsgType.command_perdata: MsgPerData mpd = (MsgPerData) msg; writeString(dous, 10, mpd.getNickname()); writeString(dous, 10, mpd.getSex()); dous.writeByte(mpd.getIcon()); break; //返回在线qq号码请求 case MsgType.command_find: case MsgType.command_onLine: case MsgType.command_offLine: case MsgType.command_vibration: break; default: String logMsg="创建未知消息类型,无法打包:type:"+msgType; LogTools.ERROR(ToolsCreateMsg.class, logMsg); //记录日志 break; } dous.flush(); byte[] data = bous.toByteArray(); return data; } /** * 向流中写入消息头信息 * @param dous 要写入的流对象 * @param msg 消息头对象 * @throws IOException */ public static void writeHead(DataOutputStream dous,MsgHead msg) throws IOException{ dous.writeInt(msg.getTotalLen()); dous.writeByte(msg.getType()); dous.writeInt(msg.getSrc()); dous.writeInt(msg.getDest()); } /** * 向流中写入len长的字符串 * @param dous 要写入的输出流 * @param len 要写入字符串的长度 * @param s 要写入的字符串 * @throws IOException */ public static void writeString(DataOutputStream dous,int len,String s) throws IOException{ byte[] data = s.getBytes(); if(data.length>len) throw new IOException("写入长度为:"+len+",文本过长!"); dous.write(data); while(len>data.length){//如果短,需要补0 dous.writeByte(‘\0‘); //补二进制的0 len--; } } }
3.ToolsParseMsg.java
package model; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; import java.util.ArrayList; import msg.MsgAddFriend; import msg.MsgAddFriendResp; import msg.MsgAddYou; import msg.MsgAddYouResp; import msg.MsgChatFile; import msg.MsgChatText; import msg.MsgFindResp; import msg.MsgHead; import msg.MsgLogin; import msg.MsgLoginResp; import msg.MsgPerData; import msg.MsgReg; import msg.MsgRegResp; import msg.MsgTeamList; import msg.MsgType; import tools.LogTools; /*** * 解包消息 * * @author Administrator * */ public class ToolsParseMsg { public static MsgHead parseMsg(byte[] data) throws IOException { int totalLen = data.length + 4; // 算出消息总长 ByteArrayInputStream bis = new ByteArrayInputStream(data); DataInputStream dis = new DataInputStream(bis); byte msgType = dis.readByte(); int src = dis.readInt(); int dest = dis.readInt(); MsgHead msgHead = new MsgHead(); msgHead.setTotalLen(totalLen); msgHead.setType(msgType); msgHead.setSrc(src); msgHead.setDest(dest); //根据类型进行判断 switch (msgType) { //注册 case MsgType.command_reg: MsgReg mr = new MsgReg(); copyHead(msgHead, mr); String nickname = readString(dis, 10); mr.setNickname(nickname); String pwd = readString(dis, 10); mr.setPwd(pwd); String sex = readString(dis, 10); mr.setSex(sex); byte icon = dis.readByte(); mr.setIcon(icon); return mr; //注册应答 case MsgType.command_reg_resp: MsgRegResp mrr = new MsgRegResp(); copyHead(msgHead, mrr); mrr.setState(dis.readByte()); return mrr; //登陆 case MsgType.command_login: MsgLogin ml = new MsgLogin(); copyHead(msgHead, ml); ml.setPwd(readString(dis, 10)); return ml; //登陆应答 case MsgType.command_login_resp: MsgLoginResp mlr = new MsgLoginResp(); copyHead(msgHead, mlr); mlr.setState(dis.readByte()); return mlr; //好友列表 case MsgType.command_teamList: MsgTeamList mtl =new MsgTeamList(); copyHead(msgHead, mtl); int listCount = dis.readInt(); //得到分组个数 ArrayList<TeamInfo> teamList = new ArrayList<TeamInfo>(); for (int i = 0; i < listCount; i++) { String groupName = readString(dis, 10); //得到某一分组名字 TeamInfo teamInfo = new TeamInfo(groupName); byte usersCount = dis.readByte(); //得到某一分组的成员个数 for (int j = 0; j < usersCount; j++) { int qq = dis.readInt(); //得到qq号码 String nickname2 = readString(dis, 10); //得到昵称 String sex2 = readString(dis, 10); //得到性别 byte teamList_icon = dis.readByte(); //得到头像 byte onLine = dis.readByte(); //得到是否在线 UserInfo userInfo = new UserInfo(qq, nickname2, sex2); userInfo.setOnLine(onLine); userInfo.setIcon(teamList_icon); teamInfo.addFriend(userInfo); } teamList.add(teamInfo); } mtl.setTeamList(teamList); return mtl; //在线qq列表 返回 case MsgType.command_find_resp: MsgFindResp mfr = new MsgFindResp(); copyHead(msgHead, mfr); int count = dis.readInt(); for (int i = 0; i < count; i++) { int qq = dis.readInt(); String nickName = readString(dis, 10); String mfr_sex = readString(dis, 10); byte find_resp_icon = dis.readByte(); UserInfo userInfo = new UserInfo(qq, nickName, mfr_sex); userInfo.setIcon(find_resp_icon); mfr.addQq(userInfo); } return mfr; //添加好友 请求 case MsgType.command_addFriend: MsgAddFriend maf = new MsgAddFriend(); copyHead(msgHead, maf); maf.setFriendQq(dis.readInt()); String note = readString(dis, 30); //!!!!!!30字节长度!!!!!! maf.setNote(note); return maf; //添加好友 回复 case MsgType.command_addFriend_Resp: MsgAddFriendResp mafr = new MsgAddFriendResp(); copyHead(msgHead, mafr); mafr.setState(dis.readByte()); mafr.setQq(dis.readInt()); String nickName = readString(dis, 10); mafr.setNickName(nickName); String addFriend_Resp_sex = readString(dis, 10); //性别 mafr.setSex(addFriend_Resp_sex); mafr.setIcon(dis.readByte()); return mafr; //有人添加你为好友 case MsgType.command_addYou: MsgAddYou may = new MsgAddYou(); copyHead(msgHead, may); String addYou_nickname = readString(dis, 10); may.setNickname(addYou_nickname); String addYou_sex = readString(dis, 10); //性别 may.setSex(addYou_sex); String addYou_note = readString(dis, 30); //备注 may.setNote(addYou_note); return may; //有人添加你为好友 的 回复 case MsgType.command_addYouResp: MsgAddYouResp mayr = new MsgAddYouResp(); copyHead(msgHead, mayr); mayr.setState(dis.readByte()); return mayr; //聊天信息 case MsgType.command_chatText: MsgChatText mct = new MsgChatText(); copyHead(msgHead, mct); String time = readString(dis, 20); mct.setTime(time); int len = totalLen-4-1-4-4-20; String chat = readString(dis, len); mct.setContent(chat); return mct; //文件传输 case MsgType.command_chatFile: MsgChatFile mcf = new MsgChatFile(); copyHead(msgHead, mcf); String chatFile_time = readString(dis, 20); mcf.setTime(chatFile_time); String fileName = readString(dis, 256); mcf.setFileName(fileName); int filelen = totalLen-4-1-4-4-256-20; byte[] fileData = new byte[filelen]; dis.readFully(fileData); mcf.setFileData(fileData); return mcf; case MsgType.command_perdata: MsgPerData mpd = new MsgPerData(); copyHead(msgHead, mpd); String perdata_nickname = readString(dis, 10); mpd.setNickname(perdata_nickname); String perdata_sex = readString(dis, 10); mpd.setSex(perdata_sex); mpd.setIcon(dis.readByte()); return mpd; //返回在线qq号码请求 case MsgType.command_find: case MsgType.command_onLine: case MsgType.command_offLine: case MsgType.command_vibration: return msgHead; default: String logMsg = "解包未知消息类型,无法解包:type:" + msgType; LogTools.ERROR(ToolsParseMsg.class, logMsg); //记录日志信息 break; } return null; } /** * 复制消息头的数据 * @param head 消息头 * @param dest 要复制到的对象 */ public static void copyHead(MsgHead head,MsgHead dest){ dest.setTotalLen(head.getTotalLen()); dest.setType(head.getType()); dest.setSrc(head.getSrc()); dest.setDest(head.getDest()); } /** * 从流中读取len长度的字节 * @param dous 流数据 * @param len 长度 * @throws IOException */ public static String readString(DataInputStream dis,int len) throws IOException{ byte[] data = new byte[len]; dis.readFully(data); return new String(data); } }
4.UserDao.java
package model; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Collections; import java.util.HashMap; import java.util.Map; import tools.LogTools; /*** * 数据存储 * @author Administrator * */ @SuppressWarnings({ "unchecked", "rawtypes" }) public class UserDao { private static int maxQQNumber = 1000; private static final String dbFileName = "qq.dat"; private static Map<Integer, UserInfo> userDB = new HashMap<Integer,UserInfo>(); static{ try { File file = new File(dbFileName); if(file.exists()&&!file.isDirectory()){ ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file)); userDB = (Map)ois.readObject(); LogTools.INFO(UserDao.class, "从数据文件读取数据成功!"); }else{ LogTools.ERROR(UserDao.class, "不存在数据文件,创建空表"); } } catch (Exception e) { // TODO: handle exception } } //用户登录 public static UserInfo checkLogin(int qq,String pwd){ UserInfo user = userDB.get(qq); if(null!=user && pwd.equals(user.getPwd())){ LogTools.INFO(UserDao.class, "登录成功!"); return user; } LogTools.ERROR(UserDao.class, "登录失败!"); return null; } //注册用户 public static int regUser(String pwd,String nickname,String sex){ if(userDB.size()>0){ maxQQNumber = Collections.max(userDB.keySet()); } maxQQNumber++; UserInfo user = new UserInfo(maxQQNumber); user.setPwd(pwd); user.setNickname(nickname); user.setSex(sex); userDB.put(maxQQNumber, user); saveDB(); return maxQQNumber; } //将内存中的数据保存到文件中 private static void saveDB(){ try { ObjectOutputStream ois = new ObjectOutputStream(new FileOutputStream(dbFileName)); ois.writeObject(userDB); ois.close(); LogTools.INFO(UserDao.class, "刷新数据文件成功!"); } catch (Exception e) { LogTools.ERROR(UserDao.class, "刷新数据文件失败:"+e); } } /** * 根据qq号码 得到用户的信息 * @param qq qq号码 * @return 用户的信息 */ public static UserInfo getUserInfo(int qq){ return userDB.get(qq); } /** * 添加好友的数据库操作 * @param qq1 * @param qq2 相互添加好友的号码 * @param groupName1 * @param groupName2 分别加入的群组 */ public static void addFriend(int qq1,int qq2,String groupName1,String groupName2){ UserInfo user1 = getUserInfo(qq1); UserInfo user2 = getUserInfo(qq2); //暂时默认添加到好友队列 user1.getTeams().get(0).addFriend(user2); user2.getTeams().get(0).addFriend(user1); //保存 saveDB(); } }
5.UserInfo.java
package model; import java.io.Serializable; import java.util.ArrayList; /*** * 用户类 * @author Administrator * */ @SuppressWarnings("serial") public class UserInfo implements Serializable{ private int qq; //qq号码 private String pwd; //密码 private String nickname; //用户昵称 private String sex; //用户性别 private byte icon; //头像 private byte onLine = 1; //用户是否在线 默认为1 即不在线 private ArrayList<TeamInfo> teams = new ArrayList<TeamInfo>(); //好友列表 public UserInfo(int qq){ this.qq = qq; init(); } public UserInfo(int qq,String nickname,String sex){ this.qq = qq; this.nickname = nickname; this.sex = sex; init(); } //初始化用户 public void init(){ TeamInfo team1,team2,team3; team1= new TeamInfo(0, "我的好友", this.qq); team2= new TeamInfo(1, "陌生人", this.qq); team3= new TeamInfo(2, "黑名单", this.qq); this.teams.add(team1); this.teams.add(team2); this.teams.add(team3); } public void addTeam(TeamInfo team){ this.teams.add(team); } //get set 方法 public int getQq() { return qq; } public byte getIcon() { return icon; } public void setIcon(byte icon) { this.icon = icon; } public byte getOnLine() { return onLine; } public void setOnLine(byte onLine) { this.onLine = onLine; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public void setQq(int qq) { this.qq = qq; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } public ArrayList<TeamInfo> getTeams() { return teams; } public void setTeams(ArrayList<TeamInfo> teams) { this.teams = teams; } @Override public String toString() { return "UserInfo [qq=" + qq + ", nickname=" + nickname + ", sex=" + sex + ", icon=" + icon + "]"; } }
msg包代码
package msg; /*** * 消息:添加好友 * friendQq 此属性暂时没有作用 * @author Administrator * */ public class MsgAddFriend extends MsgHead{ private int friendQq; //好友qq号码 private String note; //备注 30字节长度!!!!!!!!!!!! public String getNote() { return note; } public void setNote(String note) { this.note = note; } public int getFriendQq() { return friendQq; } public void setFriendQq(int friendQq) { this.friendQq = friendQq; } @Override public String toString() { String head = super.toString(); return head+"MsgAddFriend [friendQq=" + friendQq + ", note=" + note + "]"; } }
package msg; /*** * 消息:好友添加 应答 * @author Administrator * */ public class MsgAddFriendResp extends MsgHead{ private byte state; //是否同意 private int qq; //好友qq号 private String nickName; //好友昵称 private String sex; //好友性别 private byte icon; public byte getIcon() { return icon; } public void setIcon(byte icon) { this.icon = icon; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public byte getState() { return state; } public void setState(byte state) { this.state = state; } public int getQq() { return qq; } public void setQq(int qq) { this.qq = qq; } public String getNickName() { return nickName; } public void setNickName(String nickName) { this.nickName = nickName; } @Override public String toString() { String head = super.toString(); return head+"MsgAddFriendResp [state=" + state + ", qq=" + qq + ", nickName=" + nickName + ", sex=" + sex + ", icon=" + icon + "]"; } }
package msg; /** * 消息: 有人添加你 * @author Administrator * */ public class MsgAddYou extends MsgHead{ private String nickname; //要添加你的人的昵称 private String sex; //要添加你的人的性别 private String note; //验证信息 public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } public String getNote() { return note; } public void setNote(String note) { this.note = note; } @Override public String toString() { String head = super.toString(); return head+"MsgAddYou [nickname=" + nickname + ", sex=" + sex + ", note=" + note + "]"; } }
package msg; /*** * 消息:发送聊天文本 * @author Administrator * */ public class MsgChatText extends MsgHead{ private String time; //发送时间 20 private String content; //聊天信息 public String getTime() { return time; } public void setTime(String time) { this.time = time; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } @Override public String toString() { String head = super.toString(); return head+"MsgChatText [time=" + time + ", content=" + content + "]"; } }
package msg;
import java.util.Arrays;
/***
* 消息:文件传输
* @author Administrator
*
*/
public class MsgChatFile extends MsgHead{
private String time; //发送时间 20
private String fileName; //文件名字
private byte[] fileData; //文件内容
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public byte[] getFileData() {
return fileData;
}
public void setFileData(byte[] fileData) {
this.fileData = fileData;
}
@Override
public String toString() {
String head = super.toString();
return head+"MsgChatFile [fileName=" + fileName + ", fileData="
+ Arrays.toString(fileData) + "]";
}
}
package msg;
/**
* 消息:有人添加你 回复
* @author Administrator
*
*/
public class MsgAddYouResp extends MsgHead{
private byte state; //是否同意添加你为好友
public byte getState() {
return state;
}
public void setState(byte state) {
this.state = state;
}
@Override
public String toString() {
String head = super.toString();
return head+"MsgAddYouResp [state=" + state + "]";
}
}
package msg;
/***
* 定义通讯用到的常量
* @author Administrator
*
*/
public interface MsgType {
String serverIP = "localhost";
int serverPort = 9999;
int SERVER_QQ_NUMBER = 10000;
//客户端请求操作的 成功与否
int state_success = 0;
int state_false = 1;
//消息类型的定义
byte command_reg = 0X01; //注册账号
byte command_reg_resp = 0X02; //注册账号应答
byte command_login=0x03; //登陆请求消息
byte command_login_resp=0x4; //登陆应答消息
byte command_teamList=0x05; //服务器发送在线好友列表
byte command_perdata=0x16; //个人信息
byte command_onLine=0x06; //服务器发送好友上线消息*无消息体
byte command_offLine=0x07; //服务器发送好友下线消息*无消息体
byte command_chatText=0x08; //聊天消息发送
byte command_chatFile=0x09; //文件传送发送
byte command_find=0x10; //查找用户请求 *无消息体
byte command_find_resp=0x11; //查找好友请求应答
byte command_addFriend=0x12; //添加好友请求
byte command_addFriend_Resp=0x13; //添加好友应答
byte command_addYou=0x14; //添加你为好友
byte command_addYouResp=0x15; //添加你为好友 的 回复
byte command_vibration=0x17; //发送震动窗口
}
package msg;
import java.util.ArrayList;
import model.TeamInfo;
/**
* 好友分组信息
* @author Administrator
*
*/
public class MsgTeamList extends MsgHead{
//存放好友的队列
private ArrayList<TeamInfo> teamList = new ArrayList<TeamInfo>();
public ArrayList<TeamInfo> getTeamList() {
return teamList;
}
public void setTeamList(ArrayList<TeamInfo> teamList) {
this.teamList = teamList;
}
@Override
public String toString() {
@SuppressWarnings("unused")
String head = super.toString();
return "MsgTeamList [teamList=" + teamList + "]";
}
}
package msg;
/***
* 消息:用户注册 应答
* @author Administrator
*
*/
public class MsgRegResp extends MsgHead{
private byte state; ////注册状态
@Override
public String toString() {
String head = super.toString();
return head+"MsgRegResp [state=" + state + "]";
}
public byte getState() {
return state;
}
public void setState(byte state) {
this.state = state;
}
}
package msg;
/***
* 消息:用户注册
* @author Administrator
*
*/
public class MsgReg extends MsgHead{
private String pwd; //用户密码
private String nickname; //用户昵称
private String sex; //用户性别
private byte icon; //头像
@Override
public String toString() {
String head = super.toString();
return head+"MsgReg [pwd=" + pwd + ", nickname=" + nickname + ", sex=" + sex
+ ", icon=" + icon + "]";
}
public byte getIcon() {
return icon;
}
public void setIcon(byte icon) {
this.icon = icon;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
}
package msg;
/***
* 登陆成功后 返回个人信息
* @author Administrator
*
*/
public class MsgPerData extends MsgHead{
private String nickname;
private String sex;
private byte icon;
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public byte getIcon() {
return icon;
}
public void setIcon(byte icon) {
this.icon = icon;
}
@Override
public String toString() {
String head = super.toString();
return head+"MsgPerData [nickname=" + nickname + ", sex=" + sex + ", icon="
+ icon + "]";
}
}
package msg;
/***
* 消息:登录 应答
* @author Administrator
*
*/
public class MsgLoginResp extends MsgHead{
private byte state; ///登陆状态 0:成功 其它:失败代码
@Override
public String toString() {
String head = super.toString();
return head+"MsgLoginResp [state=" + state + "]";
}
public byte getState() {
return state;
}
public void setState(byte state) {
this.state = state;
}
}
package msg;
/***
* 消息:用户登录
* @author Administrator
*
*/
public class MsgLogin extends MsgHead{
private int qq; //账号
private String pwd; //密码
public int getQq() {
return qq;
}
public void setQq(int qq) {
this.qq = qq;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public String toString() {
String head = super.toString();
return head+"MsgLogin [qq=" + qq + ", pwd=" + pwd + "]";
}
}
package msg;
/***
* 所有消息的头部
* @author Administrator
*
*/
public class MsgHead {
private int totalLen;//消息总长度
private byte type; //消息类型
private int src; //发送用户的号码
private int dest; //目标用户的号码
@Override
public String toString() {
return "MsgHead [totalLen=" + totalLen + ", type=" + type + ", src="
+ src + ", dest=" + dest + "]";
}
//get set 方法
public int getTotalLen() {
return totalLen;
}
public void setTotalLen(int totalLen) {
this.totalLen = totalLen;
}
public byte getType() {
return type;
}
public void setType(byte type) {
this.type = type;
}
public int getSrc() {
return src;
}
public void setSrc(int src) {
this.src = src;
}
public int getDest() {
return dest;
}
public void setDest(int dest) {
this.dest = dest;
}
}
package msg;
import java.util.ArrayList;
import model.UserInfo;
/***
* 消息:放回在线的所有qq号码
* @author Administrator
*
*/
public class MsgFindResp extends MsgHead{
//在线列表
private ArrayList<UserInfo> users = new ArrayList<UserInfo>();
//向在线列表中添加
public void addQq(UserInfo user){
this.users.add(user);
}
public ArrayList<UserInfo> getUsers() {
return users;
}
@Override
public String toString() {
String head = super.toString();
return head+"MsgFindResp [users=" + users + "]";
}
}
tools包
package tools;
import java.awt.*;
import javax.swing.*;
@SuppressWarnings("serial")
public class RoundButton extends JButton {
public RoundButton(String label) {
super(label); // 调用父类构造函数
setContentAreaFilled(false); // 不自行绘制按钮背景
} // 绘制圆和标签
protected void paintComponent(Graphics g) {
if (getModel().isArmed()) { // 鼠标点击时
g.setColor(Color.lightGray); // 颜色为灰色
} else {
g.setColor(getBackground()); // 置按钮颜色
}
g.fillOval(0, 0, getSize().width, getSize().height); // 绘制圆
super.paintComponent(g); // 调用父类函数,绘制其余部分
}
// 绘制边框
protected void paintBorder(Graphics g) {
g.setColor(getForeground()); // 设置边框颜色
g.drawOval(0, 0, getSize().width - 1, getSize().height - 1); // 在边界上绘制一个椭圆
}
}
package tools;
import java.util.Random;
public class RandomGetYanzheng {
Random ran;
String str;
String yanzhengma;
public String randomGetFiveBitYanzheng() {
ran = new Random();
str = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
yanzhengma = "";
for (int i = 0; i < 5; i++) {
// System.out.println("随机出来的下标是:" + ran.nextInt(36));
// System.out.println("对应下标的数是:" + str.charAt(ran.nextInt(36)));
yanzhengma = yanzhengma + str.charAt(ran.nextInt(36));
}
System.out.println(yanzhengma);
return yanzhengma;
}
public void changeGetFiveBitYanzheng() {
ran = new Random();
str = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
yanzhengma = "";
for (int i = 0; i < 5; i++) {
yanzhengma = yanzhengma + str.charAt(ran.nextInt(36));
}
}
public static void main(String[] args) {
new RandomGetYanzheng().randomGetFiveBitYanzheng();
}
}
package tools;
public class MyMouseEvent {
/**
*
* @Title: getMouseEvent
* @Description: TODO(传入鼠标X,Y坐标以及图片的X,Y坐标 以确定鼠标事件的范围)
* @param @param mouseX 鼠标的X坐标
* @param @param mouseY 鼠标的Y坐标
* @param @param imageX 图片的X坐标
* @param @param imageY 图片的Y坐标
* @param @return flag 鼠标是否存在此区?
* @return boolean 返回类型
* @throws
*/
public static boolean getMouseEvent(int mouseX, int mouseY, int imageX,
int imageY) {
boolean flag;
if (mouseX >= imageX && mouseX <= imageX + 78 && mouseY >= imageY
&& mouseY <= imageY + 44) {
flag = true;
} else {
flag = false;
}
return flag;
}
}
package tools;
import java.text.SimpleDateFormat;
import java.util.Date;
/***
* 系统日志记录工具类
*
* @author Administrator
*
*/
public class LogTools {
private static boolean isDebug = true; // 是否打印标志
// 禁止输出日志信息
public static void disDebug() {
isDebug = false;
}
/**
* 记录一般日志信息
*
* @param c
* 消息所在类
* @param msg
* 消息对象
*/
public static void INFO(@SuppressWarnings("rawtypes") Class c, Object msg) {
if (!isDebug)
return;
SimpleDateFormat sdf = new SimpleDateFormat("HH-mm-ss");
String t = sdf.format(new Date());
System.out.println("INFO:" + t + " " + c.getSimpleName() + " " + msg);
}
/**
* 记录出错日志信息
*
* @param c
* 消息所在类
* @param msg
* 消息对象
*/
public static void ERROR(@SuppressWarnings("rawtypes") Class c, Object msg) {
if (!isDebug)
return;
SimpleDateFormat sdf = new SimpleDateFormat("hh-FF-ss");
String t = sdf.format(new Date());
System.out.println("INFO:" + t + " " + c.getSimpleName() + " " + msg);
}
}
package tools;
import java.util.Random;
import javax.swing.JFrame;
public class Dancing implements Runnable {
JFrame wind = null;
Random rd = new Random();
public JFrame getWind() {
return wind;
}
public void setWind(JFrame wind) {
this.wind = wind;
}
public Dancing(JFrame wind) {
this.wind = wind;
}
@SuppressWarnings("static-access")
public void run() {
for (int i = 0; i < 8; i++) {
wind.setLocation(450 + rd.nextInt(15), 130 + rd.nextInt(15));
try {
Thread.currentThread().sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
原文:http://www.cnblogs.com/lelelele/p/4575881.html