java实现网络聊天

2023-12-14 23:31:20
网络聊天实现步骤(从功能谈论方法):

客户端:

1.登录面板:注册提醒用户注册格式,登录账号密码不为空,点击登录的时候需要连接服务器端,启动聊天面板。(监听用户点击登录,这时候连接服务器)

2.聊天面板:消息框接收服务器端发送的消息,发送消息框保存消息内容,点击发送按钮将发送消息框递给服务器端(需要创造一个线程不断监听服务器端发送回来的消息,并且显示在消息框)

服务器端:

1.服务器端需要循环监听客户端发送过来的连接

2.把循环接收到的多个客户端用集合储存起来

3.为每个客户端建立一个线程,用来接收他们发送的消息并且为其他客户端转送消息。

4.发送公告功能:聊天面板,发送公告面板,发送按钮(将发送面板的消息发送给各个客户端)。

客户端启动界面

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.Socket;

public class Logon extends JFrame {
    public Logon() {

        this.setTitle("欢迎登录");
        this.setSize(400, 400);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        //标签
        JLabel jLabel = new JLabel("欢迎登录");
        jLabel.setFont(new Font("楷体", Font.BOLD, 20));//字体
        jLabel.setForeground(new Color(21, 12, 12));
        JPanel jPanel = new JPanel();
        jPanel.add(jLabel);
        //账号
        JPanel jPanel1 = new JPanel();
        JLabel jLabel1 = new JLabel("账号");
        JTextField jTextField1 = new JTextField(15);
        jPanel1.add(jLabel1);
        jPanel1.add(jTextField1);
        //密码
        JPanel jPanel2 = new JPanel();
        JLabel jLabel2 = new JLabel("密码");
        JTextField jTextField2 = new JTextField(15);
        jPanel2.add(jLabel2);
        jPanel2.add(jTextField2);
        //按钮
        //登录
        JButton jButton = new JButton("登录");
        jButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (jTextField1.getText().equals("") || jTextField2.getText().equals("")) {
                    JOptionPane.showMessageDialog(null, "请输入");
                } else {
                    try {
                        Socket socket = new Socket("192.168.124.89", 9999);
                        new ChatMap(jTextField1.getText(),socket);
                        dispose();
                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                        JOptionPane.showMessageDialog(null, "没有连接至服务器,请稍后");
                    }
                }
            }
        });
        //注册
        JButton jButton1 = new JButton("注册");
        jButton1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (!jTextField1.getText().matches("\\w*") || !jTextField2.getText().matches("\\w*")) {
                    JOptionPane.showMessageDialog(null, "只支持大小写字母及数字");
                }
            }
        });
        JPanel jPanel3 = new JPanel();
        jPanel3.add(jButton);
        jPanel3.add(jButton1);

        this.setLayout(new GridLayout(4, 1));
        this.add(jPanel);
        this.add(jPanel1);
        this.add(jPanel2);
        this.add(jPanel3);

        this.setVisible(true);//让窗口显示,放在代码的最后一行。
    }
}

客户端聊天界面

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ChatMap extends JFrame {

    JTextArea jTextArea;

    public ChatMap(String account, Socket socket) throws IOException {
        //向服务器发送信息
        DataOutputStream dataOutputStream=new DataOutputStream(socket.getOutputStream());

        this.setTitle("欢迎来到"+account+"聊天室");
        this.setSize(400, 400);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //创造面版
        JPanel jPanel = new JPanel(new BorderLayout());

        //聊天窗口
        jTextArea = new JTextArea(20, 15);
        jTextArea.setEnabled(false);
        jTextArea.setLineWrap(true);
        JScrollPane jScrollPane = new JScrollPane(jTextArea);
        jPanel.add(jScrollPane,BorderLayout.NORTH);
        //输入窗口
        JTextArea jTextArea1 = new JTextArea(1, 10);
        jTextArea.setLineWrap(true);
        JScrollPane jScrollPane1 = new JScrollPane(jTextArea1);
        jPanel.add(jScrollPane1,BorderLayout.CENTER);

        //按钮
        JButton jButton=new JButton("发送");
        jButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
              String message=jTextArea1.getText();
              if(message.length()==0)//为什么要依靠message长度判断
              {
                  JOptionPane.showMessageDialog(null, "输入不能为空");
                  return;
              }
              //不为空显示日期向服务器发送信息
                Date date=new Date();
                SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String str=sdf.format(date);
                String msg=account+":"+str+"\n";
                msg+=message;

                try {
                    dataOutputStream.writeUTF(msg);//发送消息
                    jTextArea1.setText("");//清空发送框
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                    JOptionPane.showMessageDialog(null, "内容发送失败,请检查网络");
                }

            }
        });
        jPanel.add(jButton,BorderLayout.EAST);

        this.add(jPanel);
        this.setVisible(true);//让窗口显示,放在代码的最后一行。

        //面板创造完毕建立监听(服务器传入的消息)
        new BThread(socket,jTextArea).start();
    }
    //内部类监听服务器端
    class BThread extends Thread
    {
        DataInputStream dataInputStream;

       public BThread(Socket socket,JTextArea jTextArea) throws IOException {
          dataInputStream=new DataInputStream(socket.getInputStream());

       }

        @Override
        public void run() {
            while(true)//循环条件:退出
            {
                try {
                    String message=dataInputStream.readUTF();
                    jTextArea.append(message+"\n");
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("服务器断开连接");

                    break;//停止客户端线程
                }
            }
        }
    }

}

