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

Java聊天室之實(shí)現(xiàn)客戶(hù)端群聊功能

 更新時(shí)間:2022年10月26日 09:12:17   作者:小虛竹and掘金  
這篇文章主要為大家詳細(xì)介紹了Java簡(jiǎn)易聊天室之實(shí)現(xiàn)客戶(hù)端群聊功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以了解一下

一、題目描述

題目實(shí)現(xiàn):不同的客戶(hù)端之間需要進(jìn)行通信,一個(gè)客戶(hù)端與其他的多個(gè)客戶(hù)端進(jìn)行通信,實(shí)現(xiàn)群聊功能。

實(shí)現(xiàn)一個(gè)客戶(hù)端與其他多個(gè)客戶(hù)端進(jìn)行通信,運(yùn)行程序,服務(wù)器啟動(dòng)后,啟動(dòng)3個(gè)客戶(hù)端程序,然后通過(guò)第一個(gè)客戶(hù)端向另外兩個(gè)客戶(hù)端發(fā)送信息,則另外的兩個(gè)客戶(hù)端都會(huì)收到服務(wù)器發(fā)送的信息。

二、解題思路

創(chuàng)建一個(gè)服務(wù)類(lèi):ClientOneToManyServerFrame,繼承JFrame類(lèi)

定義一個(gè)createSocket()方法,用于創(chuàng)建服務(wù)Socket和監(jiān)聽(tīng)客戶(hù)端程序。以及創(chuàng)建并啟動(dòng)線(xiàn)程對(duì)象并將接收到的客戶(hù)端發(fā)送的信息轉(zhuǎn)發(fā)給其他客戶(hù)端。

創(chuàng)建一個(gè)客戶(hù)端類(lèi):ClientOneToManyClientFrame,繼承JFrame類(lèi)

定義一個(gè)createClientSocket()方法,用于創(chuàng)建與服務(wù)器連接的Socket對(duì)象,輸出流對(duì)象,以及啟動(dòng)線(xiàn)程對(duì)象接收服務(wù)器端轉(zhuǎn)發(fā)的信息。

技術(shù)重點(diǎn):

在服務(wù)器端通過(guò)線(xiàn)程對(duì)客戶(hù)端發(fā)送的信息進(jìn)行監(jiān)聽(tīng),當(dāng)有客戶(hù)端發(fā)送信息時(shí),就會(huì)將該信息發(fā)送給其他已經(jīng)登錄到服務(wù)器的客戶(hù)端,但是不會(huì)向發(fā)送方發(fā)送該信息,在客戶(hù)端也通過(guò)線(xiàn)程來(lái)監(jiān)聽(tīng)服務(wù)器轉(zhuǎn)發(fā)的信息。 (1)在服務(wù)器端創(chuàng)建線(xiàn)程類(lèi)ServerThread,用于接收客戶(hù)端發(fā)送的信息,并轉(zhuǎn)發(fā)給其他已經(jīng)連接到服務(wù)器的客戶(hù)端。

(2)在客戶(hù)端創(chuàng)建線(xiàn)程類(lèi)ClientThread,用于接收服務(wù)器端轉(zhuǎn)發(fā)的客戶(hù)端信息,并在客戶(hù)端的文本域中顯示接收到的信息。

啟動(dòng)多個(gè)客戶(hù)端:

1、把項(xiàng)目打成jar包:利用maven 的clean install

會(huì)在target目錄下生成jar包

2、進(jìn)入target目錄,使用java -cp的命令運(yùn)行指定的類(lèi)

java -cp 命令中 cp 指的就是classpath。使用該命令可以運(yùn)行jar中的某個(gè)指定的類(lèi)(要包含全路徑的包名)

進(jìn)入cmd命令模式

運(yùn)行服務(wù)端

java -cp basics98-1.0-SNAPSHOT.jar com.xiaoxuzhu.ClientOneToManyServerFrame

運(yùn)行多個(gè)客戶(hù)端

java -cp basics98-1.0-SNAPSHOT.jar com.xiaoxuzhu.ClientOneToManyClientFrame

三、代碼詳解

ClientOneToManyServerFrame

package com.xiaoxuzhu;
import java.awt.BorderLayout;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
/**
 * Description:
 *
 * @author xiaoxuzhu
 * @version 1.0
 *
 * <pre>
 * 修改記錄:
 * 修改后版本	        修改人		修改日期			修改內(nèi)容
 * 2022/6/5.1	    xiaoxuzhu		2022/6/5		    Create
 * </pre>
 * @date 2022/6/5
 */
public class ClientOneToManyServerFrame extends JFrame {
    private JTextArea ta_info;
    private ServerSocket server; // 聲明ServerSocket對(duì)象
    private Socket socket; // 聲明Socket對(duì)象socket
    private Vector<Socket> vector = new Vector<Socket>();// 用于存儲(chǔ)連接到服務(wù)器的客戶(hù)端套接字對(duì)象

