欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java實(shí)現(xiàn)多人聊天工具(socket+多線程)

 更新時(shí)間:2021年09月10日 11:37:08   作者:Henrik-Yao  
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)多人聊天工具,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

大一下學(xué)期的java期末課程設(shè)計(jì):java實(shí)現(xiàn)多人聊天工具,分享一下

課設(shè)要求

多人聊天工具

  • 服務(wù)器要求1:能夠看到所有在線用戶(hù)(25%)
  • 服務(wù)器要求2:能夠強(qiáng)制用戶(hù)下線(25%)
  • 客戶(hù)端要求1:能夠看到所有在線用戶(hù)(25%)
  • 客戶(hù)端要求2:能夠向某個(gè)用戶(hù)發(fā)送消息(25%)

相關(guān)知識(shí)點(diǎn)

1.服務(wù)端能夠看到所有在線用戶(hù)

服務(wù)端繼承了JFrame,實(shí)現(xiàn)可視化,通過(guò)socket實(shí)現(xiàn)服務(wù)端與客戶(hù)端的連接,服務(wù)端每接收一個(gè)連接,把傳進(jìn)來(lái)的用戶(hù)名和對(duì)應(yīng)的socket連接封裝成一個(gè)User對(duì)象,把User對(duì)象存進(jìn)一個(gè)ArrayList的用戶(hù)列表并把User對(duì)象通過(guò)取用戶(hù)名方法取得用戶(hù)名存進(jìn)一個(gè)ArrayList的用戶(hù)名列表,添加一個(gè)JPanel組件,將ArrayList中的內(nèi)容通過(guò)循環(huán)顯示JPanel中并布局在窗體的右邊,在每當(dāng)有人上線或者下線,刷新JPanel組件。

2.服務(wù)端能夠強(qiáng)制用戶(hù)下線

創(chuàng)建一個(gè)布局在窗體的下方的JPanel,在此JPanel中分別添加JLabel用于顯示提示文字,添加JTextField用于獲取服務(wù)端想要強(qiáng)制用戶(hù)下線的ID,添加JButton用于綁定強(qiáng)制用戶(hù)下線的事件監(jiān)聽(tīng),事件監(jiān)聽(tīng)中將獲取的JTextField的內(nèi)容與用戶(hù)名列表進(jìn)行逐一匹配,匹配上則創(chuàng)建JSON格式的鍵值對(duì)對(duì)象,通過(guò)用戶(hù)列表循環(huán)廣播告知其他用戶(hù),并在用戶(hù)列表和用戶(hù)名列表中分別刪除該用戶(hù)信息。

3.客戶(hù)端能夠看到所有在線用戶(hù)

客戶(hù)端繼承了JFrame,實(shí)現(xiàn)可視化,添加了一個(gè)布局在窗口右邊的JPanel,把從服務(wù)端接收到的用戶(hù)名列表中的信息放進(jìn)去。

4.客戶(hù)端要求能夠向某個(gè)用戶(hù)發(fā)送消息

客戶(hù)端私發(fā)消息通過(guò)在消息后面加入-和目標(biāo)用戶(hù)名,傳給服務(wù)端,服務(wù)端截取目標(biāo)用戶(hù)名,在用戶(hù)名列表中判斷是否存在此人,有則判斷是否是私發(fā),私發(fā)則向目標(biāo)用戶(hù)發(fā)送消息,沒(méi)有則向全部用戶(hù)發(fā)送消息。

5.運(yùn)用JDBC實(shí)現(xiàn)持久化存儲(chǔ)用戶(hù)信息

數(shù)據(jù)庫(kù)連接池運(yùn)用了阿里巴巴的durid,定義一個(gè)JDBCUtils類(lèi),提供靜態(tài)代碼塊加載配置文件,初始化連接池對(duì)象,通過(guò)Spring框架的JDBCTemplate對(duì)象進(jìn)行sql語(yǔ)句的執(zhí)行,在UserDao中提供了登錄和注冊(cè)方法,登錄方法運(yùn)用queryForObject方法進(jìn)行登錄查詢(xún),如果查到返回一個(gè)User對(duì)象,查不到則返回空,注冊(cè)方法直接插入新記錄,此處建表語(yǔ)句中把用戶(hù)名設(shè)置成了主鍵,保證了用戶(hù)名的唯一性,注冊(cè)失敗有警告彈窗提示。
這里加了一個(gè)ChatTest類(lèi)用于繞過(guò)數(shù)據(jù)庫(kù)賬號(hào)校驗(yàn),可以直接進(jìn)入客戶(hù)端進(jìn)行連接。

