Java基础10

Java基础10    1

文件结构    1

Myqq功能说明:    3

服务端_QqServer/com.qq.server.view/MyServerFrame.java    5

服务端_QqServer/com.qq.server.model/QqServerUser.java    6

服务端_QqServer/com.qq.server.model/MyQqServer.java    6

服务端_QqServer/com.qq.server.model/ ManageClientThread.java    8

服务端_QqServer/com.qq.server.model/ SerConClientThread.java    9

服务端_QqServer/com.qq.common/ Message.java    11

服务端_QqServer/com.qq.common/ MessageType.java    12

服务端_QqServer/com.qq.common/ User.java    12

服务端_QqServer/com.qq.server.db/ SqlHelper.java    13

客户端_QqServer/com.qq.client.view/QqClientLogin.java    13

客户端_QqServer/com.qq.client.view/QqChat.java    16

客户端_QqServer/com.qq.client.view/QqFriendList.java    19

客户端_QqServer/com.qq.client.model/QqClientConServer.java    23

客户端_QqServer/com.qq.client.model/QqClientUser.java    25

客户端_QqServer/com.qq.client.tools/ManageQqChat.java    25

客户端_QqServer/com.qq.client.tools/ManageQqFriendList.java    26

客户端_QqServer/com.qq.client.tools/ClientConServerThread.java    26

客户端_QqServer/com.qq.client.tools/ManageClientConServerThread.java    28

客户端_QqServer/com.qq.client.common/Message.java    29

客户端_QqServer/com.qq.client.common/MessageType.java    30

客户端_QqServer/com.qq.client.common/User.java    30

 

文件结构

 

Myqq功能说明:

要求实现的功能:

    1.把登录界面,好友列表界面,聊天界面实现.

    2.当用户点击登录后,把qq号码和密码发送给QqServer去验证

    如果该用户合法,则返回ok,如果不合法,则返回err.

    3.完成好友互相聊天功能.

    4.如果好友在线则,显示彩色头像,反之显示色头像.

    5.当好友上线后,则提示.

    

扩展实现:

    1.实现真的多人聊天,不出现错误.

    2.把接收到的消息,显示到该显示的聊天界面

    3.如果好友在线,则显彩色头像,反之,显示灰色头像

        思路:当一个用户登录成功后,就向服务器发送一个要求返回

        在线好友的包,服务器就回送一个在线好友的信息包。[客户端

        得到这个包后再处理]

        

        服务器返回

        

        type:message_ret_onLineFriend;

        con: "3 4 5 6 9 12"

        

        如何在前面登录的人,知道后面登录人的情况

        思路,让每一个人登陆ok后,就通知其它在线的人,我上线了

        

要求自己完成:

    1.不让同一个账号反复登录(通过数据库验证)

    2.如果好友不在线,则不能聊天

 

QQ好友列表布局

 

QQ登录验证3层模型

 

 

服务端_QqServer/com.qq.server.view/MyServerFrame.java

 

/**

* 是服务器端的控制界面,可以完成启动服务器,关闭服务器

* 可以管理和监控用户。

*/

 

package com.qq.sever.view;

import javax.swing.*;

 

import com.qq.server.model.*;

 

import java.awt.*;

import java.awt.event.*;

 

public class MyServerFrame extends JFrame implements ActionListener{

 

    JPanel jp1;

    JButton jb1,jb2;

    

    public static void main(String[] args) {

        // TODO Auto-generated method stub

        MyServerFrame mysf=new MyServerFrame();

    }

 

    public MyServerFrame()

    {

        jp1=new JPanel();

        jb1=new JButton("启动服务器");

        jb1.addActionListener(this);//监听

        jb2=new JButton("关闭服务器");

        jp1.add(jb1);

        jp1.add(jb2);

        

        this.add(jp1);

        this.setSize(500,400);

        this.setTitle("Myqq服务器端");

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        this.setVisible(true);

    }

 

    @Override

    public void actionPerformed(ActionEvent e) {

        //判断

        if(e.getSource()==jb1)

        {

            new MyQqServer();

        }

    }

}

 

服务端_QqServer/com.qq.server.model/QqServerUser.java

 

package com.qq.server.model;

 

public class QqServerUser {

 

}

 

