java简易聊天程序

目录

项目结构

TCP

窗体组成

 server

client

 properties



项目结构

 

TCP

窗体组成

 server

package cn.itcast.chat;

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.定义窗体类组件
// 2.在构造方法中初始化属性
// 3.使用网络编程实现数据传输 (TCP,UDP 协议)
// 4.实现发送按钮的监听点击事件
    //需要注意的是,文本域拼接数据时,实现自己换行,不要在发送数据中使用 Svstem.ineSeparator( 换行)
// 5.实现回车键发送数据
public class ServerChatMain extends JFrame implements ActionListener, KeyListener {
    public static void main(String[] args) {
        new ServerChatMain();
    }

    //属性
    //文本域
    private JTextArea jTextArea;
    //滚动条
    private JScrollPane jScrollPane;
    //面板
    private JPanel jPanel;
    //文本框(发送消息)
    private JTextField jTextField;
    //按钮(发送)
    private JButton jButton;
    
    //输出流
    private BufferedWriter bufferedWriter ;
    //服务端端口号
    private static int serverPort;
    // 使用 static 静态代码块读取配置文件
        // 特点1.在类加载的时候,自动执行
        // 特点2,一个类只会被加载一次,因此静态代码块只会被执行一次
    static {
        Properties properties = new Properties();
        try {
            // 加载
            properties.load(new FileReader("chat.properties"));
            // 给属性赋值
            serverPort = Integer.parseInt(properties.getProperty("serverPort"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //构造方法初
    public ServerChatMain() {
        //始化组件
        //文本域
        jTextArea = new JTextArea();
        jTextArea.setEditable(false);//设置文本域不可编辑(默认),所以注释掉
        //  将文本域添加到滚动条中,实现滚动效果
        jScrollPane = new JScrollPane(jTextArea);
        //面板
        jPanel = new JPanel();
        //文本框长度10
        jTextField = new JTextField(20);
        //按钮
        jButton = new JButton("发送");
        //  将文本框和按钮添加到面板中
        jPanel.add(jTextField);
        jPanel.add(jButton);

        //将滚动条和面板全部添加到窗体中
        this.add(jScrollPane,BorderLayout.CENTER);//添加到中间
        this.add(jPanel,BorderLayout.SOUTH);//下面

        // 设置 标题、大小、标题、位置、关闭、是否可见
        this.setTitle("QQ聊天,服务端");
        this.setSize(500,500);
        this.setLocation(300,300);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//窗体关闭就退出
        this.setVisible(true);

        /***************** TCP 服务端 star  *************************/
        //给发送按钮绑定一个监听点击事件   需要实现 ActionListener 接口,重写方法
        jButton.addActionListener(this);
        // 给文本框绑定一个键盘点击事件 需要实现 KeyListener 接口,重写方法 keyPressed()
        jTextField.addKeyListener(this);
        try {
            // 1.创建服务端套接字
            ServerSocket serverSocket = new ServerSocket(serverPort);
            // 2.等待客户端的连接
            Socket socket = serverSocket.accept();
    
            // 4.获取socket 通道的输出流    (输出流实现写出数据,也是写一行,换一行,刷新) Bufferedwriter -> newLine();
            // 问题 : 什么时候需要写出数据??? 当用户点击~发送~ 按的时候才需要写出数据
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            // 3.获取socket 通道的输入流
            // 输出流是实现读取数据,如何读取 ??? 一行一行读取)  所以用 BufferedReader 类的 -> readLine()方法;
            InputStream input = socket.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(input));

    
            // 循环读取数据、并拼接到文本域中
            String line = null;
            System.out.println("...............  " + bufferedReader.readLine());
            while ((line =bufferedReader.readLine()) != null){
                System.out.println("line: " + line);
                //将读取的数据拼接到上面文本域中显示
                jTextArea.append(line + System.lineSeparator());
            }
            // 5.关闭 serverSocket 通道
            serverSocket.close();
            
        } catch (IOException e) {
            e.printStackTrace();
        }


        /***************** TCP 服务端 end  **************************/

    }
    
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("发送按钮点击、进入了监听方法。。。。。");
        sendDataToSocket();
    }
    
    // 按下
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER){ //回车键
            System.out.println(e);//可以敲击不同的按键查看其 keyCode、keyText...
            sendDataToSocket();
        }
    }
    
