服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服务器之家 - 编程语言 - JAVA教程 - Java基于UDP协议实现简单的聊天室程序

Java基于UDP协议实现简单的聊天室程序

2020-05-29 14:16ghost_Programmer JAVA教程

这篇文章主要为大家详细介绍了Java基于UDP协议实现简单的聊天室程序的相关资料,感兴趣的小伙伴们可以参考一下

最近比较闲,一直在抽空回顾一些Java方面的技术应用。
今天没什么事做,基于UDP协议,写了一个非常简单的聊天室程序。
现在的工作,很少用到socket,也算是对Java网络编程方面的一个简单回忆。 

先看一下效果:

Java基于UDP协议实现简单的聊天室程序

实现的效果可以说是非常非常简单,但还是可以简单的看到一个实现原理。
 “聊天室001”的用户,小红和小绿相互聊了两句,“聊天室002”的小黑无人理会,在一旁寂寞着。 

看一下代码实现: 

1、首先是消息服务器的实现,功能很简单:
•将客户端的信息(进入了哪一个聊天室等)进行登记; 
•构造UDP协议套接字对象,接受各个客户端发送的消息;
•解析消息内容,将聊天信息推送回对应聊天室的各个客户端;

?
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
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.google.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、客户端程序,依然很简单:

•简单的定义客户端聊天室界面。
•构造消息发送套接字对象。
•获取聊天信息框的内容,发送到服务器。

?
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
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格式解析。

?
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
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”。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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", "小黑");
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

延伸 · 阅读

精彩推荐
  • JAVA教程java观感示例分享

    java观感示例分享

    这篇文章主要介绍了java观感示例,该实例查询并生成了系统中存在观感对应的按钮并在用户点击相应按钮时将窗口的观感切换到指定的观感上 ...

    java技术网1282019-11-12
  • JAVA教程java中数组list map三者之间的互转介绍

    java中数组list map三者之间的互转介绍

    java中 数组 list map之间的互转一张图清晰呈现并附有代码,不懂的朋友可以参考下 ...

    java教程网4332019-10-17
  • JAVA教程linux下执行java程序的sh脚本分享

    linux下执行java程序的sh脚本分享

    这篇文章主要介绍了linux下执行java程序的sh脚本,仅供参考,但是设置的时候环境变量是最重要的,我就是环境变量一直不对,总是按网上查到的来,不明...

    hebedich1402019-11-29
  • JAVA教程java制作复制文件工具代码分享

    java制作复制文件工具代码分享

    如果目标位置没有同名文件,则直接拷贝过去;如果目标位置已有同名文件,则比对文件的最后修改日期,来进行覆盖或者忽略。程序会在可以在复制过程...

    java技术网1252019-11-04
  • JAVA教程Java操作Mysql的方法

    Java操作Mysql的方法

    这篇文章主要介绍了Java操作Mysql的方法,实例分析了Java针对有返回结果和没有返回结果的sql操作的相关技巧,需要的朋友可以参考下 ...

    yongh7013182019-12-09
  • JAVA教程Java开发人员需知的十大戒律

    Java开发人员需知的十大戒律

    这篇文章主要介绍了Java开发人员需知的十大戒律,较为详细的总结分析了Java开发中常见的注意事项与编程技巧,需要的朋友可以参考下 ...

    jerry1432020-01-12
  • JAVA教程使用Rhino让java执行javascript的方法实例

    使用Rhino让java执行javascript的方法实例

    这篇文章主要介绍了java使用Rhino执行javascript的方法,Rhino由Mozilla开发,是 JavaScript 一种基于Java的实现 ...

    java教程网5102019-10-23
  • JAVA教程Java操作MongoDB模糊查询和分页查询

    Java操作MongoDB模糊查询和分页查询

    这篇文章主要介绍了Java操作MongoDB模糊查询和分页查询的相关资料,需要的朋友可以参考下 ...

    java教程网2602020-04-22