服务端_QqServer/com.qq.server.model/MyQqServer.java

 

/**

* 这是QQ服务器,它在监听,等待某个qq客户端,来连接

*/

 

package com.qq.server.model;

import java.net.*;

import java.io.*;

import java.util.*;

 

import com.qq.common.*;

 

public class MyQqServer {

 

    public MyQqServer()

    {

        try {

            //9999监听

            ServerSocket ss=new ServerSocket(9999);

            //System.out.println("服务器在9999监听");

            //阻塞,等待客户端来连接

            while(true)

            {

                Socket s=ss.accept();

                //接收客户端发来的信息

                ObjectInputStream ois=new ObjectInputStream(s.getInputStream());

                User u=(User)ois.readObject();

                //System.out.println("服务器接收到用户名id:"+u.getUserId()+" 密码:"+u.getPassWd());

                //返回一个成功登陆的信息包

                Message m=new Message();

                ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());

                if(u.getPassWd().equals("123456"))

                {

                    m.setMesType("1");

                    oos.writeObject(m);

                    

                    //这里就单开一个线程,让该线程与该客户端保持通信

                    SerConClientThread scct=new SerConClientThread(s);

                    ManageClientThread.addClientThread(u.getUserId(), scct);

                    scct.start();//启动与该客户端通信的线程

                    

                    //并通知其它在线用户

                    scct.notifyOther(u.getUserId());

                }else{

                    m.setMesType("2");

                    oos.writeObject(m);

                    //关闭连接

                    s.close();

                }

                

                

            }

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

 

服务端_QqServer/com.qq.server.model/ ManageClientThread.java

 

/**

* 管理客户端的线程

*/

 

package com.qq.server.model;

import java.util.*;

 

public class ManageClientThread {

    public static HashMap<String, SerConClientThread> hm=new HashMap<String,SerConClientThread>();

    

    //hm中添加一个客户端通讯线程

    public static void addClientThread(String uid,SerConClientThread ct)

    {

        hm.put(uid,ct);

    }

    

    public static SerConClientThread getClientThread(String uid)

    {

        return(SerConClientThread)hm.get(uid);

    }

    

    //返回当前在线的人的情况

    public static String getAllOnLineUserid()

    {

        //使用迭代器完成对HashMapkeys的遍历

        Iterator it=hm.keySet().iterator();

        String res="";

        while(it.hasNext())

        {

            res+=it.next().toString()+" ";

        }

        return res;

    }

}

 

服务端_QqServer/com.qq.server.model/ SerConClientThread.java

 

/**

* 功能:是服务器和某个客户端的通讯线程

*/

 

package com.qq.server.model;

import java.net.*;

import java.util.HashMap;

import java.util.Iterator;

import java.io.*;

 

import com.qq.common.*;

 

public class SerConClientThread extends Thread{

    

    Socket s;

    public SerConClientThread(Socket s)

    {

        //把服务器和该客户端连接赋给s

        this.s=s;

    }

    

    //让该线程去通知其它用户

    public void notifyOther(String iam)

    {

        //得到所有在线的人的线程

        HashMap hm=ManageClientThread.hm;

        Iterator it=hm.keySet().iterator();

        

        while(it.hasNext())

        {

            Message m=new Message();

            m.setCon(iam);

            m.setMesType(MessageType.message_ret_onLineFriend);

            //取出在线人的id

            String onLineUserId=it.next().toString();

            try {

                ObjectOutputStream oos=new ObjectOutputStream(ManageClientThread.

                        getClientThread(onLineUserId).s.getOutputStream());

                m.setGetter(onLineUserId);

                oos.writeObject(m);

            } catch (Exception e) {

                e.printStackTrace();

            }

        }

    }

    

    public void run()

    {

        while(true)

        {

            try {

                //这里该线程就可以接收客户端的信息

                ObjectInputStream ois=new ObjectInputStream(s.getInputStream());

                Message m=(Message)ois.readObject();

                //System.out.println(m.getSender()+""+m.getGetter()+"说:"+m.getCon());

                

                //转发

                //从客户端取得的消息进行类型判断,然后做相应的处理

                if(m.getMesType().equals(MessageType.message_comm_mes))

                {

                    //取得接收人的通信线程

                    SerConClientThread sc=ManageClientThread.getClientThread(m.getGetter());

                    ObjectOutputStream oos=new ObjectOutputStream(sc.s.getOutputStream());

                    oos.writeObject(m);

                }

                else if(m.getMesType().equals(MessageType.message_get_onLineFriend))

                {

                    //System.out.println(m.getSender()+" 要他的好友");

                    //把在服务器的好友给该客户端返回

                    String res=ManageClientThread.getAllOnLineUserid();

                    Message m2=new Message();

                    m2.setMesType(MessageType.message_ret_onLineFriend);

                    m2.setCon(res);

                    m2.setGetter(m.getSender());

                    ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());

                    oos.writeObject(m2);

                }

                

            } catch (Exception e) {

                e.printStackTrace();

            }

            

        }

    }

}

 

服务端_QqServer/com.qq.common/ Message.java

 

/**

* Message规定一些规则

* mesType1->表示是登陆成功

* mesType2->表示是登陆失败

* mesType3->表示是普通的消息包

*/

 

package com.qq.common;

 

public class Message implements java.io.Serializable{

