1、关于山寨 QQ 的 java 的源代码Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台(即 JavaSE, JavaEE, JavaME)的总称。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于个人 PC、数据中心、游戏控制台、科学超级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群。在全球云计算和移动互联网的产业环境下,Java 更具备了显著优势和广阔前景。文库里没有关于山寨 QQ 的 java 的源代码,只能看了视频整理自己写了
2、,特免费分享。文档说明:根据 java 教学视频韩顺平.循序渐进学.java.从入门到精通 (第 8794 讲)整理得源相关代码。代码调试无误,下载后调试有误的可评论留言联系。image 中图片附录在源代码后面。工程文件夹:(源代码)/* 这是客户端连接服务器的后台*/package com.qq.client.model;import com.qq.client.tools.*;import java.util.*;import .*;import java.io.*;import mon.*;public class QqClientConServer public Socket s;/发
3、送第一次请求public boolean sendLoginInfoToServer(Object o)boolean b=false;try / System.out.println(“kk“);s=new Socket(“127.0.0.1“,9988);ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream();oos.writeObject(o);ObjectInputStream ois=new ObjectInputStream(s.getInputStream();Message ms=(Message)oi
4、s.readObject();/这里就是验证用户登录的地方if(ms.getMesType().equals(“1“)/就创建一个该 qq 号和服务器端保持通讯连接得线程ClientConServerThread ccst=new ClientConServerThread(s);/启动该通讯线程ccst.start();ManageClientConServerThread.addClientConServerThread(User)o).getUserId(), ccst);b=true;else/关闭 Scokets.close(); catch (Exception e) e.prin
5、tStackTrace();/ TODO: handle exceptionfinallyreturn b;public void SendInfoToServer(Object o)/*try Socket s=new Socket(“127.0.0.1“,9999); catch (Exception e) e.printStackTrace();/ TODO: handle exceptionfinally*/package com.qq.client.model;import mon.*;public class QqClientUser public boolean checkUse
6、r(User u)return new QqClientConServer().sendLoginInfoToServer(u);/* 这是客户端和服务器端保持通讯的线程.*/package com.qq.client.tools;import java.io.*;import .*;import com.qq.client.view.QqChat;import com.qq.client.view.QqFriendList;import mon.*;public class ClientConServerThread extends Thread private Socket s;/构造函数
7、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().e
8、quals(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.sp
9、lit(“ “);String getter=m.getGetter();System.out.println(“getter=“+getter);/修改相应的好友列表.QqFriendList qqFriendList=ManageQqFriendList.getQqFriendList(getter);/ / if(qqFriendList)/更新在线好友.if(qqFriendList!=null)qqFriendList.upateFriend(m); catch (Exception e) e.printStackTrace();/ TODO: handle exceptionpub
10、lic Socket getS() return s;public void setS(Socket s) this.s = s;/* 这是一个管理客户端和服务器保持通讯的线程类*/package com.qq.client.tools;import java.util.*;public class ManageClientConServerThread private static HashMap hm=new HashMap();/把创建好的 ClientConServerThread 放入到 hmpublic static void addClientConServerThread(St
11、ring qqId,ClientConServerThread ccst)hm.put(qqId, ccst);/可以通过 qqId 取得该线程 public static ClientConServerThread getClientConServerThread(String qqId)return (ClientConServerThread)hm.get(qqId);/* 这是一个管理用户聊天界面的类*/package com.qq.client.tools;import java.util.*;import com.qq.client.view.*;public class Mana
12、geQqChat private static HashMap hm=new HashMap();/加入public static void addQqChat(String loginIdAnFriendId,QqChat qqChat)hm.put(loginIdAnFriendId, qqChat);/取出public static QqChat getQqChat(String loginIdAnFriendId )return (QqChat)hm.get(loginIdAnFriendId);/* 管理好友、黑名单界面类*/package com.qq.client.tools;i
13、mport java.util.*;import java.io.*;import com.qq.client.view.*;public class ManageQqFriendList private static HashMap hm=new HashMap();public static void addQqFriendList(String qqid,QqFriendList qqFriendList)hm.put(qqid, qqFriendList);public static QqFriendList getQqFriendList(String qqId)return (Qq
14、FriendList)hm.get(qqId);/* 这是与好友聊天的界面* 因为客户端,要处于读取的状态,因此我们把它做成一个线程*/package com.qq.client.view;import com.qq.client.tools.*;import com.qq.client.model.*;import mon.*;import javax.swing.*;import java.awt.*;import java.awt.event.*;import java.io.*;public class QqChat extends JFrame implements ActionLi
15、stenerJTextArea 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
16、 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.setTitle(ownerId+“ 正在和 “+friend+“ 聊天“);this.setIconImage(new ImageIcon(“image/qq.gif“).getImage();this.setSize(300, 200);this.setVisible(true);/写一个方
17、法,让它显示消息public void showMessage(Message m)String info=m.getSender()+“ 对 “+m.getGetter()+“ 说:“+m.getCon()+“rn“;this.jta.append(info);public void actionPerformed(ActionEvent arg0) / TODO Auto-generated method stubif(arg0.getSource()=jb)/如果用户点击了,发送按钮Message m=new Message();m.setMesType(MessageType.mess
18、age_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();oos.writeObj
19、ect(m); catch (Exception e) e.printStackTrace();/ TODO: handle exception/ public void run() / / TODO Auto-generated method stub/ while(true)/ / try / /读取如果读不到就等待./ ObjectInputStream ois=new ObjectInputStream(QqClientConServer.s.getInputStream();/ Message m=(Message)ois.readObject();/ /显示/ String inf
20、o=m.getSender()+“ 对 “+m.getGetter()+“ 说:“+m.getCon()+“rn“;/ this.jta.append(info);/ catch (Exception e) / e.printStackTrace();/ / TODO: handle exception/ / / /* 功能:qq 客户端登录界面*/package com.qq.client.view;import mon.*;import com.qq.client.tools.*;import java.io.*;import javax.swing.*;import com.qq.cli
21、ent.model.QqClientUser;import mon.User;import java.awt.*;import java.awt.event.*;public class QqClientLogin extends JFrame implements ActionListener/定义北部需要的组件JLabel jbl1;/定义中部需要的组件/.中部有三个 JPanel,有一个叫选项卡窗口管理JTabbedPane jtp;JPanel jp2,jp3,jp4;JLabel jp2_jbl1,jp2_jbl2,jp2_jbl3,jp2_jbl4;JButton jp2_jb1;
22、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 stubQqClientLogin qqClientLogin=new QqClientLogin();public QqClientLogin()/处理北部jbl1=new JLabel(new ImageIcon(“i
23、mage/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(“ima
24、ge/clear.gif“);jp2_jtf=new JTextField();jp2_jpf=new JPasswordField();jp2_jcb1=new JCheckBox(“隐身登录“);jp2_jcb2=new JCheckBox(“记住密码“);/把控件按照顺序加入到 jp2jp2.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_j
25、bl4);/创建选项卡窗口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“
26、);jp1_jb3=new JButton(new ImageIcon(“image/xiangdao.gif“);/把三个按钮放入到 jp1jp1.add(jp1_jb1);jp1.add(jp1_jb2);jp1.add(jp1_jb3);this.add(jbl1,“North“);this.add(jtp,“Center“);/把 jp1 放在南部this.add(jp1,“South“);this.setSize(350, 240);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setVisible(true);pu
27、blic void actionPerformed(ActionEvent arg0) / TODO Auto-generated method stub/如果用户点击登录if(arg0.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 /把创建好友列表的
28、语句提前.QqFriendList qqList = new QqFriendList(u.getUserId();ManageQqFriendList.addQqFriendList(u.getUserId(), qqList);/发送一个要求返回在线好友的请求包 .ObjectOutputStream oos=new ObjectOutputStream(ManageClientConServerThread.getClientConServerThread(u.getUserId().getS().getOutputStream();/做一个 MessageMessage m=new M
29、essage();m.setMesType(MessageType.message_get_onLineFriend);/指明我要的是这个 qq 号的好友情况 .m.setSender(u.getUserId();oos.writeObject(m); catch (Exception e) e.printStackTrace();/ TODO: handle exception/关闭掉登录界面this.dispose();elseJOptionPane.showMessageDialog(this,“用户名密码错误“);/* 我的好友列表,(也包括陌生人,黑名单 )*/package com
30、.qq.client.view;import com.qq.client.tools.*;import mon.Message;import javax.swing.*;import java.awt.*;import java.awt.event.*;public class QqFriendList extends JFrame implements ActionListener,MouseListener/处理第一张卡片.JPanel jphy1,jphy2,jphy3;JButton jphy_jb1,jphy_jb2,jphy_jb3;JScrollPane jsp1;String
31、owner;/处理第二张卡片(陌生人).JPanel jpmsr1,jpmsr2,jpmsr3;JButton jpmsr_jb1,jpmsr_jb2,jpmsr_jb3;JScrollPane jsp2;JLabel jb1s;/把整个 JFrame 设置成 CardLayoutCardLayout cl;public static void main(String args) / TODO Auto-generated method stub/ QqFriendList qqFriendList=new QqFriendList();/更新在线的好友情况public void upateF
32、riend(Message m)String onLineFriend=m.getCon().split(“ “);for(int i=0;i();/向 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
33、String getAllOnLineUserid()/使用迭代器完成Iterator it=hm.keySet().iterator();String res=“;while(it.hasNext()res+=it.next().toString()+“ “;return res;/* 这是 qq 服务器,它在监听,等待某个 qq 客户端,来连接*/package com.qq.server.model;import mon.*;import .*;import java.io.*;import java.util.*;public class MyQqServer public MyQqS
34、erver()try /在 9999 监听System.out.println(“我是服务器,在 9988 监听 “);ServerSocket ss=new ServerSocket(9988);/阻塞,等待连接while(true)Socket s=ss.accept();/接收客户端发来的信息.ObjectInputStream ois=new ObjectInputStream(s.getInputStream();User u=(User)ois.readObject();System.out.println(“服务器接收到用户 id:“+u.getUserId()+“ 密码:“+u
35、.getPasswd();Message m=new Message();ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream();if(u.getPasswd().equals(“1“)/返回一个成功登陆的信息报m.setMesType(“1“);oos.writeObject(m);/这里就单开一个线程,让该线程与该客户端保持通讯 .SerConClientThread scct=new SerConClientThread(s);ManageClientThread.addClientThread(u.getUse
36、rId(), scct);/启动与该客户端通信的线程.scct.start();/并通知其它在线用户.scct.notifyOther(u.getUserId();elsem.setMesType(“2“);oos.writeObject(m);/关闭 Sockets.close(); catch (Exception e) e.printStackTrace();/ TODO: handle exceptionfinally/* 功能:是服务器和某个客户端的通信线程*/package com.qq.server.model;import java.util.*;import .*;impor
37、t java.io.*;import mon.*;public class SerConClientThread extends ThreadSocket s;public SerConClientThread(Socket s)/把服务器和该客户端的连接赋给 sthis.s=s;/让该线程去通知其它用户public void notifyOther(String iam)/得到所有在线的人的线程HashMap hm=ManageClientThread.hm;Iterator it=hm.keySet().iterator();while(it.hasNext()Message m=new
38、Message();m.setCon(iam);m.setMesType(MessageType.message_ret_onLineFriend);/取出在线人的 idString onLineUserId=it.next().toString();try ObjectOutputStream oos=new ObjectOutputStream(ManageClientThread.getClientThread(onLineUserId).s.getOutputStream();m.setGetter(onLineUserId);oos.writeObject(m); catch (Ex
39、ception e) e.printStackTrace();/ TODO: handle exceptionpublic 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();/对从客户端取得的消息进行类型判断,然后做相应的处理
40、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)S
41、ystem.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.
42、writeObject(m2); catch (Exception e) e.printStackTrace();/ TODO: handle exception/* 这是服务器端的控制界面,可以完成启动服务器,关闭服务器* 可以管理和监控用户.*/package com.qq.server.view;import javax.swing.*;import com.qq.server.model.MyQqServer;import java.awt.*;import java.awt.event.*;public class MyServerFrame extends JFrame imple
43、ments ActionListener JPanel jp1;JButton jb1,jb2;public static void main(String args) / TODO Auto-generated method stubMyServerFrame 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.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setVisible(true);public void actionPerformed(ActionEvent arg0) / TODO Auto-generated method stubif(arg0.getSource()=jb1)new MyQqServer();Image 文件夹中图片