    public void createSocket() {
        try {
            server = new ServerSocket(9527);
            while (true) {
                ta_info.append("等待新客戶(hù)連接......\n");
                socket = server.accept();// 創(chuàng)建套接字對(duì)象
                vector.add(socket);// 將套接字對(duì)象添加到向量對(duì)象中
                ta_info.append("客戶(hù)端連接成功。" + socket + "\n");
                new ServerThread(socket).start();// 創(chuàng)建并啟動(dòng)線(xiàn)程對(duì)象
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    class ServerThread extends Thread {
        Socket socket;
        public ServerThread(Socket socket) {
            this.socket = socket;
        }
        public void run() {
            try {
                BufferedReader in = new BufferedReader(new InputStreamReader(
                        socket.getInputStream()));// 創(chuàng)建輸入流對(duì)象
                while (true) {
                    String info = in.readLine();// 讀取信息
                    for (Socket s : vector) {// 遍歷所有客戶(hù)端套接字對(duì)象
                        if (s != socket) {// 如果不是發(fā)送信息的套接字對(duì)象
                            PrintWriter out = new PrintWriter(s
                                    .getOutputStream(), true);// 創(chuàng)建輸出流對(duì)象
                            out.println(info);// 發(fā)送信息
                            out.flush();// 刷新輸出緩沖區(qū)
                        }
                    }
                }
            } catch (IOException e) {
                ta_info.append(socket + "已經(jīng)退出。\n");
                vector.remove(socket);// 移除退出的客戶(hù)端套接字
            }
        }
    }

    /**
     * Launch the application
     *
     * @param args
     */
    public static void main(String args[]) {
        ClientOneToManyServerFrame frame = new ClientOneToManyServerFrame();
        frame.setVisible(true);
        frame.createSocket();
    }

    /**
     * Create the frame
     */
    public ClientOneToManyServerFrame() {
        super();
        setTitle("客戶(hù)端一對(duì)多通信——服務(wù)器端程序");
        setBounds(100, 100, 385, 266);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final JScrollPane scrollPane = new JScrollPane();
        getContentPane().add(scrollPane, BorderLayout.CENTER);

        ta_info = new JTextArea();
        scrollPane.setViewportView(ta_info);
    }
}

ClientOneToManyClientFrame

package com.xiaoxuzhu;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/**
 * Description: 
 *
 * @author xiaoxuzhu
 * @version 1.0
 *
 * <pre>
 * 修改記錄:
 * 修改后版本	        修改人		修改日期			修改內(nèi)容
 * 2022/6/5.1	    xiaoxuzhu		2022/6/5		    Create
 * </pre>
 * @date 2022/6/5
 */
public class ClientOneToManyClientFrame extends JFrame{
    private JTextArea ta_info;
    private JTextField tf_send;
    PrintWriter out;// 聲明輸出流對(duì)象

    /**
     * Launch the application
     *
     * @param args
     */
    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    ClientOneToManyClientFrame frame = new ClientOneToManyClientFrame();
                    frame.setVisible(true);
                    frame.createClientSocket();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public void createClientSocket() {
        try {
            Socket socket = new Socket("127.0.0.1", 9527);// 創(chuàng)建套接字對(duì)象
            out = new PrintWriter(socket.getOutputStream(), true);// 創(chuàng)建輸出流對(duì)象
            new ClientThread(socket).start();// 創(chuàng)建并啟動(dòng)線(xiàn)程對(duì)象
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    class ClientThread extends Thread {
        Socket socket;

        public ClientThread(Socket socket) {
            this.socket = socket;
        }

        public void run() {
            try {
                BufferedReader in = new BufferedReader(new InputStreamReader(
                        socket.getInputStream()));// 創(chuàng)建輸入流對(duì)象
                while (true) {
                    String info = in.readLine();// 讀取信息
                    ta_info.append(info + "\n");// 在文本域中顯示信息
                    if (info.equals("88")) {
                        break;// 結(jié)束線(xiàn)程
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    private void send() {
        String info = tf_send.getText();// 獲得輸入的信息
        if (info.equals("")) {
            return;// 如果沒(méi)輸入信息則返回,即不發(fā)送
        }
        if (info.equals("88")) {
            System.exit(0);// 如果沒(méi)輸入信息是88,則退出
        }
        out.println(info);// 發(fā)送信息
        out.flush();// 刷新輸出緩沖區(qū)
        tf_send.setText(null);// 清空文本框
    }
    /**
     * Create the frame
     */
    public ClientOneToManyClientFrame() {
        super();
        setTitle("客戶(hù)端一對(duì)多通信——客戶(hù)端程序");
        setBounds(100, 100, 385, 266);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final JPanel panel = new JPanel();
        getContentPane().add(panel, BorderLayout.SOUTH);

        final JLabel label = new JLabel();
        label.setText("輸入聊天內(nèi)容:");
        panel.add(label);

        tf_send = new JTextField();
        tf_send.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                send();// 調(diào)用方法發(fā)送信息
            }
        });
        tf_send.setPreferredSize(new Dimension(180, 25));
        panel.add(tf_send);

        final JButton button = new JButton();
        button.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                send();// 調(diào)用方法發(fā)送信息
            }
        });
        button.setText("發(fā)  送");
        panel.add(button);

        final JScrollPane scrollPane = new JScrollPane();
        getContentPane().add(scrollPane, BorderLayout.CENTER);

        ta_info = new JTextArea();
        scrollPane.setViewportView(ta_info);
        //
    }
}

服務(wù)器啟動(dòng)

客戶(hù)端1向其他客戶(hù)端群發(fā)信息

客戶(hù)端2接收到的信息

客戶(hù)端3接收到的信息

以上就是Java聊天室之實(shí)現(xiàn)客戶(hù)端群聊功能的詳細(xì)內(nèi)容,更多關(guān)于Java聊天室的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解如何使用MongoDB+Springboot實(shí)現(xiàn)分布式ID的方法

    詳解如何使用MongoDB+Springboot實(shí)現(xiàn)分布式ID的方法

    這篇文章主要介紹了詳解如何使用MongoDB+Springboot實(shí)現(xiàn)分布式ID的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • IDEA如何撤銷(xiāo)本地commit的代碼

    IDEA如何撤銷(xiāo)本地commit的代碼

    這篇文章主要介紹了IDEA如何撤銷(xiāo)本地commit的代碼問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • IDEA 當(dāng)前在線(xiàn)人數(shù)和歷史訪(fǎng)問(wèn)量的示例代碼

    IDEA 當(dāng)前在線(xiàn)人數(shù)和歷史訪(fǎng)問(wèn)量的示例代碼

    這篇文章主要介紹了IDEA 當(dāng)前在線(xiàn)人數(shù)和歷史訪(fǎng)問(wèn)量的實(shí)例代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Filter在springboot中的使用方法詳解

    Filter在springboot中的使用方法詳解

    這篇文章主要介紹了Filter在springboot中的使用方法詳解,filter(過(guò)濾器)作用于在intreceptor(攔截器)之前,不像intreceptor一樣依賴(lài)于springmvc框架,只需要依賴(lài)于serverlet,需要的朋友可以參考下
    2023-08-08
  • java匿名內(nèi)部類(lèi)實(shí)例代碼詳解

    java匿名內(nèi)部類(lèi)實(shí)例代碼詳解

    這篇文章主要介紹了java匿名內(nèi)部類(lèi)實(shí)例代碼詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Flink JobGraph生成源碼解析

    Flink JobGraph生成源碼解析

    這篇文章主要為大家介紹了Flink JobGraph生成源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • SpringBoot+Redis防止惡意刷新與暴力請(qǐng)求接口的實(shí)現(xiàn)

    SpringBoot+Redis防止惡意刷新與暴力請(qǐng)求接口的實(shí)現(xiàn)

    這篇文章主要為大家介紹了如何利用springboot和Redis來(lái)實(shí)現(xiàn)防止惡意刷新與暴力請(qǐng)求接口,文中的示例代碼講解詳細(xì),需要的可以參考一下
    2022-06-06
  • 理解Java面向?qū)ο缶幊淘O(shè)計(jì)

    理解Java面向?qū)ο缶幊淘O(shè)計(jì)

    這篇文章主要介紹了理解Java面向?qū)ο缶幊淘O(shè)計(jì),面向?qū)ο缶幊淌且环N編程思維方式和編碼架構(gòu)。下面詳細(xì)內(nèi)容,需要的小伙伴可以參考一下
    2022-01-01
  • 淺談MyBatisPlus中LocalDateTime引發(fā)的一些問(wèn)題和解決辦法

    淺談MyBatisPlus中LocalDateTime引發(fā)的一些問(wèn)題和解決辦法

    MyBatisPlus進(jìn)行數(shù)據(jù)庫(kù)操作時(shí),我們經(jīng)常會(huì)遇到處理日期時(shí)間類(lèi)型的需求,本文主要介紹了淺談MyBatisPlus中LocalDateTime引發(fā)的一些問(wèn)題和解決辦法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-07-07
  • 詳解Java中的final關(guān)鍵字的使用

    詳解Java中的final關(guān)鍵字的使用

    這篇文章主要介紹了詳解Java中的final關(guān)鍵字的使用,是Java入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-07-07

最新評(píng)論