    private String mesType;

    private String sender;

    private String getter;

    private String con;

    private String sendTime;

      

    

    public String getSender() {

        return sender;

    }

 

    public void setSender(String sender) {

        this.sender = sender;

    }

 

    public String getGetter() {

        return getter;

    }

 

    public void setGetter(String getter) {

        this.getter = getter;

    }

 

    public String getCon() {

        return con;

    }

 

    public void setCon(String con) {

        this.con = con;

    }

 

    public String getSendTime() {

        return sendTime;

    }

 

    public void setSendTime(String sendTime) {

        this.sendTime = sendTime;

    }

 

    public String getMesType() {

        return mesType;

    }

 

    public void setMesType(String mesType) {

        this.mesType = mesType;

    }

}

 

服务端_QqServer/com.qq.common/ MessageType.java

 

/**

* 定义消息包的种类

*/

 

package com.qq.common;

 

public interface MessageType {

    String message_succeed="1";//登录成功

    String message_login_fail="2";//登录失败

    String message_comm_mes="3";//普通信息包

    String message_get_onLineFriend="4";//请求在线好友的信息包

    String message_ret_onLineFriend="5";//返回在线好友的信息包

}

 

服务端_QqServer/com.qq.common/ User.java

 

/**

* 这是用户信息类

*/

 

package com.qq.common;

 

public class User implements java.io.Serializable{

    //将这个类序列化,就使其对应的对象可以在网络上或者是在文件中传输

    

    private String userId;

    private String passWd;

    public String getUserId() {

        return userId;

    }

    public void setUserId(String userId) {

        this.userId = userId;

    }

    public String getPassWd() {

        return passWd;

    }

    public void setPassWd(String passWd) {

        this.passWd = passWd;

    }

}

 

服务端_QqServer/com.qq.server.db/ SqlHelper.java

 

package com.qq.server.db;

 

public class SqlHelper {

 

}

 

客户端_QqServer/com.qq.client.view/QqClientLogin.java

 

/**

* 功能:qq客户端登录界面

*/

 

package com.qq.client.view;

import javax.swing.*;

import java.io.*;

 

import com.qq.client.tools.*;

import com.qq.cllient.model.*;

import com.qq.common.*;

 

 

import java.awt.*;

import java.awt.event.*;

 

public class QqClientLogin extends JFrame implements ActionListener{

 

    //定义北部需要的组件

    JLabel jbl1;

    

    //定义中部需要的组件

    //中部有三个JPanel,由一个选项卡窗口管理

    JTabbedPane jtp;

    JPanel jp2,jp3,jp4; //jp2qq号码输入

    JLabel jp2_jbl1,jp2_jbl2,jp2_jbl3,jp2_jbl4;

    JButton jp2_jb1;

    JTextField jp2_jtf;

    JPasswordField jp2_jpf;

    JCheckBox jp2_jcb1,jp2_jcb2;

    

    //定义南部需要的组件

    JPanel jp1;

    JButton jp1_jb1,jp1_jb2,jp1_jb3;

    

    public static void main(String[] args) {

        // TODO Auto-generated method stub

        QqClientLogin qqClientLogin=new QqClientLogin();

    }

 

    public QqClientLogin()