6.使用JSONObject對(duì)象封裝數(shù)據(jù)

在數(shù)據(jù)的傳輸中運(yùn)用了鍵值對(duì)的形式進(jìn)行傳輸,客戶(hù)端傳輸給服務(wù)端的數(shù)據(jù)包中,通過(guò)判斷private鍵的值來(lái)確認(rèn)是否私發(fā),通過(guò)username鍵告知服務(wù)端客戶(hù)端的用戶(hù)名,通過(guò)msg鍵傳輸具體消息,服務(wù)端傳輸給客戶(hù)端的數(shù)據(jù)包中,通過(guò)判斷user_list鍵的值來(lái)確認(rèn)在線用戶(hù)及人數(shù)

7.使用Maven構(gòu)建管理項(xiàng)目

項(xiàng)目中運(yùn)用到了JDBC相關(guān)內(nèi)容和JSONObject對(duì)象,導(dǎo)入了一些依賴(lài)jar包,其中倉(cāng)庫(kù)和配置文件都是用的idea默認(rèn)配置。

類(lèi)圖

項(xiàng)目框架

核心代碼

1.maven配置文件pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>MyChat</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>15</maven.compiler.source>
        <maven.compiler.target>15</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
            <classifier>jdk15</classifier>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.45</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.6</version>
        </dependency>
    </dependencies>

</project>

2.服務(wù)器端Server.java

import java.awt.image.BufferedImage;
import java.io.*;
import java.net.*;
import java.util.*;
import java.awt.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import net.sf.json.JSONObject;


//繼承JFrame實(shí)現(xiàn)可視化
public class Server extends JFrame{

    //用戶(hù)列表,用于存放連接上的用戶(hù)信息
    ArrayList<User> user_list = new ArrayList<>();
    //用戶(hù)名列表,用于顯示已連接上的用戶(hù)
    ArrayList<String> username_list = new ArrayList<>();

    //消息顯示區(qū)域
    JTextArea show_area = new JTextArea();
    //用戶(hù)名顯示區(qū)域
    JTextArea show_user = new JTextArea(10, 10);

    //socket的數(shù)據(jù)輸出流
    DataOutputStream outputStream = null;
    //socket的數(shù)據(jù)輸入流
    DataInputStream inputStream = null;

    //從主函數(shù)里面開(kāi)啟服務(wù)端
    public static void main(String[] args) {
        new Server();
    }

