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

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

先看一下效果:

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

实现的效果可以说是非常非常简单,但还是可以简单的看到一个实现原理。
 “聊天室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聊天室编程(一)之利用socket实现聊天之消息推送

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

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基于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 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

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

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

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

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

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

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

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 WebSocket做一个聊天室

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

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

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

Java编程利用socket多线程访问服务器文件代码示例

这篇文章将向大家展示Java编程利用socket多线程访问服务器文件代码示例,如果您想先了解Java多线程socket编程的基础知识,可以看下这篇文章:Java多线程编程实现socket通信示例代码. 接下来进入正文,我们看看利用socket多线程访问服务器代码: ServerMain.java package com.ysk.webServer; import java.io.File; import java.io.IOException; import java.net.ServerSoc

基于Nodejs利用socket.io实现多人聊天室

socket.io简介 在Html5中存在着这样的一个新特性,引入了websocket,关于websocket的内部实现原理可以看这篇文章,这篇文章讲述了websocket无到有,根据协议,分析数据帧的头,进行构建websocket.虽然代码短,但可以很好地体现websocket的原理. ,这个特性提供了浏览器端和服务器端的基于TCP连接的双向通道.但是并不是所有的浏览器都支持websocket特性,故为了磨平浏览器间的差异,为开发者提供统一的接口,引入了socket.io模块.在不支持webs

android socket聊天室功能实现

前提概要 笔者很久之前其实就已经学习过了socket,当然也是用socket做过了聊天室,但是觉得此知识点比较一般,并无特别难的技术点,于是也并未深究. 然而近期一个项目中对socket的使用却让笔者感觉socket强大无比,可以实现诸多功能. 个人Socket体验 项目主要有关智能家居,需要实现多台手机同时对灯进行操作(开或者关),主要需要实现以下几点: 1.进入界面时获取所有灯的状态. 2.一台手机改变了灯的状态,其他的手机上可以有所显示. 3.硬件上改变了灯的状态(手动开关灯),所有手机上

Java基于Socket实现网络编程实例详解

一,网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输. 在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可以唯一地确定Internet上的一台主机. 而TCP层则提供面向应用的可靠(tcp)的或非可靠(UDP)的数据传输机制,这是网络编程的主要对象,一般不需要关心IP层是如何处理数据的. 目前较为流行的网络编程模型是客户机/服务器(C/S)结构.即通信双方一方作为服务器等待客户提出请求并予以响应.客户则

详解基于java的Socket聊天程序——服务端(附demo)

写在前面: 昨天在博客记录自己抽空写的一个Socket聊天程序的初始设计,那是这个程序的整体设计,为了完整性,今天把服务端的设计细化记录一下,首页贴出Socket聊天程序的服务端大体设计图,如下图: 功能说明: 服务端主要有两个操作,一是阻塞接收客户端的socket并做响应处理,二是检测客户端的心跳,如果客户端一段时间内没有发送心跳则移除该客户端,由Server创建ServerSocket,然后启动两个线程池去处理这两件事(newFixedThreadPool,newScheduledThrea

详解基于java的Socket聊天程序——客户端(附demo)

写在前面: 上周末抽点时间把自己写的一个简单Socket聊天程序的初始设计和服务端细化设计记录了一下,周二终于等来毕业前考的软考证书,然后接下来就是在加班的日子度过了,今天正好周五,打算把客户端的详细设计和Common模块记录一下,因为这个周末开始就要去忙其他东西了. 设计: 客户端设计主要分成两个部分,分别是socket通讯模块设计和UI相关设计. 客户端socket通讯设计: 这里的设计其实跟服务端的设计差不多,不同的是服务端是接收心跳包,而客户端是发送心跳包,由于客户端只与一个服务端进行通

Android 基于Socket的聊天应用实例(二)

前言 很久没写BLOG了,之前在写Android聊天室的时候答应过要写一个客户(好友)之间的聊天demo,Android 基于Socket的聊天室已经实现了通过Socket广播形式的通信功能. 以下是我写的一个类似现在多数聊天软件的冒泡聊天APP.全部功能都是自己的想法,对于现在市面上成功的例子是怎么实现的,我还不了解.所以读者可只做参考学习,也可以分享您的案例给我. 功能 一对一聊天,非聊天室 好友列表 好友在线,离线状态(实时更新) 冒泡实时聊天窗口 发送离线信息 基本原理 之前的聊天室原理

Java的Socket通讯基础编程完全指南

什么是Socket 网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket.Socket通常用来实现客户方和服务方的连接.Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定. 但是,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的.在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程. Socket通讯的过程 Server端Listen(监听)某个端口