    {

        //处理北部

        jbl1=new JLabel(new ImageIcon("image/tou.gif"));

        

        //处理中部

        jp2=new JPanel(new GridLayout(3,3));

        jp2_jbl1=new JLabel("QQ号码",JLabel.CENTER);

        jp2_jbl2=new JLabel("QQ密码",JLabel.CENTER);

        jp2_jbl3=new JLabel("忘记密码",JLabel.CENTER);

        jp2_jbl3.setForeground(Color.blue);

        jp2_jbl4=new JLabel("申请密码保护",JLabel.CENTER);

        jp2_jb1=new JButton(new ImageIcon("image/clear.gif"));

        jp2_jtf=new JTextField();

        jp2_jpf=new JPasswordField();

        jp2_jcb1=new JCheckBox("隐身登录");

        jp2_jcb2=new JCheckBox("记住密码");

        

        //把控件按照顺序加入到jp2

        jp2.add(jp2_jbl1);

        jp2.add(jp2_jtf);

        jp2.add(jp2_jb1);

        jp2.add(jp2_jbl2);

        jp2.add(jp2_jpf);

        jp2.add(jp2_jbl3);;

        jp2.add(jp2_jcb1);

        jp2.add(jp2_jcb2);

        jp2.add(jp2_jbl4);

        

        jtp=new JTabbedPane();//创建选项卡窗口

        jtp.add("QQ号码",jp2);

        jp3=new JPanel();

        jtp.add("手机号码",jp3);

        jp4=new JPanel();

        jtp.add("电子邮件",jp4);

        

        //处理南部

        jp1=new JPanel();

        jp1_jb1=new JButton(new ImageIcon("image/denglu.gif"));

        //响应用户点击登录

        jp1_jb1.addActionListener(this);

        jp1_jb2=new JButton(new ImageIcon("image/quxiao.gif"));

        jp1_jb3=new JButton(new ImageIcon("image/xiangdao.gif"));

        

        //把三个按钮放入到jp1

        jp1.add(jp1_jb1);

        jp1.add(jp1_jb2);

        jp1.add(jp1_jb3);

        

        this.add(jbl1,"North");    //北部

        this.add(jtp,"Center");

        this.add(jp1,"South");    //南部

        

        this.setSize(350,240);

        this.setTitle("QQ登录");

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        this.setVisible(true);

    }

 

    @Override

    public void actionPerformed(ActionEvent e) {

        //如果要用户点击了登录

        if(e.getSource()==jp1_jb1)

        {

            QqClientUser qqClientUser=new QqClientUser();

            User u=new User();

            u.setUserId(jp2_jtf.getText().trim());

            u.setPassWd(new String(jp2_jpf.getPassword()));

            

            if(qqClientUser.checkUser(u))

            {    

                try {

                    //创建好友列表

                    QqFriendList qqList=new QqFriendList(u.getUserId());

                    //并将登录成功的加入到好友列表

                    ManageQqFriendList.addQqFrendList(u.getUserId(), qqList);

                    

                    //发送一个要求返回在线好友的请求包

                    ObjectOutputStream oos=new ObjectOutputStream

                        (ManageClientConServerThread.getClientConServerThread

                                (u.getUserId()).getS().getOutputStream());

                    

                    //做一个message

                    Message m=new Message();

                    //指明包的类型

                    m.setMesType(MessageType.message_get_onLineFriend);

                    //并在包中指明是这个QQ号的好友情况

                    m.setSender(u.getUserId());

                    oos.writeObject(m);

                } catch (Exception e1) {

                    e1.printStackTrace();

                }

                //关闭掉登录界面

                this.dispose();

            }else{

                JOptionPane.showMessageDialog(this, "用户名或密码错误");

            }

        }

    }

}

 

客户端_QqServer/com.qq.client.view/QqChat.java

 

/**

* 与好友聊天的界面

* 因为客户端,要处于读取的状态,因此我们把它做成一个线程

*/

 

package com.qq.client.view;

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

import java.io.*;

 

import com.qq.client.tools.*;

import com.qq.cllient.model.*;

import com.qq.common.*;

 

public class QqChat extends JFrame implements ActionListener{

 

    JTextArea jta;

    JTextField jtf;

    JButton jb;

    JPanel jp;