    // 定义一个方法、将数据发送到 socket 通道中去
    private void sendDataToSocket(){
        // 1. 获取文本框中的发送内容
        String text = jTextField.getText();
        // 2. 拼接需要发送的内容数据
        text = "服务端对客户端说: " + text;
        // 3. 自己的文本域中显示
        jTextArea.append(text + System.lineSeparator());
        System.out.println("server: " + text);
        try {
            // 4. 发送 (这里需要用到 bufferedWriter 所以是字段)
            bufferedWriter.write(text);
            bufferedWriter.newLine();//换行
            bufferedWriter.flush();//刷新
            // 5. 清空文本框
            jTextField.setText("");
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    
    // 被敲击
    @Override
    public void keyTyped(KeyEvent e) {
    }
    // 松开
    @Override
    public void keyReleased(KeyEvent e) {
    }
}

client

package cn.itcast.chat;

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;

public class ClientChatMain extends JFrame implements ActionListener, KeyListener {
    public static void main(String[] args) {
        new ClientChatMain();
    }

    //属性
    //文本域
    private JTextArea jTextArea;
    //滚动条
    private JScrollPane jScrollPane;
    //面板
    private JPanel jPanel;
    //文本框(发送消息)
    private JTextField jTextField;
    //按钮(发送)
    private JButton jButton;
   
    // 输出流
    BufferedWriter bufferedWriter = null;
    // 客户端 ip地址
    private static  String clientIP;
    // 客户端 port端口号
    private static  int clientPort;
    
    static {
        Properties properties = new Properties();
        try {
            // 加载
            properties.load(new FileReader("chat.properties"));
            // 给属性赋值
            clientIP = properties.getProperty("clientIP");
            clientPort = Integer.parseInt(properties.getProperty("clientPort"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    
    //构造方法初
    public ClientChatMain() {
        //始化组件
        //文本域
        jTextArea = new JTextArea();
        jTextArea.setEditable(false);//设置文本域不可编辑(默认),所以注释掉
        //  将文本域添加到滚动条中,实现滚动效果
        jScrollPane = new JScrollPane(jTextArea);
        //面板
        jPanel = new JPanel();
        //文本框长度10
        jTextField = new JTextField(20);
        //按钮
        jButton = new JButton("发送");
        //  将文本框和按钮添加到面板中
        jPanel.add(jTextField);
        jPanel.add(jButton);

        //将滚动条和面板全部添加到窗体中
        this.add(jScrollPane, BorderLayout.CENTER);//添加到中间
        this.add(jPanel,BorderLayout.SOUTH);//下面

        // 设置 标题、大小、标题、位置、关闭、是否可见
        this.setTitle("QQ聊天,客户端");
        this.setSize(500,500);
        this.setLocation(900,300);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//窗体关闭就退出
        this.setVisible(true);

        /***************** TCP 客户端 star  *************************/
        // 给发送按钮绑定一个监听事件
        jButton.addActionListener(this);
        // 给文本框绑定一个键盘点击事件
        jTextField.addKeyListener(this);
        try {
            // 1.创建客户端套接字(并且自动尝试连接)
            Socket socket = new Socket(clientIP, clientPort);
            // 2.获取socket 通道的输入流
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            // 3.获取socket 通道的输出流
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            // 循环读取数据、并拼接到文本域中
            String line = null;
            while ((line = bufferedReader.readLine()) != null){
                System.out.println("client: " + line);
                jTextArea.append(line + System.lineSeparator());
            }
            
            // 4.关闭socket通道
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        /***************** TCP 客户端 end  **************************/
    }
    
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("发送按钮点击,进入了客户端.....");
        sendDataToSocket();
    }
    
    // 按下
    @Override
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_ENTER){
            // 将数据发送到socket通道
            sendDataToSocket();
        }
    }
    
    private void sendDataToSocket() {
        // 1. 获取文本框中需要发送的数据内容
        String text = jTextField.getText();
        // 2. 拼接内容
        text = "客户端对服务端说: " + text;
        // 3. 自己显示
        jTextArea.append(text + System.lineSeparator());
        try {
            // 4. 发送
            bufferedWriter.write(text);
            bufferedWriter.newLine();
            bufferedWriter.flush();
            // 5. 清空
            jTextField.setText("");
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    
    @Override
    public void keyTyped(KeyEvent e) {
    }
    @Override
    public void keyReleased(KeyEvent e) {
    
    }
}

 properties

serverPort=8888
clientIP=127.0.0.1
clientPort=8888

  • 4
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值