启动客户端

public class Run {
    public static void main(String[] args) {
        new Logon();
    }
}

服务器端界面

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class server extends JFrame {
    ArrayList<Socket> sockets=new ArrayList<>();
    Socket socket;
    JTextArea jTextArea;
    JTextArea  jTextArea1;
    JButton jButton;
    public server(){
        //设置窗口
        this.setTitle("服务器");
        this.setSize(400, 400);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel jPanel=new JPanel(new BorderLayout());

        jTextArea=new JTextArea();
        jTextArea.setEnabled(false);//不可进行操作
        jTextArea.setLineWrap(true);
        JScrollPane jScrollPane=new JScrollPane(jTextArea);

        //发送
        JPanel jPanel1=new JPanel();
        jTextArea1=new JTextArea();
        jTextArea1.setEnabled(true);//可进行操作
        jTextArea1.setLineWrap(true);
        JScrollPane jScrollPane1=new JScrollPane(jTextArea1);

        jButton=new JButton("发送");
        jButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String massage=jTextArea1.getText();
                for (Socket s:sockets)
                {
                    DataOutputStream dOut= null;
                    try {
                        dOut = new DataOutputStream(s.getOutputStream());
                        dOut.writeUTF("公告:"+massage);
                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                        JOptionPane.showMessageDialog(null, "发送失败");
                    }

                }
            }
        });


        jPanel1.add(jScrollPane1);
        jPanel1.add(jButton);

        jPanel.add(jScrollPane);
        jPanel.add(jPanel1,BorderLayout.SOUTH);

        this.add(jPanel);
        this.setVisible(true);
        //启动服务器
        this.startServer();



    }

    public void startServer()
    {
        try {
            ServerSocket serverSocket=new ServerSocket(9999);
            while(true)
            {
                socket= serverSocket.accept();//阻塞程序
                System.out.println("服务器启动成功");
                sockets.add(socket);
                System.out.println("有客户端连接上了,客户端连接数为:"+sockets.size());
                //为每一个连接到服务器的客户端开启一个线程
                new A(socket).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("启动服务器失败");
        }
    }

    //创造一个内部类监听各个客户端是否给服务器端发送消息
    class A extends Thread{
        DataInputStream dataInputStream;

        public A(Socket socket) throws IOException {
            dataInputStream=new DataInputStream(socket.getInputStream());
        }

        @Override
        public void run() {
            while (true){//一直厮混换,监听客户端发送的消息
                try {
                    String msg=dataInputStream.readUTF();
                    jTextArea.append(msg+"\n");
                    //向不同的客户端转发消息
                    for(Socket s:sockets)
                    {
                        DataOutputStream dOut=new DataOutputStream(s.getOutputStream());
                        dOut.writeUTF(msg);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("一位客户端下线了");
                    sockets.remove(socket);
                    break;
                }
            }
        }
    }
}

启动服务器

public class serverRun {
    public static void main(String[] args) {
        new server();
    }
}

文章来源:https://blog.csdn.net/2303_77522514/article/details/134904257
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。