    String ownerId;

    String friendId;

    

    public static void main(String[] args) {

        // TODO Auto-generated method stub

        //QqChat qqChat=new QqChat("1");

    }

 

    public QqChat(String ownerId,String friend)

    {

        this.ownerId=ownerId;

        this.friendId=friend;

        jta=new JTextArea();

        jtf=new JTextField(15);

        jb=new JButton("发送");

        jb.addActionListener(this);//监听

        jp=new JPanel();

        jp.add(jtf);

        jp.add(jb);

        

        this.add(jta,"Center");

        this.add(jp,"South");

        

        this.setSize(300,200);

        //this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        this.setTitle(ownerId+" 正在和 "+friend+" 聊天");

        this.setIconImage((new ImageIcon("image/qq.gif")).getImage());

        this.setVisible(true);

        //this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);

        

    }

 

    //写一个方法,让它显示消息

    public void showMessage(Message m)

    {

        //显示

        String info=m.getSender()+" "+m.getGetter()+" 说:"+m.getCon()+"\r\n";

        this.jta.append(info);

    }

    

    @Override

    public void actionPerformed(ActionEvent e) {

        //判断

        if(e.getSource()==jb)

        {

            //如果用户点击了 发送按钮

            Message m=new Message();

            m.setMesType(MessageType.message_comm_mes);

            m.setSender(this.ownerId);

            m.setGetter(this.friendId);

            m.setCon(jtf.getText());

            m.setSendTime(new java.util.Date().toString());

            try {

                //发送给服务器

                ObjectOutputStream oos=new ObjectOutputStream

                    (ManageClientConServerThread.getClientConServerThread(ownerId).getS().getOutputStream());

                //通过管理线程的类取得线程,然后通过线程取得对应线程中的Socket,再通过这个Socket输出流取得Socket中内容

                oos.writeObject(m);//发送

            } catch (IOException e1) {

                e1.printStackTrace();

            }

            

        }

    }

 

//    @Override

//    public void run() {

//        //读取状态

//        while(true)

//        {

//            //读取[如果读不到就等待]

//            try {

//                ObjectInputStream ois=new ObjectInputStream(QqClientConServer.s.getInputStream());

//                Message m=(Message)ois.readObject();

//                

//                //显示

//                String info=m.getSender()+" "+m.getGetter()+" 说:"+m.getCon()+"\r\n";

//                this.jta.append(info);

//            } catch (Exception e) {

//                e.printStackTrace();

//            }

//            

//        }

//    }

}

 

客户端_QqServer/com.qq.client.view/QqFriendList.java

 

/**

* 我的好友列表,(也包括陌生人,黑名单)

*/

 

package com.qq.client.view;

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

 

import com.qq.client.tools.*;

import com.qq.common.*;

public class QqFriendList extends JFrame implements ActionListener,MouseListener{

 

    //定义控件

    //第一张卡片(好友)

    JPanel jphy1,jphy2,jphy3;

    JButton jphy_jb1,jphy_jb2,jphy_jb3;

    JScrollPane jsp1;

    

    //第二张卡片(陌生人)

    JPanel jpmsr1,jpmsr2,jpmsr3;

    JButton jpmsr_jb1,jpmsr_jb2,jpmsr_jb3;

    JScrollPane jsp2;

    JLabel []jbls;

    JLabel []jbls2;

    String owner;

    

    //把整个JFrame设置成CardLayout布局

    CardLayout cl;

    

    public static void main(String[] args) {

        //

        //QqFriendList qqFriendList=new QqFriendList();

    }

 

    //更新在线好友的情况

    public void updateFriend(Message m)

    {

        String onLineFriend[]=m.getCon().split(" ");

        for(int i=0;i<onLineFriend.length;i++)

        {

            //把对应的好友状态设置成在线

            jbls[Integer.parseInt(onLineFriend[i])-1].setEnabled(true);

            //System.out.println("创建了 "+jbls[Integer.parseInt(onLineFriend[i])-1]);

        }

    }

    

    public QqFriendList(String ownerId)

