最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java多線程實(shí)現(xiàn)多人聊天室功能

 更新時(shí)間:2021年06月25日 13:25:02   作者:CHANGEA-code  
這篇文章主要為大家詳細(xì)介紹了Java多線程實(shí)現(xiàn)多人聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文為大家分享了Java多線程實(shí)現(xiàn)多人聊天室功能的具體代碼,供大家參考,具體內(nèi)容如下

1.實(shí)驗(yàn)?zāi)康模?/h3>

編寫(xiě)一個(gè) Java 應(yīng)用程序,實(shí)現(xiàn)圖形界面多人聊天室(多線程實(shí)現(xiàn)),要求聊天室窗口標(biāo)題是 “歡迎使用 XXX 聊天室應(yīng)用”,其中 XXX 是自己的班級(jí)姓名學(xué)號(hào),如“軟件 171 張三 1234”。

2.實(shí)驗(yàn)代碼:

服務(wù)端程序代碼:

ServerChar.java

package works;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class ServerChat {

 //定義Map集合用于存儲(chǔ)用戶(hù)的Socket以及用戶(hù)的名字   key:Socket    Value:用戶(hù)名
 public final static Map<Socket,String> socketsMaps = Collections.synchronizedMap(new HashMap<Socket,String>());
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  try {
   // 創(chuàng)建服務(wù)端套接字
   ServerSocket serverSocket = new ServerSocket(9999); 
System.out.println("------服務(wù)端暴露-------");
   while (true) {
    // 監(jiān)聽(tīng)客戶(hù)端套接字,若有客戶(hù)端連接,則代碼不會(huì)往下執(zhí)行,否則會(huì)堵塞在此處。
    Socket socket = serverSocket.accept();

    // 開(kāi)啟線程,用于讀取客戶(hù)端發(fā)送的信息,并轉(zhuǎn)發(fā)給每一個(gè)客戶(hù)端
    new ThreadServer(socket).start();
   }
  } catch (Exception e) {
   // TODO: handle exception
   e.printStackTrace();
  }
 }
}

