这里有新鲜出炉的Java设计模式,程序狗速度看过来!
java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台(即JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称。
这篇文章主要为大家详细介绍了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.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、客户端程序,依然很简单:
•简单的定义客户端聊天室界面。
•构造消息发送套接字对象。
•获取聊天信息框的内容,发送到服务器。
- 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", "小黑");
- }
- }
来源: http://www.phperz.com/article/17/1123/360384.html