    {

        this.owner=ownerId;

        //处理第一张卡片(显示好友列表)

        jphy1=new JPanel(new BorderLayout());

        //假定有50个好友(50,1,两个4分别表示行间距与列间距)

        jphy2=new JPanel(new GridLayout(50,1,4,4));

        //jphy2,初始化50好友

        jbls=new JLabel[50];

        for(int i=0;i<jbls.length;i++)

        {

            jbls[i]=new JLabel(i+1+"",new ImageIcon("image/mm.jpg"),JLabel.LEFT);

            jbls[i].addMouseListener(this);//监听每一个好友

            jbls[i].setEnabled(false);//把其它人物设置成不线状态

            if(jbls[i].getText().equals(ownerId))//把自己设置成在线状态

            {

                jbls[i].setEnabled(true);

            }

            jphy2.add(jbls[i]);

        }

        jphy3=new JPanel(new GridLayout(2,1));

        

        jphy_jb1=new JButton("我的好友");

        jphy_jb2=new JButton("陌生人");

        jphy_jb2.addActionListener(this);

        jphy_jb3=new JButton("黑名单");

        

        //把两个按钮加到jphy3

        jphy3.add(jphy_jb2);

        jphy3.add(jphy_jb3);

        jsp1=new JScrollPane(jphy2);

        

        jphy1.add(jphy_jb1,"North");

        jphy1.add(jsp1,"Center");

        jphy1.add(jphy3,"South");

          

        

        //处理第二张卡片(陌生人)

        jpmsr1=new JPanel(new BorderLayout());

        jpmsr2=new JPanel(new GridLayout(20,1,4,4));

        jbls2=new JLabel[20];

        for(int i=0;i<jbls2.length;i++)

        {

            jbls2[i]=new JLabel(i+1+"",new ImageIcon("image/mm.jpg"),JLabel.LEFT);

            jbls2[i].addMouseListener(this);//监听每一个黑名单

//            jbls2[i].setEnabled(false);//把其它人物设置成不线状态

//            if(jbls2[i].getText().equals(ownerId))//把自己设置成在线状态

//            {

//                jbls2[i].setEnabled(true);

//            }

            jpmsr2.add(jbls2[i]);

        }

        jpmsr3=new JPanel(new GridLayout(2,1));

        

        jpmsr_jb1=new JButton("我的好友");

        jpmsr_jb1.addActionListener(this);

        jpmsr_jb2=new JButton("陌生人");

        jpmsr_jb3=new JButton("黑名单");

        

        //把两个按钮加到jpmsr3

        jpmsr3.add(jpmsr_jb1);

        jpmsr3.add(jpmsr_jb2);

        jsp2=new JScrollPane(jpmsr2);

        

        jpmsr1.add(jpmsr3,"North");

        jpmsr1.add(jsp2,"Center");

        jpmsr1.add(jpmsr_jb3,"South");

          

        

        cl=new CardLayout();

        this.setLayout(cl);

        this.add(jphy1,"1");

        this.add(jpmsr1,"2");

        

        this.setSize(200,400);

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        this.setTitle(ownerId+" 好友列表");//窗口显示自己的编号

        this.setVisible(true);

    }

 

    @Override

    public void actionPerformed(ActionEvent e) {

        //如果点击了陌生人按钮,就显示第二张卡片

        if(e.getSource()==jphy_jb2)

        {

            cl.show(this.getContentPane(),"2");

        }

        else if(e.getSource()==jpmsr_jb1)

        {

            cl.show(this.getContentPane(),"1");

        }

        

    }

 

    @Override

    public void mouseClicked(MouseEvent e) {

        //响应用户双击事件,并得到好友的编号

        if(e.getClickCount()==2)//双击

        {

            //得到该好友的编号

            String friendNo=((JLabel)e.getSource()).getText();

            //System.out.println("你希望和"+friendNo+"聊天");

            QqChat qqChat=new QqChat(owner,friendNo);

            //启动线程

            //Thread t=new Thread(qqChat);

            //t.start();

            

            //把聊天界面加入到管理类中

            ManageQqChat.addQqChat(this.owner+" "+friendNo, qqChat);

        }

    }

 

    @Override

    public void mouseEntered(MouseEvent e) {

        //

        JLabel jl=(JLabel)e.getSource();

        jl.setForeground(Color.red);

    }

 

    @Override

    public void mouseExited(MouseEvent e) {

        // TODO Auto-generated method stub

        JLabel jl=(JLabel)e.getSource();

        jl.setForeground(Color.black);

    }

 

