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", "小黑");
 }
}

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

时间: 2016-07-14

Java基于socket实现简易聊天室实例

本文实例讲述了Java基于socket实现简易聊天室的方法.分享给大家供大家参考.具体实现方法如下: chatroomdemo.java package com.socket.demo; import java.io.IOException; import java.net.DatagramSocket; public class ChatRoomDemo { /** * @param args * @throws IOException */ public static void main(S

Java continue break制作简单聊天室程序

Java continue break 制作简单聊天室程序,屏蔽不文明语言,显示每句话聊天时间 package com.swift; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Scanner; public class ChatWithBreakContinue { public static void main(String[] args) { Scanner scan = new Sc

基于Tomcat7、Java、WebSocket的服务器推送聊天室实例

前言 HTML5 WebSocket实现了服务器与浏览器的双向通讯,双向通讯使服务器消息推送开发更加简单,最常见的就是即时通讯和对信息实时性要求比较高的应用.以前的服务器消息推送大部分采用的都是"轮询"和"长连接"技术,这两中技术都会对服务器产生相当大的开销,而且实时性不是特别高.WebSocket技术对只会产生很小的开销,并且实时性特别高.下面就开始讲解如何利用WebSocket技术开发聊天室.在这个实例中,采用的是Tomcat7服务器,每个服务器对于WebSoc

基于java编写局域网多人聊天室

由于需要制作网络计算机网络课程设计,并且不想搞网络布线或者局域网路由器配置等等这种完全搞不懂的东西,最后决定使用socket基于java编写一个局域网聊天室: 关于socket以及网络编程的相关知识详见我另一篇文章:Java基于socket编程 程序基于C/S结构,即客户端服务器模式. 服务器: 默认ip为本机ip 需要双方确定一个端口号 可设置最大连接人数 可启动与关闭 界面显示在线用户人以及姓名(本机不在此显示) 客户端: 需要手动设置服务器ip地址(局域网) 手动设置端口号 输入姓名 可连

使用Java和WebSocket实现网页聊天室实例代码

在没介绍正文之前,先给大家介绍下websocket的背景和原理: 背景 在浏览器中通过http仅能实现单向的通信,comet可以一定程度上模拟双向通信,但效率较低,并需要服务器有较好的支持; flash中的socket和xmlsocket可以实现真正的双向通信,通过 flex ajax bridge,可以在javascript中使用这两项功能. 可以预见,如果websocket一旦在浏览器中得到实现,将会替代上面两项技术,得到广泛的使用.面对这种状况,HTML5定义了WebSocket协议,能更

Java Socket聊天室编程(二)之利用socket实现单聊聊天室

在上篇文章Java Socket聊天室编程(一)之利用socket实现聊天之消息推送中我们讲到如何使用socket让服务器和客户端之间传递消息,达到推送消息的目的,接下来我将写出如何让服务器建立客户端与客户端之间的通讯. 其实就是建立一个一对一的聊天通讯. 与上一篇实现消息推送的代码有些不同,在它上面加以修改的. 如果没有提到的方法或者类则和上一篇一模一样. 1,修改实体类(服务器端和客户端的实体类是一样的) 1,UserInfoBean 用户信息表 public class UserInfoB

用java WebSocket做一个聊天室

最近一个项目中,需要用到Java的websocket新特性,于是就学了一下,感觉这技术还挺好玩的,瞬间知道网页上面的那些在线客服是怎么做的了. 先看图: 实现了多客户机进行实时通讯. 下面看代码项目结构图:很简单,就1个类,1个页面 然后看具体代码 先看后端代码 package com.main; import java.io.IOException; import java.util.concurrent.CopyOnWriteArraySet; import javax.websocket.

使用java基于pushlet和bootstrap实现的简单聊天室

这是一个简单的不能再简单的聊天室,本代码包含以下功能 1.用户注册. 2.用户登录. 3.当然还可以聊天. DBUtil.java 复制代码 代码如下: package com.hongyuan.core;   import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statemen

java实现一个简单TCPSocket聊天室功能分享

本文实例为大家分享了java实现TCPSocket聊天室功能的相关代码,供大家参考,具体内容如下 1.TCPserver.java import java.net.*; import java.io.*; import java.util.*; import java.util.concurrent.*; public class TCPserver{ private static final int SERVERPORT = 8888; private ServerSocket MyServe

Java Socket聊天室编程(一)之利用socket实现聊天之消息推送

相关阅读:Java Socket聊天室编程(二)之利用socket实现单聊聊天室 网上已经有很多利用socket实现聊天的例子了,但是我看过很多,多多少有一些问题存在. 这里我将实现一个比较完整的聊天例子,并解释其中的逻辑. 由于socket这一块比较大,所以我将分出几篇来写一个比较完整的socket例子. 这里我们先来实现一个最简单的,服务器与客户端通讯,实现消息推送的功能. 目的:服务器与客户端建立连接,客户端可以向服务器发送消息,服务器可以向客户端推送消息. 1,使用java建立socke

java WebSocket实现聊天消息推送功能

本文实例为大家分享了java WebSocket实现聊天消息推送功能的具体代码,供大家参考,具体内容如下 环境: JDK.1.7.0_51 apache-tomcat-7.0.53 java jar包:tomcat-coyote.jar.tomcat-juli.jar.websocket-api.jar ChatAnnotation消息发送类: import java.io.IOException; import java.util.HashMap; import java.util.Map;

Android中使用socket通信实现消息推送的方法详解

原理 最近用socket写了一个消息推送的demo,在这里和大家分享一下. 主要实现了:一台手机向另外一台手机发送消息,这两台手机可以随时自由发送文本消息进行通信,类似我们常用的QQ. 效果图: 原理:手机通过socket发送消息到服务器,服务器每接收到一条消息之后,都会把这条消息放进一个messageList里面,服务器会不停地检测messageList是否含有消息,如果有的话就会根据messageList里面item的数据,推送到相应的另一端手机上面. 下面简单画了一个图来说明这个原理: 演

Django Channels 实现点对点实时聊天和消息推送功能

简介在很多实际的项目开发中,我们需要实现很多实时功能:而在这篇文章中,我们就利用django channels简单地实现了点对点聊天和消息推送功能. 手边有一个项目需要用到后台消息推送和用户之间一对一在线聊天的功能.例如用户A评论了用户B的帖子,这时候用户B就应该收到一条通知,显示自己的帖子被评论了.这个功能可以由最基本的刷新页面后访问数据库来完成,但是这样会增加对后台服务器的压力,同时如果是手机客户端的话,也会造成流量的损失.于是,我们考虑使用websocket建立一个连接来完成这个功能. 但

Java中websocket消息推送的实现代码

一.服务层 package com.demo.websocket; import java.io.IOException; import java.util.Iterator; import java.util.concurrent.ConcurrentLinkedQueue; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.springframew

node.js中TCP Socket多进程间的消息推送示例详解

前言 前段时间接到了一个支付中转服务的需求,即支付数据通过http接口传到中转服务器,中转服务器将支付数据发送到异构后台(Lua)的指定tcp socket. 一开始评估的时候感觉蛮简单的,就是http server和tcp server间的通信,不是一个Event实例就能解决的状态管理问题吗?注册一个事件A用于消息传递,在socket连接时注册唯一的ID,然后在http接收到数据时,emit事件A:在监听到事件A时,在tcp server中寻找指定ID对应的socket处理该数据即可. 尽管n

java实现钉钉机器人消息推送的示例代码

先建个钉钉群,并加好机器人 此时,机器人已经添加完毕,接下来编写我们连接机器人小哥的代码 import com.alibaba.fastjson.JSON; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import java.util.List; import java.util.Map; /** * @author yanghao * @version DingTalkTest.j

Android中利用App实现消息推送机制的代码

1.消息推送机制 服务器器端需要变被动为主动,通知客户一些开发商认为重要的信息,无论应用程序是否正在运行或者关闭. 我想到了一句话:don't call me,i will call you! qq今天在右下角弹出了一个对话框:"奥巴马宣布本拉登挂了...",正是如此. 自作聪明,就会带点小聪明,有人喜欢就有人讨厌. 2.独立进程 无论程序是否正在运行,我们都要能通知到客户,我们需要一个独立进程的后台服务. 我们需要一个独立进程的后台服务. 在androidmanifest.xml中注

Python编程实现微信企业号文本消息推送功能示例

本文实例讲述了Python微信企业号文本消息推送功能.分享给大家供大家参考,具体如下: 企业号的创建.企业号应用的创建.组.tag.part就不赘述了,一搜一大堆,但是网上拿的那些个脚本好多都不好使,所以自己修了一个 坦率的讲,这个脚本是用来作为zabbix的通知媒介脚本的,本人是个菜鸟,如果哪里不对,大神们不要笑话,python也处于学习阶段,如果有哪些地方不合理,很希望可以不吝赐教,废话不多说,脚本奉上: #!/usr/bin/python # _*_coding:utf-8 _*_ imp