• java实现聊天系统项目笔记


    JavaSE学完以后,用java实现的聊天室融合了很多java知识.

    比如GUI简单的图形界面,集合,IO,多线程,socket,监听等.

    那么这个聊天系统是如何实现的呢?

    首先我们要有界面.如图所示.

    这仅仅是一个简单的Frame窗口界面.

    首先package : 包入境,相当于这个类文件的绝对路径,与别人重复几率减小

          import   : 导入包/类的意思.当要想调用某个包中的类的方法,就要用到import 

          extends : ChatClient01继承Frame,相当于,继承了父类Frame里面的所有方法

          接下来如图中代码所示,声明接下来要用到的变量,变量声明三步:指定数据类型,指定变量名,赋值

          main     : 程序的入口

          实例化ChatClient01然后调用LaunchFrame()里面的方法,并且把它实现.

          this       : 就是指当前对象.

          pack()   : 调用pack()方法,这个方法就是依据你放置的组件设定窗口的大小 使之正好能容纳你放置的所有组件

          setVisible() : 设置可视化窗口可见.

    窗口实现了,接下来就该实现对窗口的一些响应.

    这个过程就是对这个Frame窗口进行了监听,感应,让他实现某些功能.

    这里就已经连接到了服务器.使用到了socket,那么socket就是网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket

    说简单就就像插座.

    Socket通讯的过程:1 创建socket

                             2 打开链接到socket的输入输出流

                             3 对socket进行读写操作

                             4 关闭socket

    这个就可以实现发送功能了.

    这里就实现了多个线程同时发送接收,实现对话.

    那么这一步步是怎么实现的,我简单说一下我的理解.

    界面--->控件监听/感应--->添加服务器--->链接服务器--->把数据发送到服务器,并且获得客户端数据并输出--->接受多线程客户端请求--->优化--->关闭数据接受线程

    总体来说,就差不多完整了.其中可能在涉及到服务端以及多线程客户请求的时候可能有些麻烦,但细心一点,认真一点,会ok

    刚开始的程序只能实现Server和一个客户的对话,为了实现在服务器方给多个客户提供服务的功能,需要对开始单线程的程序进行改造,利用多线程实现多客户机制.

    聊天室服务端:
    public class ChatServer {
        boolean started = false;
        ServerSocket ssoc = null;//对象变量
        ArrayList<Client> clients = new ArrayList<Client>();//存放对象的集合
        
        public static void main(String[] args) {
            new ChatServer().serverStart();
        }
        
        private void serverStart(){
            try {
                ssoc = new ServerSocket(8888);//创建一个ServerSocket在端口8888监听客户请求
                 started = true;
            } catch (BindException e) { //出错,出错信息
                System.out.println("服务器端口已经被占用");
                System.out.println("请关闭服务器重新启动");
                System.exit(0);
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                 while (started) {//循环等待客户端连接
                     Socket soc;
                     try {
                          soc = ssoc.accept();//使用accept()阻塞等待客户请求,有客户,请求到来则产生一个Socket对象,并继续执行
                          boolean bConnected = false;
                          Client c = new Client(soc);
                          new Thread(c).start();//开始一个线程
                          clients.add(c);
                    } catch (Exception e) {
                         e.printStackTrace();
                    }
                 }
             } catch (Exception e) {
                 // TODO: handle exception
             }
         }
        
         private class Client implements Runnable {
            private DataOutputStream dos = null;
            DataInputStream dis = null;
            Socket soc = null;
            boolean started = false;
            boolean bConnected = false;
            
            public Client(Socket soc) {
                 try {
                    this.soc = soc;
                    dis = new DataInputStream(soc.getInputStream());//得到输入流
                    dos = new DataOutputStream(soc.getOutputStream());//得到输出流
                    bConnected = true;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            
            @Override
            public void run() {  //针对每个socket进行
                 try {
                     while (bConnected) {
                        String str = dis.readUTF();
                        System.out.println(str);
                        for (int i = 0; i < clients.size(); i++) {
                            Client c = clients.get(i);
                            c.send(str);
                        }
                    }
                } catch (EOFException e) {
                    System.out.println("客户端退出");
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (dis != null) {
                            dis.close();
                        }
                        if (soc != null) {//socket不为空
                            soc.close();//关闭socket
                        }
                    } catch (Exception e2) {
                        e2.printStackTrace();
                    }
                }
            }

            public void send(String str) {//发送
                 try {
                    dos.writeUTF(str);
                } catch (IOException e) {
                    e.printStackTrace();
                }            
            }
            
        }
    }

        

  • 相关阅读:
    阿里巴巴电商搜索推荐实时数仓演进之路
    阿里云发布边缘计算视频上云解决方案 为海量视图处理提供城市级云基础设施
    MySQL设置所有IP地址都可以访问数据库
    HTML5中的data-*属性和jQuery中的.data()方法使用
    21. 合并两个有序链表 *****
    链表相交
    链表的中间节点
    剑指 Offer 24. 反转链表 *****
    从尾到头打印链表
    返回倒数第k个节点
  • 原文地址:https://www.cnblogs.com/lwxalxy/p/4709452.html
Copyright © 2020-2023  润新知