    @Override

    public void mousePressed(MouseEvent e) {

        // TODO Auto-generated method stub

        

    }

 

    @Override

    public void mouseReleased(MouseEvent e) {

        // TODO Auto-generated method stub

        

    }

}

 

客户端_QqServer/com.qq.client.model/QqClientConServer.java

 

/**

* 这是客户端连接服务器的后台

*/

 

package com.qq.cllient.model;

import java.util.*;

import java.net.*;

import java.io.*;

 

import com.qq.client.tools.*;

import com.qq.common.*;;

public class QqClientConServer {

 

    public Socket s;

    //发送第一次请求

    public boolean sendInfoToServer(Object o)

    {

        boolean b=false;

        try {

            //System.out.println("kk");

            s=new Socket("127.0.0.1",9999);

            ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());

            oos.writeObject(o);

            

            ObjectInputStream ois=new ObjectInputStream(s.getInputStream());

            Message ms=(Message)ois.readObject();

            

            //这里就是验证用户登录的地方

            if(ms.getMesType().equals("1"))

            {

                //就创建一个该qq号和服务器端保持通讯连接的线程

                ClientConServerThread ccst=new ClientConServerThread(s);

                //启动该通讯线程

                ccst.start();

                ManageClientConServerThread.addClientConServerThread(((User)o).getUserId(), ccst);

                b=true;

            }else{

                //关闭socket

                s.close();

            }

            

        } catch (Exception e) {

            e.printStackTrace();

        }finally{

            

        }

        return b;

    }

      

      

    

    //发送信息

    public void SendInfoToServer(Object o)

    {

        try {

            Socket s=new Socket("127.0.0.1",9999);

        } catch (Exception e) {

            e.printStackTrace();

        }finally{

            

        }

    }

}

 

客户端_QqServer/com.qq.client.model/QqClientUser.java

 

/**

* model层中的 登录验证

*/

 

package com.qq.cllient.model;

 

import java.net.*;

import java.io.*;

 

import com.qq.common.*;

 

public class QqClientUser {

    public boolean checkUser(User u)

    {

        return new QqClientConServer().sendInfoToServer(u);

    }

}

 

客户端_QqServer/com.qq.client.tools/ManageQqChat.java

 

/**

* 这是一个管理用户聊天界面的类

*/

 

package com.qq.client.tools;

import java.util.*;

import com.qq.client.view.*;

public class ManageQqChat {

    

    private static HashMap hm=new HashMap<String,QqChat>();

    

    //加入HashMap

    public static void addQqChat(String loginIdAndFriendId,QqChat qqChat)

    {

        hm.put(loginIdAndFriendId, qqChat);

    }

    

    //HashMap取出

    public static QqChat getQqChat(String loginIdAndFriendId)

    {

        return (QqChat)hm.get(loginIdAndFriendId);

    }

}

 

客户端_QqServer/com.qq.client.tools/ManageQqFriendList.java

 

/**

* 管理好友、陌生人、黑名单...界面类

*/

 

package com.qq.client.tools;

import java.util.*;

import java.io.*;

 

import com.qq.client.view.*;

 

public class ManageQqFriendList {

 

    private static HashMap hm=new HashMap<String,QqFriendList>();

    

    public static void addQqFrendList(String qqid,QqFriendList qqFriendList)

    {

        hm.put(qqid, qqFriendList);

    }

    public static QqFriendList getQqFriendList(String qqId)

    {

        return (QqFriendList)hm.get(qqId);

    }

}

 

客户端_QqServer/com.qq.client.tools/ClientConServerThread.java

 

/**

* 这是客户端和服务器端保持通讯的线程

*/

 

package com.qq.client.tools;

import java.io.*;

import java.net.*;

 

import com.qq.client.view.*;

import com.qq.common.Message;

import com.qq.common.MessageType;

 

public class ClientConServerThread extends Thread{

    

    private Socket s;

    public Socket getS() {

        return s;

    }

    public void setS(Socket s) {

        this.s = s;

    }

    //构造函数

    public ClientConServerThread(Socket s)

    {

        this.s=s;

    }

    public void run()