class ThreadServer extends Thread {
 private Socket socket;
 ThreadServer(){};
 ThreadServer(Socket socket)
 {
  this.socket = socket;
 }
 @Override
 public void run() {
  try {
   while(true)
   {
    DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
    String data = dataInputStream.readUTF();
    
    if(data.startsWith("①②③④")&&data.endsWith("①②③④"))
    {
     //發(fā)送過(guò)來(lái)的是用戶(hù)名
     //將Socket以及用戶(hù)名字都存放在Map集合中
     ServerChat.socketsMaps.put(socket, data.replace("①②③④",""));
     //獲取所有的key(Socket),將所有用戶(hù)的名字發(fā)送至客戶(hù)端
     Set<Socket> sockets = ServerChat.socketsMaps.keySet();
     //獲取所有的用戶(hù)的名字,將這些名字拼裝成一個(gè)字符串
     Collection<String> names = ServerChat.socketsMaps.values();
     StringBuffer sbf = new StringBuffer();
     for(String userName :names)
     {
      sbf.append(userName).append(",");
     }
     System.out.println("sbf:"+sbf.toString());
     for(Socket soc:sockets)
     {
      DataOutputStream dataOutputStream = new DataOutputStream(soc.getOutputStream());
      dataOutputStream.writeUTF("①②③④"+sbf.toString()+"①②③④");
      dataOutputStream.flush();
     }
    }
    else{
     //發(fā)送過(guò)來(lái)的是聊天信息
     //獲取所有的key(Socket),將所有用戶(hù)的名字發(fā)送至客戶(hù)端
     Set<Socket> sockets = ServerChat.socketsMaps.keySet();
     //將聊天信息廣播出去
     for(Socket soc:sockets)
     {
      DataOutputStream dataOutputStream = new DataOutputStream(soc.getOutputStream());
      dataOutputStream.writeUTF("[ "+ServerChat.socketsMaps.get(socket)+" ]說(shuō):"+data);
      dataOutputStream.flush();
     }
     
     
    }
    
   }
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
}

客戶(hù)端程序代碼:

ClientChar.java

package works;

import java.awt.BorderLayout;
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 javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class ClientChat {

 private JFrame mainWin = new JFrame("聊天窗口");

 // 消息展示框
 private JTextArea displayTa = new JTextArea(14, 40);
 // 在線用戶(hù)名稱(chēng)展示框
 private DefaultListModel<String> userListModel = new DefaultListModel<>();
 private JList<String> userList = new JList<>(userListModel);
 // 消息發(fā)送框
 private JTextArea inputTF = new JTextArea(4, 40);
 // 消息按鈕
 private JButton sendBn = new JButton("發(fā)送");
 // 用戶(hù)記錄當(dāng)前聊天用戶(hù)名
 private String curUser;

 public static void main(String[] args) {
  new ClientChat().init();
 }

 private void init() {
  try {
   // 通過(guò)彈出對(duì)話框獲取用戶(hù)輸入的用戶(hù)名
   String userName = JOptionPane.showInputDialog(mainWin, "請(qǐng)輸入您的用戶(hù)名:");
   // 把用戶(hù)輸入的用戶(hù)名,賦給curUser
   curUser = userName;
   mainWin.setTitle(curUser + "的聊天窗口");

   // 創(chuàng)建套接字
   Socket socket = new Socket("192.168.193.1", 9999);
   // 向服務(wù)器聲明
   DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
   //發(fā)送用戶(hù)名到服務(wù)端
   dataOutputStream.writeUTF("①②③④"+userName+"①②③④");
   dataOutputStream.flush();

   // 開(kāi)啟線程,用于讀取服務(wù)器發(fā)送的信息
   new ThreadClient(socket, this).start();

   JPanel bottomPanel = new JPanel();

   // 將消息框和按鈕添加到窗口的底端
   mainWin.add(bottomPanel, BorderLayout.SOUTH);
   bottomPanel.add(inputTF);
   bottomPanel.add(sendBn);

   ActionListener listener = new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
     // 獲取用戶(hù)發(fā)送的消息
     String message = inputTF.getText();
     sendSms(message,socket);
    }
   };
   // 給發(fā)送消息按鈕綁定點(diǎn)擊事件監(jiān)聽(tīng)器
   sendBn.addActionListener(listener);

   JPanel centerPanel = new JPanel();

   // 將展示消息區(qū)centerPanel添加到窗口的中間
   mainWin.add(centerPanel);
   // 讓展示消息區(qū)可以滾動(dòng)
   centerPanel.add(new JScrollPane(displayTa));
   displayTa.setEditable(false);
   // 用戶(hù)列表和是否私聊放到窗口的最右邊
   Box rightBox = new Box(BoxLayout.Y_AXIS);
   userList.setFixedCellWidth(60);
   userList.setVisibleRowCount(13);
   rightBox.add(new JLabel("用戶(hù)列表:"));
   rightBox.add(new JScrollPane(userList));

   centerPanel.add(rightBox);

   // 關(guān)閉窗口退出當(dāng)前程序
   mainWin.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   mainWin.pack(); // swing加上這句就可以擁有關(guān)閉窗口的功能
   mainWin.setVisible(true);

  } catch (Exception e) {
   // TODO: handle exception
   e.printStackTrace();
  }
 }
  //點(diǎn)擊發(fā)送后將消息發(fā)送到服務(wù)器
  protected void sendSms(String sms, Socket socket) {
   try {
    //發(fā)送聊天消息到服務(wù)端
    DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
    dataOutputStream.writeUTF(sms);
    dataOutputStream.flush(); 
     
   } catch (Exception e) {
    // TODO: handle exception
    e.printStackTrace();
   }
  }

  public DefaultListModel<String> getUserListModel() {
   return userListModel;
  }

  public JTextArea getDisplayTa() {
   return displayTa;
  }
  public JTextArea getInputTF()
  {
   return inputTF;
  }
}

// 定義線程類(lèi),用來(lái)讀取服務(wù)器發(fā)送的信息
class ThreadClient extends Thread {
 private Socket socket;
 private ClientChat clientChat;

 ThreadClient() {
 }

 ThreadClient(Socket socket, ClientChat clientChat) {
  this.socket = socket;
  this.clientChat = clientChat;
 }

