JAVA基于UDP的一个聊天程序

这是一个使用Java Swing库创建的图形用户界面,包括一个基础面板类`Panel1`和两个派生类`Panel2`(聊天室界面)。`Panel2`实现了聊天功能,分为客户端`Client1`和服务器端`Receive`,通过UDP套接字进行通信。用户输入账号,点击‘确定’按钮后,可以输入聊天内容并发送,同时可以离线断开连接。
摘要由CSDN通过智能技术生成

学校的实验课的一个小程序 

图形界面

Panel1

import javax.swing.*;
import java.awt.*;

public class Panel1 extends JPanel{
    protected int size;
    protected JLabel labels[];
    protected JTextField fields[];
    //“确定”按钮,根据派生子类的要求具体实现
    protected JButton doTask1;
    protected JLabel  promptLabel;
    //中区域:文本区
    protected JTextArea textArea;
    //南区域:根据派生子类的要求可放置不同的图形组件
    JPanel  southPanel;
    public Panel1(int mySize){
        setLayout(new BorderLayout());
        //北区域
        size = mySize;
        labels = new JLabel[size];
        fields = new JTextField[size];
        for (int count = 0; count < labels.length; count++)
            labels[count] = new JLabel("标签"+count,SwingConstants.RIGHT);
        for (int count = 0; count < fields.length; count++)
            fields[count] = new JTextField(12);
        JPanel innerPanelCenter = new JPanel();
        for (int count = 0; count < size; count++) {
            JPanel innerPanel=new JPanel();
            innerPanel.add(labels[count]);
            innerPanel.add(fields[count]);
            innerPanelCenter.add(innerPanel);
        }
        doTask1 = new JButton("确定");
        innerPanelCenter.add(doTask1);
        promptLabel=new JLabel("设置提示!");
        promptLabel.setForeground(Color.red);
        promptLabel.setBorder(BorderFactory.createTitledBorder("提示"));
        JPanel northPanel=new JPanel(new BorderLayout());
        northPanel.add(innerPanelCenter, BorderLayout.CENTER);
        northPanel.add(promptLabel, BorderLayout.SOUTH);
        add(northPanel,BorderLayout.NORTH);
        //中区域
        textArea=new JTextArea();
        //设置自动换行
        textArea.setLineWrap(true);
        //字边界换行
        textArea.setWrapStyleWord(true);
        textArea.setFont(new Font("幼圆", Font.PLAIN, 16));
        add(new JScrollPane(textArea),BorderLayout.CENTER);
        //南区域
        //调用本类方法:初始化南边图形界面组件
        southPanel=this.setSouthPanel();
        add(this.setSouthPanel(),BorderLayout.SOUTH);
    }
    //该方法创建南边的图形界面组件,子类中根据需要覆盖它
    protected JPanel setSouthPanel(){
        JPanel panelSouth=new JPanel();
        panelSouth.add(new JLabel("子类中需重写南边的图形组件,以满足不同要求!"));
        return panelSouth;
    }
    //测试MyPanel2类
    public static void main(String args[]) {
        JFrame app= new JFrame("通用图形界面--父类MyPanel2");
        Panel1 p=new Panel1(1);
        p.labels[0].setText("账号");
        app.getContentPane().add(p,BorderLayout.CENTER);
        app.setSize(400, 300);
        app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        app.setVisible(true);
    }
}

Panel2

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