    {

        while(true)

        {

            //不停的读取从服务器端发来的消息

            try {

                ObjectInputStream ois=new ObjectInputStream(s.getInputStream());

                Message m=(Message)ois.readObject();

//                System.out.println("读取到从服务器发来的消息"+m.getSender()+" "+

//                        m.getGetter()+" 内容:"+m.getCon());

                

                //如果是普通包

                if(m.getMesType().equals(MessageType.message_comm_mes))

                {

                    //把从服务器获得的消息,显示到该显示的聊天界面

                    QqChat qqChat=ManageQqChat.getQqChat(m.getGetter()+" "+m.getSender());

                    //显示

                    qqChat.showMessage(m);

                }

                //如果返回的是好友上线的包

                else if(m.getMesType().equals(MessageType.message_ret_onLineFriend))

                {

                    //System.out.println("客户端接收到:"+m.getCon());

                    String con=m.getCon();

                    String friends[]=con.split(" ");

                    String getter=m.getGetter();

                    //System.out.println("getter="+getter);

                    

                    //修改相应的好友列表.

                    QqFriendList qqFriendList=ManageQqFriendList.getQqFriendList(getter);

                    

                    if(qqFriendList!=null)

                    {

                        //更新在线好友

                        qqFriendList.updateFriend(m);

                    }

                }

                

            } catch (Exception e) {

                e.printStackTrace();

            }

        }

    }

}

 

客户端_QqServer/com.qq.client.tools/ManageClientConServerThread.java

 

/**

* 这是一个管理客户端和服务器保持通讯的线程类

*/

 

package com.qq.client.tools;

import java.util.*;

 

public class ManageClientConServerThread {

    

    private static HashMap<String,ClientConServerThread> hm=new HashMap<String,ClientConServerThread>();

    

    //把创建好的ClientConServerThread放入到hm

    public static void addClientConServerThread(String qqId,ClientConServerThread ccst)

    {

        hm.put(qqId, ccst);

    }

    

    //可以通过qqId取得该线程

    public static ClientConServerThread getClientConServerThread(String qqId)

    {

        return (ClientConServerThread)hm.get(qqId);

    }

}

 

客户端_QqServer/com.qq.client.common/Message.java

 

/**

* Message规定一些规则

* mesType 1->表示是登陆成功

* mesType 2->表示是登陆失败

* mesType 3->表示是普通的消息包

*/

 

package com.qq.common;

 

public class Message implements java.io.Serializable{

    private String mesType;

    private String sender;

    private String getter;

    private String con;

    private String sendTime;

      

    

    public String getSender() {

        return sender;

    }

 

    public void setSender(String sender) {

        this.sender = sender;

    }

 

    public String getGetter() {

        return getter;

    }

 

    public void setGetter(String getter) {

        this.getter = getter;

    }

 

    public String getCon() {

        return con;

    }

 

    public void setCon(String con) {

        this.con = con;

    }

 

    public String getSendTime() {

        return sendTime;

    }

 

    public void setSendTime(String sendTime) {

        this.sendTime = sendTime;

    }

 

    public String getMesType() {

        return mesType;

    }

 

    public void setMesType(String mesType) {

        this.mesType = mesType;

    }

    

}

 

客户端_QqServer/com.qq.client.common/MessageType.java

 

/**

* 定义消息包的种类

*/

 

package com.qq.common;

 

public interface MessageType {

    String message_succeed="1";//登录成功

    String message_login_fail="2";//登录失败

    String message_comm_mes="3";//普通信息包

    String message_get_onLineFriend="4";//请求在线好友的信息包

    String message_ret_onLineFriend="5";//返回在线好友的信息包

}

 

客户端_QqServer/com.qq.client.common/User.java

 

/**

* 这是用户信息类

*/

 

package com.qq.common;

 

public class User implements java.io.Serializable{

    //将这个类序列化,就使其对应的对象可以在网络上或者是在文件中传输

    

    private String userId;

    private String passWd;

    public String getUserId() {

        return userId;

    }

    public void setUserId(String userId) {

        this.userId = userId;

    }

    public String getPassWd() {

        return passWd;

    }

    public void setPassWd(String passWd) {

        this.passWd = passWd;

    }

}

posted @ 2011-08-14 19:12  维唯为为  阅读(1279)  评论(0)    收藏  举报