 @Override
 public void run() {

  try {
   while (true) {
    DataInputStream DataInputStream = new DataInputStream(socket.getInputStream());
    String message = DataInputStream.readUTF();

    if(message.startsWith("①②③④")&&message.endsWith("①②③④"))
    {
     //說(shuō)明信息是用戶(hù)名
     String[] names = message.replace("①②③④","").split(",");
     // 將用戶(hù)列表先清空
     clientChat.getUserListModel().clear();
     for (int i = 0; i < names.length; ++i) {
      clientChat.getUserListModel().addElement(names[i]);
     }
    }
    else
    {
     //說(shuō)明是聊天信息,將聊天信息放在displayTa中
     clientChat.getInputTF().setText("");
     clientChat.getDisplayTa().append(message+"\t\n");
    }

    
   }
  } catch (IOException e) {
   // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
}

3.實(shí)驗(yàn)截圖

先開(kāi)啟服務(wù)端

再開(kāi)啟客戶(hù)端

聊天過(guò)程

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

相關(guān)文章

  • java 中String和StringBuffer與StringBuilder的區(qū)別及使用方法

    java 中String和StringBuffer與StringBuilder的區(qū)別及使用方法

    這篇文章主要介紹了java 中String和StringBuffer與StringBuilder的區(qū)別及使用方法的相關(guān)資料,在開(kāi)發(fā)過(guò)程中經(jīng)常會(huì)用到String 這個(gè)類(lèi)進(jìn)行操作,需要的朋友可以參考下
    2017-08-08
  • Spring啟動(dòng)流程refresh()源碼深入解析

    Spring啟動(dòng)流程refresh()源碼深入解析

    這篇文章主要給大家介紹了關(guān)于Spring啟動(dòng)流程refresh()源碼深入解析的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • 淺析 Java多線程

    淺析 Java多線程

    這篇文章主要介紹了Java多線程的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Java線程相關(guān)知識(shí),感興趣的朋友可以了解下
    2020-09-09
  • SpringBoot使用Micrometer實(shí)現(xiàn)度量和監(jiān)控

    SpringBoot使用Micrometer實(shí)現(xiàn)度量和監(jiān)控

    在構(gòu)建和維護(hù)現(xiàn)代應(yīng)用程序時(shí),度量和監(jiān)控是至關(guān)重要的,它們可以幫助您了解應(yīng)用程序的性能、穩(wěn)定性和可用性,本文將介紹如何在Spring Boot應(yīng)用程序中使用Micrometer進(jìn)行度量和監(jiān)控,需要的朋友可以參考下
    2023-10-10
  • Java圖像處理之RGB調(diào)色面板

    Java圖像處理之RGB調(diào)色面板

    這篇文章主要為大家詳細(xì)介紹了Java圖像處理之RGB調(diào)色面板,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • SpringBoot中開(kāi)啟GZIP壓縮的方式

    SpringBoot中開(kāi)啟GZIP壓縮的方式

    這篇文章主要介紹了SpringBoot中開(kāi)啟GZIP壓縮的方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • java實(shí)現(xiàn)網(wǎng)頁(yè)爬蟲(chóng)的示例講解

    java實(shí)現(xiàn)網(wǎng)頁(yè)爬蟲(chóng)的示例講解

    下面小編就為大家?guī)?lái)一篇java實(shí)現(xiàn)網(wǎng)頁(yè)爬蟲(chóng)的示例講解。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • Java中的定時(shí)任務(wù)調(diào)度Quartz舉例詳解

    Java中的定時(shí)任務(wù)調(diào)度Quartz舉例詳解

    這篇文章主要介紹了Java中的定時(shí)任務(wù)調(diào)度Quartz的相關(guān)資料,Quartz是Java平臺(tái)上的一個(gè)強(qiáng)大且靈活的任務(wù)調(diào)度庫(kù),廣泛應(yīng)用于企業(yè)級(jí)應(yīng)用中,本文介紹了Quartz的基本概念、核心組件、使用步驟和示例,幫助你更好地利用Quartz進(jìn)行定時(shí)任務(wù)調(diào)度,需要的朋友可以參考下
    2024-12-12
  • 簡(jiǎn)單了解Java方法的定義和使用實(shí)現(xiàn)詳解

    簡(jiǎn)單了解Java方法的定義和使用實(shí)現(xiàn)詳解

    這篇文章主要介紹了簡(jiǎn)單了解Java方法的定義和使用實(shí)現(xiàn)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Java實(shí)現(xiàn)簡(jiǎn)單圖形界面計(jì)算器

    Java實(shí)現(xiàn)簡(jiǎn)單圖形界面計(jì)算器

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡(jiǎn)單圖形界面計(jì)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04

最新評(píng)論

乐业县| 宜兰市| 金川县| 陆河县| 九江市| 五华县| 应用必备| 大化| 亳州市| 岚皋县| 濉溪县| 江门市| 偃师市| 平阴县| 邓州市| 贵溪市| 化德县| 扶余县| 新建县| 阜宁县| 麦盖提县| 琼结县| 云龙县| 耒阳市| 宜丰县| 沧源| 琼结县| 靖安县| 安新县| 玉溪市| 溆浦县| 太保市| 郓城县| 邻水| 清流县| 尼玛县| 鹤岗市| 武冈市| 城步| 陈巴尔虎旗| 延津县|