6.面向对象程序设计(1)

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();
			}
	
		}

	}

}

 

posted @ 2015-06-14 22:38  518软件工程小组  阅读(313)  评论(3编辑  收藏  举报