激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - Java多線程實(shí)現(xiàn)多人聊天室功能

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

2021-09-15 11:04CHANGEA-code Java教程

這篇文章主要為大家詳細(xì)介紹了Java多線程實(shí)現(xiàn)多人聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

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

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

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

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

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

ServerChar.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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ǔ)用戶的Socket以及用戶的名字   key:Socket    Value:用戶名
 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)聽客戶端套接字,若有客戶端連接,則代碼不會(huì)往下執(zhí)行,否則會(huì)堵塞在此處。
    Socket socket = serverSocket.accept();
 
    // 開啟線程,用于讀取客戶端發(fā)送的信息,并轉(zhuǎn)發(fā)給每一個(gè)客戶端
    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ā)送過來的是用戶名
     //將Socket以及用戶名字都存放在Map集合中
     ServerChat.socketsMaps.put(socket, data.replace("①②③④",""));
     //獲取所有的key(Socket),將所有用戶的名字發(fā)送至客戶端
     Set<Socket> sockets = ServerChat.socketsMaps.keySet();
     //獲取所有的用戶的名字,將這些名字拼裝成一個(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ā)送過來的是聊天信息
     //獲取所有的key(Socket),將所有用戶的名字發(fā)送至客戶端
     Set<Socket> sockets = ServerChat.socketsMaps.keySet();
     //將聊天信息廣播出去
     for(Socket soc:sockets)
     {
      DataOutputStream dataOutputStream = new DataOutputStream(soc.getOutputStream());
      dataOutputStream.writeUTF("[ "+ServerChat.socketsMaps.get(socket)+" ]說:"+data);
      dataOutputStream.flush();
     }
     
     
    }
    
   }
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
}

客戶端程序代碼:

ClientChar.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
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);
 // 在線用戶名稱展示框
 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ā)送");
 // 用戶記錄當(dāng)前聊天用戶名
 private String curUser;
 
 public static void main(String[] args) {
  new ClientChat().init();
 }
 
 private void init() {
  try {
   // 通過彈出對話框獲取用戶輸入的用戶名
   String userName = JOptionPane.showInputDialog(mainWin, "請輸入您的用戶名:");
   // 把用戶輸入的用戶名,賦給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ā)送用戶名到服務(wù)端
   dataOutputStream.writeUTF("①②③④"+userName+"①②③④");
   dataOutputStream.flush();
 
   // 開啟線程,用于讀取服務(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) {
     // 獲取用戶發(fā)送的消息
     String message = inputTF.getText();
     sendSms(message,socket);
    }
   };
   // 給發(fā)送消息按鈕綁定點(diǎn)擊事件監(jiān)聽器
   sendBn.addActionListener(listener);
 
   JPanel centerPanel = new JPanel();
 
   // 將展示消息區(qū)centerPanel添加到窗口的中間
   mainWin.add(centerPanel);
   // 讓展示消息區(qū)可以滾動(dòng)
   centerPanel.add(new JScrollPane(displayTa));
   displayTa.setEditable(false);
   // 用戶列表和是否私聊放到窗口的最右邊
   Box rightBox = new Box(BoxLayout.Y_AXIS);
   userList.setFixedCellWidth(60);
   userList.setVisibleRowCount(13);
   rightBox.add(new JLabel("用戶列表:"));
   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;
  }
}
 
// 定義線程類,用來讀取服務(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("①②③④"))
    {
     //說明信息是用戶名
     String[] names = message.replace("①②③④","").split(",");
     // 將用戶列表先清空
     clientChat.getUserListModel().clear();
     for (int i = 0; i < names.length; ++i) {
      clientChat.getUserListModel().addElement(names[i]);
     }
    }
    else
    {
     //說明是聊天信息,將聊天信息放在displayTa中
     clientChat.getInputTF().setText("");
     clientChat.getDisplayTa().append(message+"\t\n");
    }
 
    
   }
  } catch (IOException e) {
   // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
}

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

先開啟服務(wù)端

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

再開啟客戶端

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

聊天過程

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

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://blog.csdn.net/CHANGE_A1/article/details/111086171

延伸 · 閱讀

精彩推薦
  • Java教程20個(gè)非常實(shí)用的Java程序代碼片段

    20個(gè)非常實(shí)用的Java程序代碼片段

    這篇文章主要為大家分享了20個(gè)非常實(shí)用的Java程序片段,對java開發(fā)項(xiàng)目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關(guān)于小米推送Java代碼,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧...

    富貴穩(wěn)中求8032021-07-12
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經(jīng)有好久沒有升過級了。升級完畢重啟之后,突然發(fā)現(xiàn)好多錯(cuò)誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程xml與Java對象的轉(zhuǎn)換詳解

    xml與Java對象的轉(zhuǎn)換詳解

    這篇文章主要介紹了xml與Java對象的轉(zhuǎn)換詳解的相關(guān)資料,需要的朋友可以參考下...

    Java教程網(wǎng)2942020-09-17
  • Java教程Java實(shí)現(xiàn)搶紅包功能

    Java實(shí)現(xiàn)搶紅包功能

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)搶紅包功能,采用多線程模擬多人同時(shí)搶紅包,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程Java BufferWriter寫文件寫不進(jìn)去或缺失數(shù)據(jù)的解決

    Java BufferWriter寫文件寫不進(jìn)去或缺失數(shù)據(jù)的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進(jìn)去或缺失數(shù)據(jù)的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程Java8中Stream使用的一個(gè)注意事項(xiàng)

    Java8中Stream使用的一個(gè)注意事項(xiàng)

    最近在工作中發(fā)現(xiàn)了對于集合操作轉(zhuǎn)換的神器,java8新特性 stream,但在使用中遇到了一個(gè)非常重要的注意點(diǎn),所以這篇文章主要給大家介紹了關(guān)于Java8中S...

    阿杜7472021-02-04
主站蜘蛛池模板: 免费a级作爱片免费观看欧洲 | 中文字幕 亚洲一区 | 国产羞羞视频免费在线观看 | 久草在线视频首页 | 久久久人成影片一区二区三区 | av在线免费不卡 | 自偷自偷久产久精九国品在线 | 成人区一区二区三区 | 久久免费视频一区二区三区 | 欧美视频在线一区二区三区 | 九色激情网 | 操嫩草 | 欧美日韩精品一区二区三区在线观看 | 国产精品视频一区二区噜噜 | 黑色丝袜美美女被躁视频 | 欧美精品一区二区久久久 | 中文字幕免费播放 | 午夜视频中文字幕 | 欧美黄色大片免费观看 | 黄色毛片免费视频 | 一区二区三区四区免费 | 黄色网址电影 | 黄色片在线播放 | 射逼网站| 在线播放免费视频 | 国产精品剧情一区二区三区 | 久久99久久98精品免观看软件 | 精品国产99久久久久久宅男i | 欧美性激情视频 | av电影在线免费观看 | 日本一区二区在线 | 欧美国产一级片 | 久久久久久久久久久久久久av | 亚洲最新无码中文字幕久久 | 久久久久北条麻妃免费看 | 91精品国产一区二区三区动漫 | 中文字幕在线免费播放 | 91在线视频免费观看 | 国产精品美女一区二区 | 99riav国产在线观看 | 精品一区二区三区在线视频 |