zoukankan      html  css  js  c++  java
  • JAVA入门到精通-网络编程补充和QQ案例

    ------------------------------------------------------

    补充讲解:

    如何在网络间传递对象?

    [MyServer.java]服务器源代码

    39
    39
     
    1
    package com.test.server;
    2
    import java.io.ObjectInputStream;
    3
    import java.net.ServerSocket;
    4
    import java.net.Socket;
    5
    import com.common.User;
    6
     
    7
    public class MyServer {
    8
        ServerSocket ss;
    9
        Socket s;
    10
        ObjectInputStream ois;
    11
       
    12
        public static void main(String[] args) {
    13
            new MyServer();
    14
        }
    15
       
    16
        //构造函数
    17
        public MyServer(){
    18
            try {
    19
                ss=new ServerSocket(3456);
    20
                s=ss.accept();
    21
                //以对象流的方式读取(假设客户端发送的是User的一个对象)
    22
                ois=new ObjectInputStream(s.getInputStream());
    23
                User u=(User)ois.readObject();
    24
                //输出
    25
                System.out.println(u.getName()+"	"+u.getPasswd());
    26
               
    27
            } catch (Exception e) {
    28
                e.printStackTrace();
    29
            }finally{
    30
                try {
    31
                    if(ois!=null) ois.close();
    32
                    if(s!=null) s.close();
    33
                    if(ss!=null) ss.close();
    34
                } catch (Exception e2) {
    35
                    e2.printStackTrace();
    36
                }
    37
            }
    38
        }
    39
    }

    [User.java]服务端的公共服务

    20
    20
     
    1
    package com.common;
    2
     
    3
    import java.io.Serializable;
    4
     
    5
    public class User implements Serializable{
    6
        private String name;
    7
        private String passwd;
    8
        public String getName() {
    9
            return name;
    10
        }
    11
        public void setName(String name) {
    12
            this.name = name;
    13
        }
    14
        public String getPasswd() {
    15
            return passwd;
    16
        }
    17
        public void setPasswd(String passwd) {
    18
            this.passwd = passwd;
    19
        }
    20
    }

     

    [MyClient.java]客户端源代码

    36
    36
     
    1
    package com.test.client;
    2
     
    3
    import java.io.ObjectOutputStream;
    4
    import java.net.Socket;
    5
    import com.common.User;
    6
     
    7
    public class MyClient {
    8
        Socket s;
    9
        ObjectOutputStream oos;
    10
       
    11
        public static void main(String[] args) {
    12
            new MyClient();
    13
        }
    14
     
    15
        //构造函数
    16
        public MyClient(){
    17
            try {
    18
                s=new Socket("127.0.0.1",3456);
    19
                //通过ObjectOutputStream给服务器传送对象
    20
                oos=new ObjectOutputStream(s.getOutputStream());
    21
                User u=new User();
    22
                u.setName("张三");
    23
                u.setPasswd("123");
    24
                oos.writeObject(u);
    25
            } catch (Exception e) {
    26
                e.printStackTrace();
    27
            }finally{
    28
                try {
    29
                    if(oos!=null) oos.close();
    30
                    if(s!=null) s.close();
    31
                } catch (Exception e2) {
    32
                    e2.printStackTrace();
    33
                }
    34
            }
    35
        }
    36
    }

     

    [User.java]客户端的公共服务

    21
     
    1
    package com.common;
    2
     
    3
    import java.io.Serializable;
    4
    //通过io在网络上传送对象需要进行序列化Serializable
    5
    public class User implements Serializable{
    6
        private String name;
    7
        private String passwd;
    8
       
    9
        public String getName() {
    10
            return name;
    11
        }
    12
        public void setName(String name) {
    13
            this.name = name;
    14
        }
    15
        public String getPasswd() {
    16
            return passwd;
    17
        }
    18
        public void setPasswd(String passwd) {
    19
            this.passwd = passwd;
    20
        }
    21
    }

    特别说明:

    java网络编程需要通过IO流实现对象的传递需要对,服务端和客户端定义相同的传递对对向方法,以达到实现对象的传递。同时需要对方法进行Serializable序列化,否则报错。


    ------------------------------


    QQ
    案例

    说明:该案例主讲内容:java网络编程、多线程、C/S数据交互

    附源代码

    注:代码分为Server部分与Client部分,由于此案例仅为对NET操作未使用数据库

    Server部分包含的包有:

    1、com.qq.server.view (服务端界面包)

    1.1QqServerFrame.java (服务端主页面)

    2、com.qq.server.model (业务逻辑包)

    2.1MyQqServer.java (服务器验证客户信息)

    2.2QqServerUser.java (用于管理QQ用户信息[此包功能应为对数据库逻辑操作])()

    2.3SerConClientThread.java (服务器连接客户端线程)

    2.4ManageClientThrea.java (管理客户端连接线程)

    3com.qq.server.db (数据库操作包)

       3.1SqlHelper.java (对数据库的CURD操作)()

    4com.qq.server.tools (服务端工具包)()

    5com.qq.common (通用包)

       5.1Message.java (消息类)

       5.2MessageType.java (消息类型接口类)

       5.3User.java (用户信息类)

    Client部分包含的包有:

    1、com.qq.client.view (客户端界面包)

    1.1、QqClientLogin.java (QQ登录界面)

    1.2、QqFriendList.java (好友列表界面)

    1.3、QqChat.java (聊天界面)

    2、com.qq.client.model (客户端业务逻辑包)

    2.1QqClienConServer.java (客户端连接服务端的后台用于与服务端数据交互)

    2.2QqClientUser.java (客户端用户操作逻辑类)

    3com.qq.client.tools (原应为客户端工具包,现为处理与服务端的线程包)

       3.1ClientConServerThread.java (客户端连接服务器线程类)

       3.2ManageClientConServerThread.java (管理C/S线程类)

       3.3ManageQqChat.java (管理聊天界面类)

       3.4ManageQqFriendList.java (管理好友列表类)

    4com.qq.common (通用包)

       4.1Message.java (消息类)

       4.2MessageType.java(消息类型类)

       4.3User.java (用户信息类)

    注意:ServerClient中的com.qq.common通用包主要功能是统一保持客户端与服务端的用户及消息一致。

     

    下见源代码:

     

     

    Server端源代码:

    com.qq.server.view

    [QqServerFrame.java]

    48
     
    1
    /**
    2
     * 服务器端的控制界面
    3
     * 功能:
    4
     *     1、完成启动、关闭服务器
    5
     *     2、管理及监控用户
    6
     */
    7
    package com.qq.server.view;
    8
     
    9
    import java.awt.event.ActionEvent;
    10
    import java.awt.event.ActionListener;
    11
    import javax.swing.JButton;
    12
    import javax.swing.JFrame;
    13
    import javax.swing.JPanel;
    14
    import com.qq.server.model.MyQqServer;
    15
     
    16
    public class QqServerFrame extends JFrame implements ActionListener{
    17
        JPanel jp1;
    18
        JButton jb1,jb2;
    19
       
    20
        public static void main(String []args){
    21
            new QqServerFrame();
    22
        }
    23
       
    24
        //构造函数
    25
        public QqServerFrame(){
    26
            jp1=new JPanel();
    27
            jb1=new JButton("启动服务器");
    28
            jb1.addActionListener(this);
    29
            jb2=new JButton("关闭服务器");
    30
            jb2.addActionListener(this);
    31
            jp1.add(jb1);
    32
            jp1.add(jb2);
    33
           
    34
            this.add(jp1);
    35
            this.setSize(500, 400);
    36
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    37
            this.setVisible(true);
    38
        }
    39
     
    40
        @Override
    41
        public void actionPerformed(ActionEvent e) {
    42
            if(e.getSource()==jb1){
    43
                new MyQqServer();
    44
            }else if(e.getSource()==jb2){
    45
                System.exit(0);
    46
            }
    47
        }
    48
    }

    *******************************************************************************

    com.qq.server.model

    [MyQqServer.java]

    55
     
    1
    /**
    2
     * 这是QQ服务器,它在监听等待某个QQ客户端连接服务器
    3
     */
    4
    package com.qq.server.model;
    5
     
    6
    import java.io.BufferedReader;
    7
    import java.io.InputStreamReader;
    8
    import java.io.ObjectInputStream;
    9
    import java.io.ObjectOutputStream;
    10
    import java.net.ServerSocket;
    11
    import java.net.Socket;
    12
    import com.qq.common.Message;
    13
    import com.qq.common.User;
    14
     
    15
    public class MyQqServer {
    16
        BufferedReader br;
    17
     
    18
        public MyQqServer(){
    19
            try {
    20
                System.out.println("服务器在监听9999端口...");
    21
                //在9999端口监听
    22
                ServerSocket ss=new ServerSocket(9999);
    23
                //等待连接
    24
                while(true){
    25
                    Socket s=ss.accept();
    26
                    //接收客户端发来的信息
    27
                    ObjectInputStream ois=new ObjectInputStream(s.getInputStream());
    28
                    User u=(User)ois.readObject();
    29
                    Message m=new Message();
    30
                    ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());
    31
                    //此处代替数据库密码验证
    32
                    if(u.getPasswd().equals("12345")){
    33
                        //返回一个成功登录的信息包
    34
                        m.setMesType("1");
    35
                        oos.writeObject(m);
    36
                        //这里就单开一个线程,让该线程与该客户端保持通讯
    37
                        SerConClientThread scct=new SerConClientThread(s);
    38
                        ManageClientThrea.addClientThrea(u.getUserId(), scct);
    39
                        //启动与该客户端通讯的线程
    40
                        scct.start();
    41
                       
    42
                        //并通知其它在线用户
    43
                        scct.notifyOther(u.getUserId());
    44
                    }else{
    45
                        m.setMesType("2");
    46
                        oos.writeObject(m);
    47
                        //关闭连接
    48
                        s.close();
    49
                    }
    50
                }
    51
            } catch (Exception e) {
    52
                e.printStackTrace();
    53
            }
    54
        }
    55
    }

    *******************************************************************************

    [SerConClientThread.java]

    75
     
    1
    /**
    2
     * 功能:是服务器与某个客户端的通讯线程
    3
     */
    4
    package com.qq.server.model;
    5
     
    6
    import java.io.IOException;
    7
    import java.io.ObjectInputStream;
    8
    import java.io.ObjectOutputStream;
    9
    import java.net.Socket;
    10
    import java.util.HashMap;
    11
    import java.util.Iterator;
    12
    import com.qq.common.Message;
    13
    import com.qq.common.MessageType;
    14
     
    15
    public class SerConClientThread extends Thread{
    16
            Socket s;
    17
       
    18
        public SerConClientThread(Socket s){
    19
            //把服务器与该客户端的连接赋给s
    20
            this.s=s;
    21
        }
    22
       
    23
        //让该线程去通知其它在线用户
    24
        public void notifyOther(String iam){
    25
            //得到所有在线的用户的线程
    26
            HashMap hm=ManageClientThrea.hm;
    27
            Iterator it=hm.keySet().iterator();
    28
            while(it.hasNext()){
    29
                Message m=new Message();
    30
                m.setCon(iam);
    31
                m.setMesType(MessageType.message_ret_onLineFriend);
    32
                //取出在线用户的id
    33
                String onLineUserId=it.next().toString();
    34
                try {
    35
                    ObjectOutputStream oos=new ObjectOutputStream(ManageClientThrea.getClientThrea(onLineUserId).s.getOutputStream());
    36
                    m.setGetder(onLineUserId);
    37
                    oos.writeObject(m);
    38
                } catch (IOException e) {
    39
                    e.printStackTrace();
    40
                }
    41
            }
    42
        }
    43
       
    44
        public void run(){
    45
            while(true){
    46
                //这里该线程就可以接收客户端发来的信息
    47
                try {
    48
                    ObjectInputStream ois=new ObjectInputStream(s.getInputStream());
    49
                    Message m=(Message)ois.readObject();
    50
                   
    51
                    System.out.println(m.getSender()+" 给 "+m.getGetder()+" 说:"+m.getCon());
    52
                   
    53
                    //对从客户端取得的消息进行类型判断,然后做相应的处理
    54
                    if(m.getMesType().equals(MessageType.message_comm_mes)){
    55
                        //服务器完成转发功能
    56
                        //取得接收人的通讯线程
    57
                        SerConClientThread sc=ManageClientThrea.getClientThrea(m.getGetder());
    58
                        ObjectOutputStream oos=new ObjectOutputStream(sc.s.getOutputStream());
    59
                        oos.writeObject(m);
    60
                    }else if(m.getMesType().equals(MessageType.message_get_onLineFriend)){
    61
                        //把在服务器的好友给该客户端返回
    62
                        String res=ManageClientThrea.getAllOnLineUserid();
    63
                        Message m2=new Message();
    64
                        m2.setMesType(MessageType.message_ret_onLineFriend);
    65
                        m2.setCon(res);
    66
                        m2.setGetder(m.getSender());
    67
                        ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());
    68
                        oos.writeObject(m2);
    69
                    }
    70
                } catch (Exception e) {
    71
                    e.printStackTrace();
    72
                }
    73
            }
    74
        }
    75
    }

    *******************************************************************************

    [ManageClientThrea.java]

    30
     
    1
    /**
    2
     * 这是一个管理客户端线程的类
    3
     */
    4
    package com.qq.server.model;
    5
     
    6
    import java.util.HashMap;
    7
    import java.util.Iterator;
    8
     
    9
    public class ManageClientThrea {
    10
        public static HashMap hm=new HashMap<String,SerConClientThread>();
    11
        //向hashmap中添加一个客户端通讯线程
    12
        public static void addClientThrea(String uid,SerConClientThread scct){
    13
            hm.put(uid,scct);
    14
        }
    15
       
    16
        public static SerConClientThread getClientThrea(String uid){
    17
            return (SerConClientThread)hm.get(uid);
    18
        }
    19
       
    20
        //返回当前在线的人的好友情况
    21
        public static String getAllOnLineUserid(){
    22
            //使用迭代器完成
    23
            Iterator it=hm.keySet().iterator();
    24
            String res="";
    25
            while(it.hasNext()){
    26
                res+=it.next().toString()+" ";
    27
            }
    28
            return res;
    29
        }
    30
    }

    *******************************************************************************

    com.qq.common

    [Message.java]

    57
     
    1
    /**
    2
     * 为Message规定规则
    3
     * mesType1-->表明登录成功
    4
     * mesType2-->表明登录失败
    5
     * mesType3-->表明普通消息包
    6
     */
    7
    package com.qq.common;
    8
     
    9
    import java.io.Serializable;
    10
     
    11
    public class Message implements Serializable{
    12
        private String mesType;
    13
        private String sender;
    14
        private String getder;
    15
        private String con;
    16
        private String sendTime;
    17
     
    18
        public String getGetder() {
    19
            return getder;
    20
        }
    21
     
    22
        public void setGetder(String getder) {
    23
            this.getder = getder;
    24
        }
    25
     
    26
        public String getSender() {
    27
            return sender;
    28
        }
    29
     
    30
        public void setSender(String sender) {
    31
            this.sender = sender;
    32
        }
    33
     
    34
        public String getCon() {
    35
            return con;
    36
        }
    37
     
    38
        public void setCon(String con) {
    39
            this.con = con;
    40
        }
    41
     
    42
        public String getSendTime() {
    43
            return sendTime;
    44
        }
    45
     
    46
        public void setSendTime(String sendTime) {
    47
            this.sendTime = sendTime;
    48
        }
    49
     
    50
        public String getMesType() {
    51
            return mesType;
    52
        }
    53
     
    54
        public void setMesType(String mesType) {
    55
            this.mesType = mesType;
    56
        }
    57
    }

    *******************************************************************************

    [MessageType.java]

    12
     
    1
    /**
    2
     * 定义消息包的种类的接口
    3
     */
    4
    package com.qq.common;
    5
     
    6
    public interface MessageType {
    7
        String message_succeed="1";//登录成功包
    8
        String message_login_fail="2";//登录失败包
    9
        String message_comm_mes="3";//普通消息包
    10
        String message_get_onLineFriend="4";//要求在线的好友包
    11
        String message_ret_onLineFriend="5";//返回在线好友包
    12
    }

    *******************************************************************************

    [User.java]

    25
     
    1
    /**
    2
     * 这是用户信息类
    3
     */
    4
    package com.qq.common;
    5
     
    6
    import java.io.Serializable;
    7
     
    8
    public class User implements Serializable{
    9
        private String userId;
    10
        private String passwd;
    11
        public String getUserId() {
    12
            return userId;
    13
        }
    14
        public void setUserId(String userId) {
    15
            this.userId = userId;
    16
        }
    17
        public String getPasswd() {
    18
            return passwd;
    19
        }
    20
        public void setPasswd(String passwd) {
    21
            this.passwd = passwd;
    22
        }
    23
    }
    24
    25





  • 相关阅读:
    What's the most secure desktop operating system?
    合肥一中在校学生丁雯琪(中美班)被麻省理工学院(MIT)录取
    Classic Computer Science 1980s-1990s
    HOWTO do Linux kernel development
    选择器zuoye
    HTML+css 小组件
    弹性盒子
    CSS3 学习笔记(动画 多媒体查询)
    CSS3 学习笔记(边框 背景 字体 图片 旋转等)
    学习笔记css3
  • 原文地址:https://www.cnblogs.com/xuxaut-558/p/10047898.html
Copyright © 2011-2022 走看看