Java基於UDP協定完成簡略的聊天室法式。本站提示廣大學習愛好者:(Java基於UDP協定完成簡略的聊天室法式)文章只能為提供參考,不一定能成為您想要的結果。以下是Java基於UDP協定完成簡略的聊天室法式正文
比來比擬閒,一向在抽閒回想一些Java方面的技巧運用。
明天沒甚麼事做,基於UDP協定,寫了一個異常簡略的聊天室法式。
如今的任務,很罕用到socket,也算是對Java收集編程方面的一個簡略回想。
先看一下後果:
完成的後果可以說長短常異常簡略,但照樣可以簡略的看到一個完成道理。
“聊天室001”的用戶,小紅和小綠互相聊了兩句,“聊天室002”的小黑無人理睬,在一旁孤單著。
看一下代碼完成:
1、起首是新聞辦事器的完成,功效很簡略:
•將客戶真個信息(進入了哪個聊天室等)停止掛號;
•結構UDP協定套接字對象,接收各個客戶端發送的新聞;
•解析新聞內容,將聊天信息推送回對應聊天室的各個客戶端;
package com.tsr.simplechat.receive_server;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.HashMap;
import com.谷歌.gson.Gson;
import com.tsr.simplechat.bean.MessageEntity;
import com.tsr.simplechat.client.ChatClient;
//聊天辦事器
public class ChatServer extends Thread {
// 法式占用端標語
private static final int PORT = 10000;
// 新聞接收套接字對象
private static DatagramSocket server = null;
// 字典對象(Key:聊天室ID,Value:該聊天室下的客戶端用戶聚集);
private static HashMap<String, ArrayList<ChatClient>> groups = new HashMap<String, ArrayList<ChatClient>>();
// 結構器
public ChatServer() {
try {
// 新聞接收套接字對象的結構初始化
server = new DatagramSocket(PORT);
} catch (SocketException e) {
e.printStackTrace();
}
}
// 注冊聊天室新登錄用戶
public static void logInGroup(String groupID, ChatClient client) {
// 經由過程聊天室ID,獲得該聊天室的一切在線用戶
ArrayList<ChatClient> clients = groups.get(groupID);
if (clients == null) {
clients = new ArrayList<ChatClient>();
}
// 將此次進入聊天室的用戶掛號
clients.add(client);
// 更新聊天室信息
groups.put(groupID, clients);
}
// 輪回吸收新聞
@Override
public void run() {
while (true) {
receiveMessage();
}
}
private void receiveMessage() {
// UDP數據包
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
while (true) {
try {
// 接收數據包
server.receive(packet);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 解析數據包,獲得聊天信息
String content = new String(packet.getData(), 0, packet.getLength());
// 經由過程第三方包解析json數據
Gson gson = new Gson();
MessageEntity me = gson.fromJson(content, MessageEntity.class);
// 解析新聞內容,經由過程聊天室ID,獲得該聊天室的一切在線用戶
ArrayList<ChatClient> clients = groups.get(me.getGroupId());
// 將吸收到的新聞推送回該聊天室的各個用戶
for (ChatClient client : clients) {
client.pushBackMessage(me);
}
}
}
}
2、客戶端法式,仍然很簡略:
•簡略的界說客戶端聊天室界面。
•結構新聞發送套接字對象。
•獲得聊天信息框的內容,發送到辦事器。
package com.tsr.simplechat.client;
import java.awt.Button;
import java.awt.Event;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import com.tsr.simplechat.bean.MessageEntity;
import com.tsr.simplechat.receive_server.ChatServer;
//客戶端法式
public class ChatClient extends Frame {
private static final long serialVersionUID = 1L;
// 聊天室ID
private String groupID;
// 客戶端用戶名
private String clientName;
// 客戶端新聞發送辦事套接字
private DatagramSocket msg_send;
// 辦事端口
private final int PORT = 10000;
// 辦事器IP地址
private InetAddress ip;
// 客戶端控件
TextField tf = new TextField(20);
TextArea ta = new TextArea();
Button send = new Button("send");
// 客戶端結構器
public ChatClient(String groupID, String clientName) {
super("聊天室:" + groupID + "/" + clientName);
this.clientName = clientName;
this.groupID = groupID;
// 設置客戶端界面款式
add("North", tf);
add("Center", ta);
add("South", send);
setSize(250, 250);
show();
// 聊天相干辦事器初始化
init();
// 監督器
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
// 封閉新聞發送辦事
msg_send.close();
// 封閉客戶端法式
dispose();
System.exit(0);
}
});
}
// 聊天相干辦事器初始化
private void init() {
// 注冊以後用戶及地點聊天室信息注冊到辦事器
ChatServer.logInGroup(groupID, this);
try {
// 初始化新聞發送套接字對象
msg_send = new DatagramSocket();
// 指定新聞辦事器
try {
ip = InetAddress.getByName("127.0.0.1");
} catch (UnknownHostException e) {
System.out.println("未知的主機異常..");
}
} catch (SocketException e) {
System.out.println("套接字銜接異常..");
}
}
// 新聞發送按鈕時光監聽
public boolean action(Event evt, Object arg) {
if (evt.target.equals(send)) {
try {
// 獲得輸出內容
String content = tf.getText();
// 發送新聞
send_message(content);
// 清空聊天框
tf.setText(null);
} catch (Exception ioe) {
System.out.print(ioe.getMessage());
}
}
return true;
}
// 新聞發送
private void send_message(String content) {
// 新聞格局化(json格局)
String message = messageFormat(content);
// 將新聞封裝成UDP數據包
byte[] buf = message.getBytes();
DatagramPacket packet = new DatagramPacket(buf, buf.length, ip, PORT);
try {
// 經由過程UDP協定發送新聞
msg_send.send(packet);
} catch (IOException e) {
System.out.println("IO異常..");
}
}
// 新聞格局化
private String messageFormat(String content) {
StringBuffer buffer = new StringBuffer();
buffer.append("{\"groupId\":").append("\"").append(groupID).append(
"\",");
buffer.append("\"userName\":\"").append(clientName).append("\",");
buffer.append("\"text\":\"").append(content).append("\"}");
return buffer.toString();
}
// 從辦事器獲得以後聊天室最新新聞(回調..)
public void pushBackMessage(MessageEntity me) {
ta.append(me.getUserName() + ":" + me.getText());
ta.append("\n");
}
}
3、新聞實體類
重要就是用於將新聞封裝成對象,包括:聊天室ID、新聞發送者昵稱,新聞內容。應用json格局解析。
package com.tsr.simplechat.bean;
//新聞實體
public class MessageEntity {
private String groupId;
private String userName;
private String text;
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
4、OK,到了這裡就根本弄定了,樹立一個測試類。
•開啟新聞辦事器。
•開啟三個客戶端,個中兩個進入“聊天室001”,另外一個進入“聊天室002”。
import com.tsr.simplechat.client.ChatClient;
import com.tsr.simplechat.receive_server.ChatServer;
public class Test {
public static void main(String[] args) {
ChatServer r = new ChatServer();
r.start();
ChatClient c1 = new ChatClient("001", "小紅");
ChatClient c2 = new ChatClient("001", "小綠");
ChatClient c3 = new ChatClient("002", "小黑");
}
}
以上就是本文的全體內容,願望對年夜家的進修有所贊助,也願望年夜家多多支撐。