/*聊天室图形界面类:实现了各按钮的动作监听:但只提供空方法体,由子类分别实现具体的功能。*/
public class Panel2 extends Panel1 implements ActionListener{
    //南边的图形界面
    //文本框:输入聊天内容
    protected JTextField southField;
    //“发送”按钮:发送聊天内容
    protected JButton sendButton;
    //“离线”按钮,断开连接
    protected JButton exitButton;
    //昵称
    protected String nickname="我们";
    //初始化面板中的图形组件
    public Panel2() {
        //图形界面继承自父类,但修改了文字提示、南边图形界面
        //调用父类构造方法:有1个标签labels[0],1个文本框fields[0]
        super(1);
        // 设置第1个标签提示文字
        labels[0].setText("输入账号");
        promptLabel.setText("单击\"确定\"按钮,若服务器和客户连接上后,可开始聊天!");
        //北边“确定”按钮增加监听
        doTask1.addActionListener(this);
        //南边“发送”按钮增加监听
        sendButton.addActionListener(this);
        //南边“离线”按钮增加监听
        exitButton.addActionListener(this);
    }
    //“确定”、“发送”、“离线”3按钮单击时将执行的任务
    public void actionPerformed(ActionEvent e) {
        if(e.getSource()==doTask1){//北边“确定”按钮
            doTask1Button();
        }
        if(e.getSource()==sendButton){//南边“发送”按钮
            sendButton();
        }
        if(e.getSource()==exitButton){//南边“离线”按钮
            exitButton();
        }
    }
    //单击北边“确定”按钮执行的动作:只提供空方法体,由子类实现具体功能
    protected void doTask1Button(){
    }
    //单击南边“发送”按钮执行的动作:只提供空方法体,由子类实现具体功能
    protected void sendButton(){
    }
    //单击南边“离线”按钮执行的动作:只提供空方法体,由子类实现具体功能
    protected void exitButton(){
    }
    //覆盖父类同名方法,重新设置聊天室南边的GUI
    protected JPanel setSouthPanel() {
        //聊天面板南边,一个文本框输入聊天内容、两个按钮(“发送”和“离线”)
        //放置南边组件的面板对象
        JPanel southPanel = new JPanel();
        //输入聊天内容的文本框
        southField = new JTextField(20);
        southPanel.add(southField);
        //“发送”按钮
        sendButton = new JButton("发送");
        //初试设置为不可用
        sendButton.setEnabled(false);
        southPanel.add(sendButton);
        //“离线”按钮
        exitButton = new JButton("离线");
        //初试设置为不可用
        exitButton.setEnabled(false);
        southPanel.add(exitButton);
        //返回包含上述组件的面板对象
        return southPanel;
    }
    //测试ChatPanel类
    public static void main(String args[]){
        JFrame app= new JFrame("聊天界面");
        app.getContentPane().add(new Panel2());
        app.setSize(400, 300);
        app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        app.setVisible(true);
    }
}

客户端

import java.io.*;
import java.net.*;
import javax.swing.JFrame;

public class Client1 extends Panel2 implements Runnable{
    protected DatagramSocket sendSocket;
    //线程对象,用于接收对方发送的字符串
    protected Thread  thread;
    InetAddress inetAddress;
    {
        try {
            sendSocket = new DatagramSocket(9090);
        } catch (SocketException e) {
            e.printStackTrace();
        }

    }
    public Client1(){
        super();
    }
    protected void sendButton() {
        nickname=fields[0].getText();
            String str =nickname + "说:" +  southField.getText();
            //要发送的信息
            byte[] bytes = str.getBytes();
            //发送的目标地址
            inetAddress = null;
            try {
                inetAddress = InetAddress.getByName("127.0.0.1");
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
            //数据报文
            DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, inetAddress, 9091);
            //发送
            try {
                sendSocket.send(datagramPacket);
            } catch (IOException e) {
                e.printStackTrace();
            }
        textArea.append("我说:"+southField.getText() + "\n");
    }
    protected void exitButton(){
        try {
            //向对方发送串“bye”,当对方收到后,关闭连接
            String s1 = "bye";
            byte[] bytes = s1.getBytes();
            inetAddress = null;
            try {
                inetAddress = InetAddress.getByName("127.0.0.1");
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
            DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, inetAddress, 9091);
            sendButton.setEnabled(false);
            exitButton.setEnabled(false);
            textArea.append("连接断开!");
            sendSocket.send(datagramPacket);
            //sendSocket.close();
        }catch(Exception e) {
            e.printStackTrace();
        }

    }
    public void run() {
        System.out.println("线程启动!");

            while (true) {
                byte[] bytes = new byte[1024];
                //创建一个报文,于与接收
                DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
                //接收
                try {
                sendSocket.receive(datagramPacket);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                String s2 = new String(bytes,0,datagramPacket.getLength());

                if (s2.equals("bye")) {
                    sendButton.setEnabled(false);
                    exitButton.setEnabled(false);
                    textArea.append("连接断开!!");
                    break;
                } else {
                    textArea.append(s2 + "\n");
                }
            }


    }
    //单击北边按钮:连接服务器,开始聊天
    protected void doTask1Button(){
        textArea.append("连接服务器!\n");

        thread = new Thread(this);
        //启动线程,执行run()方法
        thread.start();
        doTask1.setEnabled(false);
        //设置南边“发送”按钮可用
        sendButton.setEnabled(true);
        //设置南边“离线”按钮可用
        exitButton.setEnabled(true);
    }
    //启动聊天室客户端程序
    public static void main(String args[]) {
        JFrame app= new JFrame("客户端");
        app.getContentPane().add(new Client1());
        app.setSize(400, 300);
        app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        app.setVisible(true);
    }
}

服务端

import java.io.IOException;
import java.net.*;

public class Receive extends Panel2 implements Runnable{
    protected DatagramSocket sendSocket;
    //线程对象,用于接收对方发送的字符串
    protected Thread  thread;
    InetAddress inetAddress;

