• java程序实现聊天互动(二)


     解决 java程序实现聊天互动(一) 硬编码问题

    将服务端和客户端的端口号和ip放置在配置文件中,同时在ServerChat.java和ClientChat.java使用static代码块

    编写两个java文件:

    ServerChat.java文件

    ClientChat.java文件
    
    

    windows + R 开启cmd黑窗口

    在cmd黑窗口中运行:注意开启两个cmd窗口,称第一个为serverCMD,第二个为clientCMD

    serverCMD:

        跳转到ServerChat.java文件所在的文件夹

            cd D:otest

        编译ServerChat.java文件,编译后会新增一个ServerChat.class文件

            javac ServerChat.java

        运行ServerChat.class文件,注意运行时不要有 .class

            java ServerChat

    clientCMD:

        跳转到ClientChat.java文件所在的文件夹

            cd D:otest

        编译ClientChat.java文件,编译后会新增一个ClientChat.class文件

            javac ClientChat.java

        运行ClientChat.class文件,注意运行时不要有 .class

            java ClientChat

    chat.properties文件

    serverPort=8888
    
    clientIp=127.0.0.1
    clientPort=8888
    

      

    ServerChat.java文件
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.Properties;
    
    //说明:如果一个类,需要有界面显示,那么该类就需要继承自JFrame,此时,该类就可以被称为一个"窗体类"
    //1.定义JFrame 窗体中的组件
    //2.在构造方法中初始化窗体的组件
    //3.使用网络编程完成数据的传输(TCP,UDP 协议)
    //4.实现"发送"按钮的监听点击事件
    //需要注意:文本域拼接数据时,实现自己换行,不要在发送数据中使用System.lineSeparator()换行
    //这样会导致bw.newLine()与System.lineSeparator()两个换行导致使用BufferedReader读取时,无法正确的辨别需要的换行
    //5.实现"回车键"发送数据
    public class ServerChat extends JFrame implements ActionListener, KeyListener {
        public static void main(String[] args) {
            //调用构造方法
            new ServerChat();
        }
    
        //属性
        //文本域
        private JTextArea jta;
        //滚动条
        private JScrollPane jsp;
        //面板
        private JPanel jp;
        //文本框
        private JTextField jtf;
        //按钮
        private JButton jb;
    
        //输出流
        private BufferedWriter bw = null;
    
        //服务端的端口号
        private static int serverPort;
        //使用static 静态代码块读取外部配置文件
        static {
            Properties p = new Properties();
            try {
                //加载
                p.load(new FileReader("chat.properties"));
                //赋值属性值
                serverPort = Integer.parseInt(p.getProperty("serverPort"));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //构造方法
        public ServerChat() {
            //初始化组件
            //文本域
            jta = new JTextArea();
            //注意:需要将文本域添加到滚动条中,实现滚动效果
            //滚动条
            jsp = new JScrollPane(jta);
    
            //面板
            jp = new JPanel();
            //文本框
            jtf = new JTextField(10);//文本框大小
            //按钮
            jb = new JButton("发送");//按钮名称
            //注意:需要将文本框与按钮添加到面板中
            jp.add(jtf);
            jp.add(jb);
    
            //注意:需要将滚动条和面板添加到窗体中
            this.add(jsp, BorderLayout.CENTER);
            this.add(jp,BorderLayout.SOUTH);//上北下南
    
            //注意:需要设置 标题、大小、位置、关闭、是否可见
            this.setTitle("聊天框 服务");//标题
            this.setSize(300,300);// 宽 高
            this.setLocation(300,300);// 水平 垂直
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//窗体关闭 程序退出
            this.setVisible(true);//是否可见
    
            /******************* TCP 服务端 start ****************************/
            //给"发送"按钮绑定一个监听点击事件
            jb.addActionListener(this);//让当前对象监听
            //给文本框绑定一个键盘点击事件
            jtf.addKeyListener(this);
    
            try {
                //1.创建服务端套接字
                ServerSocket serverSocket = new ServerSocket(serverPort);
                //2.等待客户端连接
                Socket socket = serverSocket.accept();
                //3.获取socket 通道的输入流(输入流是实现读取数据,一行一行读取)
                InputStream in = socket.getInputStream();
                BufferedReader br = new BufferedReader(new InputStreamReader(in));
                //4.获取socket 通道的输出流(输出流实现写出数据,也是写一行,换一行,刷新)
                OutputStream out = socket.getOutputStream();
                bw = new BufferedWriter(new OutputStreamWriter(out));
    
                //循环读取数据,并拼接到文本域中
                String line = null;
                while((line = br.readLine()) != null) {
                    //将读取的数据拼接到文本域中显示
                    jta.append(line + System.lineSeparator());//换行
                }
                //5.关闭serverSocket 通道
                serverSocket.close();
            } catch(IOException e) {
                e.printStackTrace();
            }
    
            /******************* TCP 服务端 end ****************************/
    
        }
    
        @Override
        public void actionPerformed(ActionEvent event) {
            //发送数据到socket通道中
            sendDataToSocket();
        }
    
        @Override
        public void keyPressed(KeyEvent e) {
            if(e.getKeyCode() == KeyEvent.VK_ENTER) {
                //发送数据到socket通道中
                sendDataToSocket();
            }
        }
        @Override
        public void keyTyped(KeyEvent e) {
        }
        @Override
        public void keyReleased(KeyEvent e) {
        }
    
        //将数据发送到socket通道中
        private void sendDataToSocket(){
            //1.获取文本框中发送的内容
            String text = jtf.getText();
            //2.拼接需要发送的数据内容
            text = "服务:" + text;
            //3.在自己文本域中显示
            jta.append(text + System.lineSeparator());
    
            try {
                //4.发送
                bw.write(text);
                bw.newLine();
                bw.flush();
                //5.清空文本框内容
                jtf.setText("");
    
            } catch (IOException el) {
                el.printStackTrace();
            }
        }
    }
    

      

    ClientChat.java文件
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.io.*;
    import java.net.Socket;
    import java.util.Properties;
    
    //说明:如果一个类,需要有界面显示,那么该类就需要继承自JFrame,此时,该类就可以被称为一个"窗体类"
    //1.定义JFrame 窗体中的组件
    //2.在构造方法中初始化窗体的组件
    //3.使用网络编程完成数据的传输(TCP,UDP 协议)
    //4.实现"发送"按钮的监听点击事件
    //5.实现"回车键"发送数据
    public class ClientChat extends JFrame implements ActionListener, KeyListener {
        public static void main(String[] args) {
            //调用构造方法
            new ClientChat();
        }
    
        //属性
        //文本域
        private JTextArea jta;
        //滚动条
        private JScrollPane jsp;
        //面板
        private JPanel jp;
        //文本框
        private JTextField jtf;
        //按钮
        private JButton jb;
    
        //输出流
        private BufferedWriter bw = null;
    
        //客户端IP
        private static String clientIp;
        //客户端端口号
        private static int clientPort;
    
        //使用static 静态代码块读取外部配置文件
        static {
            Properties p = new Properties();
            try {
                //加载
                p.load(new FileReader("chat.properties"));
                //赋值属性值
                clientPort = Integer.parseInt(p.getProperty("clientPort"));
                clientIp = p.getProperty("clientIp");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        //构造方法
        public ClientChat() {
            //初始化组件
            //文本域
            jta = new JTextArea();
            //注意:需要将文本域添加到滚动条中,实现滚动效果
            //滚动条
            jsp = new JScrollPane(jta);
    
            //面板
            jp = new JPanel();
            //文本框
            jtf = new JTextField(10);//文本框大小
            //按钮
            jb = new JButton("发送");//按钮名称
            //注意:需要将文本框与按钮添加到面板中
            jp.add(jtf);
            jp.add(jb);
    
            //注意:需要将滚动条和面板添加到窗体中
            this.add(jsp, BorderLayout.CENTER);
            this.add(jp,BorderLayout.SOUTH);//上北下南
    
            //注意:需要设置 标题、大小、位置、关闭、是否可见
            this.setTitle("聊天框 服务");//标题
            this.setSize(300,300);// 宽 高
            this.setLocation(700,300);// 水平 垂直
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//窗体关闭 程序退出
            this.setVisible(true);//是否可见
    
            /******************* TCP 服务端 start ****************************/
            //给"发送"按钮绑定一个监听点击事件
            jb.addActionListener(this);//让当前对象监听
            //给文本框绑定一个键盘点击事件
            jtf.addKeyListener(this);
    
            try {
                //1.创建服务端套接字
                Socket socket = new Socket(clientIp,clientPort);
                //2.获取socket 通道的输入流(输入流是实现读取数据,一行一行读取)
                InputStream in = socket.getInputStream();
                BufferedReader br = new BufferedReader(new InputStreamReader(in));
                //3.获取socket 通道的输出流(输出流实现写出数据,也是写一行,换一行,刷新)
                OutputStream out = socket.getOutputStream();
                bw = new BufferedWriter(new OutputStreamWriter(out));
    
                //循环读取数据,并拼接到文本域中
                String line = null;
                while((line = br.readLine()) != null) {
                    //将读取的数据拼接到文本域中显示
                    jta.append(line + System.lineSeparator());//换行
                }
                //4.关闭serverSocket 通道
                socket.close();
            } catch(IOException e) {
                e.printStackTrace();
            }
    
            /******************* TCP 服务端 end ****************************/
    
        }
    
        @Override
        public void actionPerformed(ActionEvent event) {
            //发送数据到socket通道中
            sendDataToSocket();
        }
    
        @Override
        public void keyPressed(KeyEvent e) {
            if(e.getKeyCode() == KeyEvent.VK_ENTER) {
                //发送数据到socket通道中
                sendDataToSocket();
            }
        }
        @Override
        public void keyTyped(KeyEvent e) {
        }
        @Override
        public void keyReleased(KeyEvent e) {
        }
    
        //将数据发送到socket通道中
        private void sendDataToSocket(){
            //1.获取文本框中发送的内容
            String text = jtf.getText();
            //2.拼接需要发送的数据内容
            text = "客户:" + text;
            //3.在自己文本域中显示
            jta.append(text + System.lineSeparator());
    
            try {
                //4.发送
                bw.write(text);
                bw.newLine();
                bw.flush();
                //5.清空文本框内容
                jtf.setText("");
    
            } catch (IOException el) {
                el.printStackTrace();
            }
        }
    }
    

      

      




  • 相关阅读:
    List
    美团Leaf分布式ID生成策略
    单点登陆
    ElasticSearch
    Eureka
    Nginx
    UML
    Computer English
    加密
    Excel中把一列数据转换成逗号隔开的一行
  • 原文地址:https://www.cnblogs.com/zj68/p/13377387.html
Copyright © 2020-2023  润新知