【Java小项目】山寨QQ

  最近看着韩顺平老师的视频加上百度谷歌做了这个小玩意。


  主要功能:

           服务器端:

                      1.选择监听端口

                      2.打印服务器日志

                      3.查看在线用户(强制下线没做)

           客户端:

                      1.登陆的密码我写死到程序里了(密码是一个空格)

                      2.三个分组可切换

                      3.可多对多聊天

                      4.A找B好友聊天时,若B好友没有打开与A聊天的界面,则B与A聊天的界面会直接弹出

                      5.可以选择要链接的服务器的地址和端口

                      6.上线,下线好友头像会有相应变化


    思路:

            服务器和客户端用ObjectOutputStream,ObjectInputStream 进行通信,把数据包封装到类里(User,Message)。

            服务器端:

                     1.点击启动服务器时启动一个线程来监听端口

public void run(){
        try {
            while(true) {
                Socket s = ss.accept();
                ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
                User u = (User) ois.readObject();
                System.out.println("收到UserName:" + u.getUserName() + " PassWard:" + u.getPassWard());
                Message m = new Message();
                ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
                if (u.getPassWard().equals(" ")) {
                    display.di.showLog("用户名:"+u.getUserName() + " 登陆成功!密码:" + u.getPassWard());
                    m.setType("success");
                    oos.writeObject(m);
                    //启动一个线程来服务
                    myThread mythread=new myThread(s,oos,ois);
                    mythread.start();
                    threadManger.addThread(u.getUserName(),mythread);
                    threadManger.friendAlert();
                } else {
                    display.di.showLog("用户名:"+u.getUserName() + " 登陆失败!密码:" + u.getPassWard());
                    m.setType("failed");
                    oos.writeObject(m);
                    oos.close();
                }
            }
        }catch(IOException e){
            e.printStackTrace();
        }catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

                  2.监听到登陆,如果登陆成功就在启动一个线程来维持与该Socket的通信

public void run(){

        try {
            while(true) {
                Message m = (Message)ois.readObject();
                if(m.getType().equals("sendMsg")) {
                    System.out.println(s + m.getSender() + " 对 " + m.getGetter() + " 说:" + m.getMsg());
                    display.di.showLog(s.getInetAddress()+" : "+m.getSender() + " 对 " + m.getGetter() + " 说:" + m.getMsg());
                    //转发
                    myThread fri = threadManger.getThread(m.getGetter());
                    fri.oos.writeObject(m);
                }else if(m.getType().equals("LoginOut")){
                    display.di.showLog(m.getSender()+"下线!");
                    threadManger.delThread(m.getSender());
                    threadManger.friendAlert();
                    System.out.println(m.getSender()+" loginOut!");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
         客户端:

                   1.用填写的信息登陆,若成功的话就启动一个线程来负责该客户端与服务器端之间的通信。

 public void run(){
        try {
            while(true) {
                Message m = (Message)clientUser.getOIS().readObject();
                if(m.getType().equals("sendMsg")) {
                    System.out.println(m.getSender() + " say to " + m.getGetter() + " with " + m.getMsg());
                    //已经打开聊天界面
                    if(chatManger.Getchat(m.getGetter() + "_" + m.getSender())!=null) {
                        chat ch = chatManger.Getchat(m.getGetter() + "_" + m.getSender());
                        ch.ShowMsg(m.getSender() + " : " + m.getMsg());
                    }else{
                        chat ch=new chat(m.getGetter(),m.getSender());
                        chatManger.Addchat(m.getGetter()+"_"+m.getSender(),ch);
                        ch.ShowMsg(m.getSender() + " : " + m.getMsg());
                    }

                }else if(m.getType().equals("getFriend")){
                    //好友列表
                    Object[] l=m.getFriList();
                    System.out.println(m.getType()+"  "+l.length);
                    listManger.getMainL().changeList(l);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

  完整代码:

CSDN下载上传了但是刷不出来啊

GitHub地址:https://github.com/zhang-tiancheng/qq-little_copycat




  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
1、具有登陆界面,包括服务器IP(或服务器名)、用户名、密码。 登录:在数据库服务器上验证用户名和密码,如果匹配就进入QQ聊天主界面,否则提示不能登录。 取消:退出即可。 注册:进入用户注册界面。 服务器栏中默认是你要使用的服务器名字,即该服务器安装的数据库,所有qq用户信息都保存在这个服务器的数据库里。图片显示的是我试验的服务器名字。 登录成功后还要把自己当前所在机器的IP地址提取出来并保存到数据库的个人信息中,替换原来注册或上次使用的IP。 2、注册界面,可以让第一次使用的用户注册,即给自己在服务器上注册一个用户名、密码、自己所使用的机器IP、自己的端口号,如图所示: 注册:首先验证密码和确认密码是否一致,如果不一致,则提示,否则,把输入的信息记录到数据库中,如果用户名重复也要提示。 其中IP栏目的内容可以由程序自动提取出本机的ip地址,并显示出来,省得用户输入错误。 3、聊天主界面 登陆成功后就进入本届面,界面如下: 界面设计类似简单的QQ界面,可以使用BorderLayout布局管理器,在上面(BorderLayou.NORTH)显示“好友列表”四个字,中间部分(BorderLayou.CENTER)显示自己的好友名单,名单可以用多个JLabel控件(JLabel中添加ImageIcon)显示,或者用JTree控件显示(比较复杂),名单中可以显示qq号、昵称(姓名)、状态(在线、离线等)。最下边(BorderLayou.SOUTH)可以显示“欢迎您:***”。 好友要求用不同的图标显示在线和不在线的状态。 双击在线的好友名字可以打开聊天窗口,而双击不在线的好友不动(即不开启聊天窗口)。 达到这种效果的前提是在登录成功后,获得当前登录用户的信息,在本模块根据登录信息获取用户名、获取他的好友列表等数据。
资源分设为1,因为我自己只有3分资源分了,所以就不设为0了 这个山寨QQ代码2000行,基于现在可以使用IP6,给出它的设计原理 功能:山寨QQ 主要行为: ①用户注册 ②添加好友 ③好友上线头像变为彩色 ④在线上的好友头像是彩色,不在线上的好友头像是灰色,动态变化 ⑤独立窗口聊天 ⑥服务器端有两个表,全部用户表和在线用户表,都是动态改变的 代码在下面,有2000多行,总共17个文件,干脆就看看这些思路得了。 山寨QQ分为用户端和服务器端,主要用到的Java知识点有:多线程、网络编程、IO流,如果能够加入数据库当然更好,可是我在家一直没网,没有数据库,所以就把用户信息全部储存在文件中了。 服务器端3000号端口作为一个特殊的端口,放在一个单独的线程中时刻监听着。服务器的交互信息通讯端口从3001号一直向后监听,最大可以到65535号端口。 用户每次来连接服务器时,首先连接3000号端口,获取服务器正在监听的端口号,然后再去连接这个端口。 用户和服务器之间的交互信息使用对象流来传递,信息类型分为 注册消息=0、 修改密码=1、 登录验证=2、 请求聊天=3、 获取在线好友=4、 添加好友=5、 某人上线了=6 如果是登录消息,则把这个新建的套接字(套接字即Socket,网络通讯全靠他来实现)储存在一个单独的线程中,使用这个线程的类储存用户的用户名、昵称、密码、IP。然后将这个县城储存在一组向量中,即C语言中的链表。IP地址可以通过套接字得到。当用户再次和服务器发生交互信息时,直接利用这个已存在的套接字即可。 如果用户双击某个用户希望聊天时,首先从服务器端获取该用户的IP,然后再单独去连接这个用户。 用户连接用户时,和连接服务器的原理大同小异。2000号端口作为一个特殊的端口被监听着。如果一台机器上同时登陆有多个用户,则监听的端口一直往下走,最小可以到1025,总共有975个端口可以利用,用户总该用不了这么多吧。然后接下来,该不用我说了吧,连接好友正在监听的端口就是了。 建立完成连接,就可以弹出聊天窗口开始聊天了。 好了,大体思路就是这样。当然还有一些其他的功能,比如注册用户、添加好友等,和上面思路也差不多。 对了,忘了说说如何获取在线好友了 用户登录成功后,将自己所有的好友列表从文件中读取,放在一个向量中发送给服务器,服务器查看哪些人在在线用户列表中,然后返回用户的在线好友,同时通知这些在线好友某人人上线了,还是利用已建立的套接字。 用户下线后,和服务器已建立的套接字发生IOException异常,程序代码块跳转,服务器就通知用户的在线好友有人下线了。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值