• java socket之多人聊天室Demo


    一、功能介绍

    该功能实现了一个类似QQ的最简单多人聊天室,如下图所示。

    二、目录结构

    三、服务端

    1)SocketServer类,该类是服务端的主类,主要负责创建聊天窗口,创建监听客户端的线程:

    package multiThreadChatSocketServer;
    
    import java.awt.*;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class SocketServer {
         private TextArea ta;
         private TextField tf;
         
           private ServerSocket ss;
         private Socket s;
         private DataInputStream dis;
         private DataOutputStream dos;
         
         public TextField getTextField() {
            return tf;
         }
         
         public TextArea getTextArea() {
             return ta;
         }
         
         public DataInputStream getDataInputStream() {
            return dis;
         }
         
         public DataOutputStream getDataOutputStream() {
            return dos;
         }
         
         public static void main(String[] args) {
             SocketServer socketServer = new SocketServer();
             socketServer.createUI();
             socketServer.connect();
             socketServer.createThread();
            }
         
         
         public void close() {
             try {
                   dis.close();
                   dos.close();
                   s.close();
                   ss.close();
             } catch (IOException e) {
                 e.printStackTrace();
             }
        }
    
        /**
          * 创建界面
          */
         private void createUI(){
             Frame f=new Frame("socketServer");
             ta = new TextArea();
             tf = new TextField();
             Button send = new Button("send");
             
             Panel p = new Panel();
             p.setLayout(new BorderLayout());
             p.add(tf, "Center");
             p.add(send, "East");
             
             f.add(ta, "Center");
             f.add(p, "South");
             
             MyServerListener listener = new MyServerListener(this);
             //不管点击发送按钮还是输入框回车,都会触发listener事件
             send.addActionListener(listener);
             tf.addActionListener(listener);
             //当关闭窗口的时候,退出系统
             f.addWindowListener(new WindowAdapter() {
                 public void windowClosing(WindowEvent e) {
                       System.exit(0);
                 }
            });
            f.setSize(400,400);
            f.setVisible(true);
         }
         
         /**
          * 创建连接
          */
         public void connect(){
             try {
                ss=new ServerSocket(8888);
                s=ss.accept();
                dis=new DataInputStream(s.getInputStream());
                dos=new DataOutputStream(s.getOutputStream());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
         }
         /**
          * 启动监听客户端发来的消息的线程
          */
         public void createThread() {
             MyServerReader reader = new MyServerReader(this);
             reader.start();
         }
    }

    2)MyServerReader类,该类实时监听客户端输入的信息,如果对方输入“bye”,则退出监听并关闭窗口

    package multiThreadChatSocketServer;
    
    import java.awt.TextArea;
    import java.io.DataInputStream;
    import java.io.IOException;
    
    /**
     * 监听客户端发过来的消息,关显示在服务端的界面上
     * @author Administrator
     *
     */
    class MyServerReader extends Thread {
         private SocketServer server;
         public MyServerReader(SocketServer server) {
             this.server = server;
         }
         public void run() {
             String info;
             DataInputStream dis = server.getDataInputStream();
             TextArea ta = server.getTextArea();
             try {
                 while (true) {
                     info = dis.readUTF();
                     ta.append("对方说: " + info + "
    ");
                     if (info.equals("bye")) {
                         server.close();
                         System.exit(0);
                     }
                 }
             } catch (IOException e) {
                 e.printStackTrace();
             }
         }
     }

    3)MyServerListener类,是点发送按钮的时候执行的类

    package multiThreadChatSocketServer;
    
    import java.awt.TextField;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.IOException;
    
    /**
     * 当点击发服务端的送按钮的时候,将信息显示在服务端的界面上,并将信息发送给客户端
     * @author Administrator
     *
     */
    class MyServerListener implements ActionListener {
         private SocketServer server;
     
         public MyServerListener(SocketServer server) {
             this.server = server;
         }
    
         public void actionPerformed(ActionEvent e) {
            TextField tf = server.getTextField();
            String info = tf.getText();
            server.getTextArea().append("自己说: " + info + "
    ");
             try {
                // writeUTF(value:String) :将 UTF-8 字符串写入字节流。先写入以字节表示的 UTF-8 字符串长度(作为 16 位整数),然后写入表示字符串字符的字节。 
                // 因为先把字符长度写入二进制,16位能保存的字节长度为65535,超出这个长度会报RangeError。
                // writeUTFBytes(value:String):不添加字节长度直接写入字符串的字节数据。因此在读取的时候需要指定字节长度
                server.getDataOutputStream().writeUTF(info);
             } catch (IOException e1) {
                 e1.printStackTrace();
            }
             if (info.equals("bye")) {
                 server.close();
                 System.exit(0);
             }
            tf.setText("");
            tf.requestFocus();
         }
     }

    四、客户端

    1)SocketClient类

    package multiThreadChatSocketClient;
    
    import java.awt.*;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class SocketClient {
         private TextArea ta;
         private TextField tf;
         
         private Socket s;
         private DataInputStream dis;
         private DataOutputStream dos;
         
         public TextField getTextField() {
            return tf;
         }
         
         public TextArea getTextArea() {
             return ta;
         }
         
         public DataInputStream getDataInputStream() {
            return dis;
         }
         
         public DataOutputStream getDataOutputStream() {
            return dos;
         }
         
         public static void main(String[] args) {
             SocketClient socketClient = new SocketClient();
             socketClient.createUI();
             socketClient.connect();
             socketClient.createThread();
            }
         
         
         public void close() {
             try {
                   dis.close();
                   dos.close();
                   s.close();
             } catch (IOException e) {
                 e.printStackTrace();
             }
        }
    
        /**
          * 创建界面
          */
         private void createUI(){
             Frame f=new Frame("socketClient");
             ta = new TextArea();
             tf = new TextField();
             Button send = new Button("send");
             
             Panel p = new Panel();
             p.setLayout(new BorderLayout());
             p.add(tf, "Center");
             p.add(send, "East");
             
             f.add(ta, "Center");
             f.add(p, "South");
             
             MyClientListener listener = new MyClientListener(this);
             //不管点击发送按钮还是输入框回车,都会触发listener事件
             send.addActionListener(listener);
             tf.addActionListener(listener);
             //当关闭窗口的时候,退出系统
             f.addWindowListener(new WindowAdapter() {
                 public void windowClosing(WindowEvent e) {
                       System.exit(0);
                 }
            });
            f.setSize(400,400);
            f.setVisible(true);
         }
         
         /**
          * 创建连接
          */
         public void connect(){
             try {
                s = new Socket("127.0.0.1", 8888);
                dis=new DataInputStream(s.getInputStream());
                dos=new DataOutputStream(s.getOutputStream());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
         }
         /**
          * 启动监听服务端发来的消息的线程
          */
         public void createThread() {
             MyClientReader reader = new MyClientReader(this);
             reader.start();
         }
    }

    2)MyClientReader类

    package multiThreadChatSocketClient;
    
    import java.awt.TextArea;
    import java.io.DataInputStream;
    import java.io.IOException;
    
    /**
     * 监听服务端发过来的消息,关显示在客户端的界面上
     * @author Administrator
     *
     */
    class MyClientReader extends Thread {
         private SocketClient client;
         public MyClientReader(SocketClient client) {
             this.client = client;
         }
         public void run() {
             String info;
             DataInputStream dis = client.getDataInputStream();
             TextArea ta = client.getTextArea();
             try {
                 while (true) {
                     info = dis.readUTF();
                     ta.append("对方说: " + info + "
    ");
                     if (info.equals("bye")) {
                         client.close();
                         System.exit(0);
                     }
                 }
             } catch (IOException e) {
                 e.printStackTrace();
             }
         }
     }

    3)MyClientListener类

    package multiThreadChatSocketClient;
    
    import java.awt.TextField;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.IOException;
    
    /**
     * 当点击客户端的发送按钮的时候,将信息显示在客户端的界面上,并将信息发送给服务端
     * @author Administrator
     *
     */
    class MyClientListener implements ActionListener {
         private SocketClient client;
     
         public MyClientListener(SocketClient client) {
             this.client = client;
         }
    
         public void actionPerformed(ActionEvent e) {
            TextField tf = client.getTextField();
            String info = tf.getText();
            client.getTextArea().append("自己说: " + info + "
    ");
             try {
                client.getDataOutputStream().writeUTF(info);
             } catch (IOException e1) {
                 e1.printStackTrace();
            }
             if (info.equals("bye")) {
                 client.close();
                 System.exit(0);
             }
            tf.setText("");
            tf.requestFocus();
         }
     }
  • 相关阅读:
    【Golang】 关于Go 并发之三种线程安全的 map
    Halodoc使用 Apache Hudi 构建 Lakehouse的关键经验
    Logstash优化吞吐率
    ES集群状态yellow修复
    ES集群状态red修复
    vxetable 导出Excel 超过100条,自定义模板template替换失效
    [转]使用minio搭建自己的文件存储服务(新版和旧版)
    [转]vue 预览pdf,txt
    windows7 使用nvs升级降级node.js版本
    新建Token来访问K8S apiserver
  • 原文地址:https://www.cnblogs.com/boshen-hzb/p/5892245.html
Copyright © 2020-2023  润新知