    { try {
        sendSocket = new DatagramSocket(9091);
    } catch (SocketException e) {
        e.printStackTrace();
    }}

    public Receive(){
        super();
    }
    protected void sendButton() {

        nickname=fields[0].getText();
            String str = nickname + "说:" + southField.getText();
            //要发送的信息
            byte[] bytes = str.getBytes();
            //发送的目标地址
            inetAddress = null;
            try {
                inetAddress = InetAddress.getByName("127.0.0.1");
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
            //数据报文
            DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, inetAddress, 9090);
            //发送
            try {
                sendSocket.send(datagramPacket);
            } catch (IOException e) {
                e.printStackTrace();
            }
        textArea.append("我说:"+southField.getText() + "\n");
        }



    protected void exitButton(){
        try {
            //向对方发送串“bye”,当对方收到后,关闭连接
            String s1 = "bye";
            byte[] bytes = s1.getBytes();
            inetAddress = null;
            try {
                inetAddress = InetAddress.getByName("127.0.0.1");
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
            DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, inetAddress, 9090);
            sendButton.setEnabled(false);
            exitButton.setEnabled(false);
            textArea.append("连接断开!");
            sendSocket.send(datagramPacket);
            //sendSocket.close();
        }catch(Exception e) {
            e.printStackTrace();
        }

    }
    public void run() {
        System.out.println("线程启动!");



            while (true) {
                byte[] bytes = new byte[1024];
                //创建一个报文,于与接收
                DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
                //接收

                try { sendSocket.receive(datagramPacket);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                String s2 = new String(bytes,0,datagramPacket.getLength());

                if (s2.equals("bye")) {
                    sendButton.setEnabled(false);
                    exitButton.setEnabled(false);
                    textArea.append("连接断开!!");
                    break;
                } else {
                    textArea.append(s2 + "\n");
                }
            }


    }
    protected void doTask1Button(){

        thread = new Thread(this);
        //启动线程,执行run()方法
        thread.start();
        doTask1.setEnabled(false);
        //设置南边“发送”按钮可用
        sendButton.setEnabled(true);
        //设置南边“离线”按钮可用
        exitButton.setEnabled(true);

    }
    public static void main(String[] args) {
        JFrame app= new JFrame("服务器端");
        app.getContentPane().add(new Receive());
        app.setSize(400, 300);
        app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        app.setVisible(true);
    }
}

代码可能有点繁多,没有采取什么框架一类的,主要是为了完成作业。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值