    //構(gòu)造函數(shù)
    public Server() {

        //設(shè)置流式布局
        setLayout(new BorderLayout());
        //VERTICAL_SCROLLBAR_AS_NEEDED設(shè)置垂直滾動(dòng)條需要時(shí)出現(xiàn)
        //HORIZONTAL_SCROLLBAR_NEVER設(shè)置水平滾動(dòng)條不出現(xiàn)
        //創(chuàng)建信息顯示區(qū)的畫(huà)布并添加到show_area
        JScrollPane panel = new JScrollPane(show_area,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        //設(shè)置信息顯示區(qū)標(biāo)題
        panel.setBorder(new TitledBorder("信息顯示區(qū)"));
        //布局到中央
        add(panel,BorderLayout.CENTER);
        //設(shè)置信息顯示區(qū)為不可編輯
        show_area.setEditable(false);


        //創(chuàng)建用于顯示用戶(hù)的畫(huà)布
        final JPanel panel_east = new JPanel();
        //添加流式布局
        panel_east.setLayout(new BorderLayout());
        //設(shè)置標(biāo)題
        panel_east.setBorder(new TitledBorder("在線用戶(hù)"));
        //在用戶(hù)顯示區(qū)添加show_uesr
        panel_east.add(new JScrollPane(show_user), BorderLayout.CENTER);
        //設(shè)置用戶(hù)顯示區(qū)域?yàn)椴豢删庉?
        show_user.setEditable(false);
        //將顯示用戶(hù)的畫(huà)布添加到整體布局的右側(cè)
        add(panel_east, BorderLayout.EAST);

        //創(chuàng)建關(guān)于踢下線用戶(hù)的畫(huà)布
        final JPanel panel_south = new JPanel();
        //創(chuàng)建標(biāo)簽
        JLabel label = new JLabel("輸入要踢下線用戶(hù)的ID");
        //創(chuàng)建輸入框
        JTextField out_area = new JTextField(40);
        //創(chuàng)建踢下線按鈕
        JButton out_btn = new JButton("踢下線");
        //依次添加進(jìn)畫(huà)布
        panel_south.add(label);
        panel_south.add(out_area);
        panel_south.add(out_btn);
        //將踢下線用戶(hù)的畫(huà)布添加到整體布局的下側(cè)
        add(panel_south,BorderLayout.SOUTH);

        //設(shè)置踢下線按鈕的監(jiān)聽(tīng)
        out_btn.addActionListener(e -> {
            try {
                //用于存儲(chǔ)踢下線用戶(hù)的名字
                String out_username;
                //從輸入框中獲取踢下線用戶(hù)名
                out_username = out_area.getText().trim();
                //用于判斷蓋用戶(hù)是否被踢下線
                boolean is_out=false;
                //遍歷用戶(hù)列表依次判斷
                for (int i = 0; i < user_list.size(); i++){
                    //比較用戶(hù)名,相同則踢下線
                    if(user_list.get(i).getUsername().equals(out_username)){
                        //獲取被踢下線用戶(hù)對(duì)象
                        User out_user = user_list.get(i);
                        //使用json封裝將要傳遞的數(shù)據(jù)
                        JSONObject data = new JSONObject();
                        //封裝全體用戶(hù)名,廣播至所有用戶(hù)
                        data.put("user_list", username_list);
                        //廣播的信息內(nèi)容
                        data.put("msg", out_user.getUsername() + "被管理員踢出\n");
                        //服務(wù)端消息顯示區(qū)顯示相應(yīng)信息
                        show_area.append(out_user.getUsername() + "被你踢出\n");
                        //依次遍歷用戶(hù)列表
                        for (User value : user_list) {
                            try {
                                //獲取每個(gè)用戶(hù)列表的socket連接
                                outputStream = new DataOutputStream(value.getSocket().getOutputStream());
                                //傳遞信息
                                outputStream.writeUTF(data.toString());
                            } catch (IOException ex) {
                                ex.printStackTrace();
                            }
                        }
                        //將被踢用戶(hù)移出用戶(hù)列表
                        user_list.remove(i);
                        //將被踢用戶(hù)移出用戶(hù)名列表
                        username_list.remove(out_user.getUsername());
                        //刷新在線人數(shù)
                        show_user.setText("人數(shù)有 " + username_list.size() + " 人\n");
                        //刷新在線用戶(hù)
                        for (String s : username_list) {
                            show_user.append(s + "\n");
                        }
                        //判斷踢出成功
                        is_out=true;
                        break;
                    }

                }
                //根據(jù)是否踢出成功彈出相應(yīng)提示
                if(is_out){
                    JOptionPane.showMessageDialog(null,"踢下線成功","提示",
                            JOptionPane.WARNING_MESSAGE);
                }
                if(!is_out){
                    JOptionPane.showMessageDialog(null,"不存在用戶(hù)","提示",
                            JOptionPane.WARNING_MESSAGE);
                }
                //重置輸入框
                out_area.setText("");
            } catch(Exception ex) {
                ex.printStackTrace();
            }
        });

        //設(shè)置該窗口名
        setTitle("服務(wù)器 ");
        //引入圖片
        BufferedImage img;
        try {
            //根據(jù)圖片名引入圖片
            img = ImageIO.read(Server.class.getResource("/a.jpg"));
            //設(shè)置其為該窗體logo
            setIconImage(img);
        } catch (IOException exception) {
            exception.printStackTrace();
        }
        //設(shè)置窗體大小
        setSize(700, 700);
        //設(shè)置窗體位置可移動(dòng)
        setLocationRelativeTo(null);
        //設(shè)置窗體關(guān)閉方式
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //設(shè)置窗體可見(jiàn)
        setVisible(true);

        //socket連接相關(guān)代碼
        try {
            //開(kāi)啟socket服務(wù)器,綁定端口11111
            ServerSocket serverSocket = new ServerSocket(11111);
            //信息顯示區(qū)打印服務(wù)器啟動(dòng)時(shí)間
            show_area.append("服務(wù)器啟動(dòng)時(shí)間 " + new Date() + "\n");
            //持續(xù)接收連接
            while (true) {
                //接收連接
                Socket socket = serverSocket.accept();
                //創(chuàng)建用戶(hù)對(duì)象
                User user = new User();
                //判斷是否連接上
                if (socket != null) {
                    //獲取輸入流
                    inputStream = new DataInputStream(socket.getInputStream());
                    //讀取輸入流
                    String json = inputStream.readUTF();
                    //創(chuàng)建信息對(duì)象
                    JSONObject data = JSONObject.fromObject(json);
                    //信息顯示區(qū)打印用戶(hù)上線
                    show_area.append("用戶(hù) " + data.getString("username") + " 在" + new Date() + "登陸系統(tǒng)"+"\n");
                    //創(chuàng)建新用戶(hù)
                    user = new User();
                    //存儲(chǔ)socket對(duì)象
                    user.setSocket(socket);
                    //獲取輸入流用戶(hù)名
                    user.setUsername(data.getString("username"));
                    //添加進(jìn)用戶(hù)列表
                    user_list.add(user);
                    //添加進(jìn)用戶(hù)名列表
                    username_list.add(data.getString("username"));

                    //刷新在線人數(shù)
                    show_user.setText("人數(shù)有 " + username_list.size() + " 人\n");
                    //刷新在線用戶(hù)
                    for (String s : username_list) {
                        show_user.append(s + "\n");
                    }

                }

                //封裝信息對(duì)象
                JSONObject online = new JSONObject();
                //設(shè)置接收信息對(duì)象
                online.put("user_list", username_list);
                //設(shè)置信息內(nèi)容
                online.put("msg", user.getUsername() + "上線了");
                //依次遍歷,將信息廣播給所有在線用戶(hù)
                for (User value : user_list) {
                    //獲取輸出流
                    outputStream = new DataOutputStream(value.getSocket().getOutputStream());
                    //給所有用戶(hù)輸出上線信息
                    outputStream.writeUTF(online.toString());
                }

                //開(kāi)啟新線程,持續(xù)接收該socket信息
                new Thread(new ServerThread(socket)).start();

            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    //線程代碼
    class ServerThread implements Runnable {
        //存放全局變量socket
        private final Socket socket;

        //構(gòu)造函數(shù),初始化socket
        public ServerThread(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            try {
                //獲取輸入流
                DataInputStream inputStream = new DataInputStream(socket.getInputStream());
                //持續(xù)接收信息
                while (true) {
                    //獲取傳遞進(jìn)來(lái)的信息
                    String json = inputStream.readUTF();
                    //封裝成json格式
                    JSONObject data = JSONObject.fromObject(json);

                    //通過(guò)json里面的private判斷是否私發(fā)
                    boolean is_private = false;
                    //私發(fā)處理
                    for (int i = 0; i < user_list.size(); i++) {
                        //找到私發(fā)對(duì)象
                        if (user_list.get(i).getUsername().equals(data.getString("private"))) {
                            //構(gòu)建私發(fā)信息內(nèi)容
                            String msg = data.getString("time") +"\n" + data.getString("username")
                                    + " 給你發(fā)了一條私密消息,其它用戶(hù)看不到" + "\n"  + data.getString("msg");
                            //用該方法指定對(duì)象發(fā)送信息
                            send_msg(i, msg);

                            //將發(fā)送成功反饋給原用戶(hù)
                            for (int j = 0; j < user_list.size(); j++) {
                                //找到發(fā)信息用戶(hù)
                                if(user_list.get(j).getUsername().equals(data.getString("username"))){
                                    //構(gòu)建反饋信息內(nèi)容
                                    String msg2 = data.getString("time")+"\n你成功向"+user_list.get(i).getUsername()
                                            +"發(fā)送了一條私密消息\n" +data.getString("msg");
                                    //用該方法指定對(duì)象發(fā)送信息
                                    send_msg(j,msg2);
                                }
                            }
                            //將該操作打印到服務(wù)器監(jiān)視窗
                            show_area.append(data.getString("username") +data.getString("time")+ "私發(fā)給"
                                    + data.getString("private") + ":\n" + data.getString("msg") + "\n");
                            //判斷是私發(fā)
                            is_private = true;
                            break;
                        }
                    }
                    //非私發(fā)的情況
                    if (!is_private) {
                        //構(gòu)建信息內(nèi)容
                        String msg = data.getString("username") + " " + data.getString("time") + ":\n"
                                + data.getString("msg");
                        //添加到服務(wù)器顯示
                        show_area.append(msg + "\n");
                        //依次發(fā)給所有在線用戶(hù)
                        for (int i = 0; i < user_list.size(); ) {
                            send_msg(i, msg);
                            i++;
                        }
                    }

                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


        //發(fā)送信息給指定用戶(hù)的方法
        public void send_msg(int i, String msg) {
            //構(gòu)建對(duì)象
            JSONObject data = new JSONObject();
            //封裝信息
            data.put("user_list", username_list);
            data.put("msg", msg);
            //獲取目標(biāo)對(duì)象
            User user = user_list.get(i);
            try {
                //獲取輸出流
                outputStream = new DataOutputStream(user.getSocket().getOutputStream());
                //寫(xiě)信息
                outputStream.writeUTF(data.toString());
            } catch (IOException e) {
                //如果沒(méi)有找到,則說(shuō)明該用戶(hù)已經(jīng)下線
                User out_user = user_list.get(i);
                //重復(fù)刪除操作
                user_list.remove(i);
                username_list.remove(out_user.getUsername());
                //重新構(gòu)建信息
                JSONObject out = new JSONObject();
                out.put("user_list", username_list);
                out.put("msg", out_user.getUsername() + "下線了\n");
                //將其下線通知廣播給所有用戶(hù)
                for (User value : user_list) {
                    try {
                        outputStream = new DataOutputStream(value.getSocket().getOutputStream());
                        outputStream.writeUTF(out.toString());
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            }

        }
    }


}

代碼太多了,懶得注釋了,大家應(yīng)該看得懂

3.客戶(hù)端登錄界面Client.java

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.image.BufferedImage;
import java.io.IOException;


public class Client extends JFrame{


    public static void main(String[] args) {
        new Client();
    }

    public Client(){
        setTitle("登陸界面");
        BufferedImage img;
        try {
            img = ImageIO.read(Server.class.getResource("/a.jpg"));
            setIconImage(img);
        } catch (IOException exception) {
            exception.printStackTrace();
        }
        setLayout(null);
        setSize(500,500);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setLayout(null);
        setResizable(false);

        JLabel username_label = new JLabel("用戶(hù)名");
        username_label.setBounds(60,100,100,50);
        add(username_label);

        JLabel password_label = new JLabel("密碼");
        password_label.setBounds(60,200,100,50);
        add(password_label);

        JTextField username_field = new JTextField();
        username_field.setBounds(110,100,300,50);
        add(username_field);

        JPasswordField password_field = new JPasswordField();
        password_field.setBounds(110,200,300,50);
        add(password_field);

        JButton login = new JButton("登陸");
        login.setBounds(130,300,100,50);
        add(login);
        JButton register = new JButton("注冊(cè)");
        register.setBounds(280,300,100,50);
        add(register);

        setVisible(true);


        login.addActionListener(e -> {
            String username = username_field.getText();
            String password = String.valueOf(password_field.getPassword());
            if(username.length()!=0 && password.length()!=0){
                User user = new User();
                user.setUsername(username);
                user.setPassword(password);
                UserDao dao = new UserDao();
                User u = dao.login(user);
                if(u!=null){
                    setVisible(false);
                    new Chat(username);
                }else{
                    JOptionPane.showMessageDialog(null,"登錄失敗,賬號(hào)或密碼錯(cuò)誤","提示",
                        JOptionPane.WARNING_MESSAGE);
                }
            }else {
                JOptionPane.showMessageDialog(null,"登錄失敗,賬號(hào)或密碼不能為空","提示",
                        JOptionPane.WARNING_MESSAGE);
            }
        });

        register.addActionListener(e -> {
            setVisible(false);
            new Register();
        });
    }

}

4.客戶(hù)端注冊(cè)界面Register.java

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.image.BufferedImage;
import java.io.IOException;


public class Register extends JFrame {
    public Register(){
        setTitle("注冊(cè)界面");
        BufferedImage img;
        try {
            img = ImageIO.read(Server.class.getResource("/a.jpg"));
            this.setIconImage(img);
        } catch (IOException exception) {
            exception.printStackTrace();
        }
        setLayout(null);
        setSize(500,500);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setLayout(null);
        setResizable(false);

        JLabel username_label = new JLabel("用戶(hù)名");
        username_label.setBounds(60,50,100,50);
        add(username_label);

        JLabel password_label = new JLabel("密碼");
        password_label.setBounds(60,150,100,50);
        add(password_label);

        JLabel password_label2 = new JLabel("請(qǐng)?jiān)俅屋斎朊艽a");
        password_label2.setBounds(20,250,100,50);
        add(password_label2);

        JTextField username_field = new JTextField();
        username_field.setBounds(110,50,300,50);
        add(username_field);

        JPasswordField password_field = new JPasswordField();
        password_field.setBounds(110,150,300,50);
        add(password_field);

        JPasswordField password_field2 = new JPasswordField();
        password_field2.setBounds(110,250,300,50);
        add(password_field2);


        JButton register_success = new JButton("注冊(cè)");
        register_success.setBounds(130,350,100,50);
        add(register_success);

        JButton back = new JButton("返回");
        back.setBounds(280,350,100,50);
        add(back);

        setVisible(true);


        register_success.addActionListener(e -> {
            String username = username_field.getText();
            String password = String.valueOf(password_field.getPassword());
            String password2 = String.valueOf(password_field2.getPassword());
            System.out.println(password);
            System.out.println(password2);
            if(username.length()==0 || password.length()==0){
                JOptionPane.showMessageDialog(null,"注冊(cè)失敗,賬號(hào)或密碼不能為空","提示",
                        JOptionPane.WARNING_MESSAGE);
            }else if (!password.equals(password2)) {
                JOptionPane.showMessageDialog(null,"注冊(cè)失敗,前后密碼不匹配","提示",
                        JOptionPane.WARNING_MESSAGE);
            }else{
                System.out.println();
                System.out.println(password);
                User user = new User();
                user.setUsername(username);
                user.setPassword(password);
                UserDao dao = new UserDao();
                int flag = dao.register(user);
                if(flag!=0){
                    JOptionPane.showMessageDialog(null,"注冊(cè)成功,歡迎您登錄","提示",
                            JOptionPane.WARNING_MESSAGE);

                }else{
                    //建表語(yǔ)句中設(shè)置了user為主鍵,重復(fù)則建表失敗
                    JOptionPane.showMessageDialog(null,"注冊(cè)失敗,賬號(hào)已經(jīng)存在","提示",
                            JOptionPane.WARNING_MESSAGE);
                }
            }
        });

        back.addActionListener(e ->{
           setVisible(false);
           new Client();
        });


    }

}

5.客戶(hù)端聊天界面Chat.java

import java.awt.image.BufferedImage;
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.awt.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
public class Chat extends JFrame{

    JTextArea show_area = new JTextArea();
    JTextArea show_user = new JTextArea(10, 10);
    DataOutputStream outputStream;
    DataInputStream inputStream;
    String username;
    ArrayList<String> username_list = new ArrayList<>();
    boolean is_stop = false;

    public Chat(final String username) {
        this.username = username;
        
        final JPanel panel_south = new JPanel();
        panel_south.setLayout(new BorderLayout());
        panel_south.setBorder(new TitledBorder("寫(xiě)消息區(qū),若私聊,在內(nèi)容后添加(-用戶(hù)名)"));
        JTextField send_area = new JTextField(40);
        panel_south.add(send_area, BorderLayout.CENTER);
        JButton send_btn = new JButton("發(fā)送");
        panel_south.add(send_btn,BorderLayout.EAST);
        add(panel_south, BorderLayout.SOUTH);

        send_btn.addActionListener(e -> {
            try {

                if (is_stop) {
                    show_area.append("你已被踢出,不能發(fā)送消息\n");
                    JOptionPane.showMessageDialog(null,"你已被踢出,不能發(fā)送消息,進(jìn)程已經(jīng)關(guān)閉","提示",
                            JOptionPane.WARNING_MESSAGE);
                    System.exit(0);
                } else {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String time = sdf.format(new Date());

                    String msg = send_area.getText().trim();

                    if (!msg.equals("")) {
                        String[] msg1 = msg.split("-");
                        JSONObject data = new JSONObject();
                        data.put("username", username);
                        data.put("msg", msg1[0]);
                        data.put("time", time);

                        try {
                            data.put("private", msg1[1]);

                        } catch (ArrayIndexOutOfBoundsException e1) {
                            data.put("private", "");
                        }
                        outputStream.writeUTF(data.toString());
                    }
                }
                send_area.setText("");
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        });

        JScrollPane panel = new JScrollPane(show_area,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        panel.setBorder(new TitledBorder("信息顯示區(qū)"));
        add(panel,BorderLayout.CENTER);
        show_area.setEditable(false);
        
        final JPanel panel_east = new JPanel();
        panel_east.setLayout(new BorderLayout());
        panel_east.setBorder(new TitledBorder("在線用戶(hù)"));
        panel_east.add(new JScrollPane(show_user), BorderLayout.CENTER);
        show_user.setEditable(false);
        add(panel_east, BorderLayout.EAST);

        setTitle("用戶(hù)  " + username);
        BufferedImage img;
        try {
            img = ImageIO.read(Server.class.getResource("/a.jpg"));
            this.setIconImage(img);
        } catch (IOException exception) {
            exception.printStackTrace();
        }
        setSize(500, 500);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);

        JSONObject data = new JSONObject();
        data.put("username", username);
        data.put("msg", null);

        try {
            Socket socket = new Socket("127.0.0.1", 11111);
            inputStream = new DataInputStream(socket.getInputStream());
            outputStream = new DataOutputStream(socket.getOutputStream());
            outputStream.writeUTF(data.toString());
            new Thread(new Read()).start();
        } catch (IOException e) {
            show_area.append("服務(wù)器無(wú)響應(yīng)");
            JOptionPane.showMessageDialog(null,"服務(wù)器無(wú)響應(yīng)","提示",
                    JOptionPane.WARNING_MESSAGE);
        }
    }

    public class Read implements Runnable {
        @Override
        public void run() {
            try {
                while (true) {
                    String json = inputStream.readUTF();
                    JSONObject data = JSONObject.fromObject(json);
                    String msg = data.getString("msg");
                    if (msg.contains("踢出") && msg.contains(username)) {
                        is_stop = true;
                        show_area.append(username + ",你已經(jīng)被踢出群聊\n");
                        JOptionPane.showMessageDialog(null,"你已經(jīng)被踢出群聊","提示",
                                JOptionPane.WARNING_MESSAGE);
                        System.exit(0);
                    } else {
                        show_area.append(msg + "\n");
                        show_area.selectAll();
                        username_list.clear();
                        JSONArray jsonArray = data.getJSONArray("user_list");
                        for (Object o : jsonArray) {
                            username_list.add(o.toString());
                        }
                        show_user.setText("人數(shù)有 " + jsonArray.size() + " 人\n");
                        for (String s : username_list) {
                            show_user.append(s + "\n");
                        }
                    }

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

6.用戶(hù)實(shí)體User.java

import java.net.Socket;

public class User {
    private String username;
    private String password;
    private Socket socket;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Socket getSocket() {
        return socket;
    }

    public void setSocket(Socket socket) {
        this.socket = socket;
    }
}

7.JDBC工具類(lèi)

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.util.Properties;

public class JDBCUtils {
    private static DataSource ds;

    static {
        try {
            Properties pro = new Properties();
            InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
            pro.load(is);
            ds = DruidDataSourceFactory.createDataSource(pro);
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

    public static DataSource getDataSource(){
        return ds;
    }


}

8.UserDao.java連接數(shù)據(jù)庫(kù)

import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

 

public class UserDao {
    private final JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());


    public User login(User login_user) {
        try {
            //編寫(xiě)sql
            String sql = "select * from user where username = ? and password = ?";

            User user = template.queryForObject(sql,
                    new BeanPropertyRowMapper<User>(User.class),
                    login_user.getUsername(), login_user.getPassword());
            return user;
        } catch (DataAccessException e) {
            e.printStackTrace();
            return null;
        }
    }

    public int register(User register_user) {
        try {
            String sql = "insert into user values (null ,?,?)";
            int count = template.update(sql,register_user.getUsername(),register_user.getPassword());
            return count;
        } catch (DataAccessException e) {
            e.printStackTrace();
            return 0;
        }
    }

}

運(yùn)行結(jié)果

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 在netty中使用native傳輸協(xié)議的方法

    在netty中使用native傳輸協(xié)議的方法

    這篇文章主要介紹了在netty中使用native傳輸協(xié)議,這里我們只以Kqueue為例介紹了netty中native傳輸協(xié)議的使用,需要的朋友可以參考下
    2022-05-05
  • Java文件管理操作的知識(shí)點(diǎn)整理

    Java文件管理操作的知識(shí)點(diǎn)整理

    這篇文章主要為大家詳細(xì)介紹了Java中文件管理操作的一些知識(shí)點(diǎn)和實(shí)現(xiàn)方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下
    2022-09-09
  • Java面試突擊之Bean作用域詳解

    Java面試突擊之Bean作用域詳解

    Spring?框架作為一個(gè)管理?Bean?的?IoC?容器,那么?Bean?自然是?Spring?中的重要資源了,那?Bean?的作用域是什么意思?又有幾種類(lèi)型呢?接下來(lái)我們一起來(lái)看
    2022-08-08
  • 詳解JavaWeb如何實(shí)現(xiàn)文件上傳和下載功能

    詳解JavaWeb如何實(shí)現(xiàn)文件上傳和下載功能

    這篇文章主要介紹了如何利用JavaWeb實(shí)現(xiàn)文件的上傳和下載功能,文中的示例代碼講解詳細(xì),對(duì)我們的學(xué)習(xí)或工作有一定的幫助,感興趣的小伙伴可以學(xué)習(xí)一下
    2021-12-12
  • Spring、SpringMvc和SpringBoot的區(qū)別及說(shuō)明

    Spring、SpringMvc和SpringBoot的區(qū)別及說(shuō)明

    Spring框架提供了全面的Java開(kāi)發(fā)解決方案,核心包括IOC和AOP,SpringMvc作為其中的WEB層開(kāi)發(fā)框架,通過(guò)復(fù)雜的XML配置管理前端視圖和后臺(tái)邏輯,SpringBoot則簡(jiǎn)化了配置,專(zhuān)注于微服務(wù)接口開(kāi)發(fā),支持嵌入式服務(wù)器,提高了開(kāi)發(fā)效率
    2024-10-10
  • mybatis 獲取無(wú)數(shù)據(jù)的字段不顯示的問(wèn)題

    mybatis 獲取無(wú)數(shù)據(jù)的字段不顯示的問(wèn)題

    這篇文章主要介紹了mybatis 獲取無(wú)數(shù)據(jù)的字段不顯示的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Java實(shí)現(xiàn)音頻添加自定義時(shí)長(zhǎng)靜音的示例代碼

    Java實(shí)現(xiàn)音頻添加自定義時(shí)長(zhǎng)靜音的示例代碼

    這篇文章主要介紹了一個(gè)Java工具類(lèi),可以實(shí)現(xiàn)給一個(gè)wav音頻添加自定義時(shí)長(zhǎng)靜音。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編學(xué)習(xí)一下
    2022-01-01
  • spring boot 統(tǒng)一JSON格式的接口返回結(jié)果的實(shí)現(xiàn)

    spring boot 統(tǒng)一JSON格式的接口返回結(jié)果的實(shí)現(xiàn)

    這篇文章主要介紹了spring boot 統(tǒng)一JSON格式的接口返回結(jié)果的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • 淺談Java多線程實(shí)現(xiàn)及同步互斥通訊

    淺談Java多線程實(shí)現(xiàn)及同步互斥通訊

    下面小編就為大家?guī)?lái)一篇淺談Java多線程實(shí)現(xiàn)及同步互斥通訊。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-04-04
  • java中同類(lèi)對(duì)象之間的compareTo()和compare()方法對(duì)比分析

    java中同類(lèi)對(duì)象之間的compareTo()和compare()方法對(duì)比分析

    這篇文章主要介紹了java中同類(lèi)對(duì)象之間的compareTo()和compare()方法對(duì)比分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09

最新評(píng)論