场景很简单,就是多个客户端通过udp,连接到服务器(其实是无连接的,就是服务器保存了客户端的ip信息)。然后通过udp协议先服务器发送消息,然后服务器在通过udp转发在各个客服端。

这个是不是 观察者模式

server代码

public class Server {
private static LinkedList<SocketAddress> list=new LinkedList<SocketAddress>();
private static final ExecutorService executorService = Executors.newFixedThreadPool(4);//这里用多线程去转发,可以提高效率。emmm,udp没有3次握手,速度应该很快,多不多线程应该差不了太多
private static DatagramChannel server=null;
private static Selector selector=null;
static {
try{
server=DatagramChannel.open().bind(new InetSocketAddress(8889));
server.configureBlocking(false);
selector=Selector.open(); }catch (Exception e){
e.printStackTrace();
}
}
public static void main(String[] args)throws Exception { server.register(selector, SelectionKey.OP_READ);
while (true){
if (selector.select()>0){
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> iterator = keys.iterator();
while (iterator.hasNext()){
SelectionKey selectionKey = iterator.next();
if (selectionKey.isReadable()){
String msg = readMsg(selectionKey);
broadcast(msg);
}
iterator.remove();
}}
}
}
public static void saveIP(SocketAddress address)throws Exception{
if (!list.contains(address)){
list.add(address);
System.out.println("新增ip:"+address);
}
System.out.println("当前udp 保存的ip数量:"+list.size());
}
public static void broadcast(String msg) throws Exception{ //DatagramPacket packet=new DatagramPacket(msg.getBytes(),0,msg.getBytes().length);
for (SocketAddress address:list
) {
ByteBuffer byteBuffer=ByteBuffer.wrap(msg.getBytes());
executorService.submit(new Runnable() {
@Override
public void run() {
try{
server.send(byteBuffer, address);
System.out.println(Thread.currentThread().getName()+":"+address+"发送成功");
}catch (Exception e){
System.out.println(Thread.currentThread().getName()+":"+address+"发送失败");
}
}
});
}
}
public static String readMsg(SelectionKey selectionKey)throws Exception{
DatagramChannel channel=(DatagramChannel)selectionKey.channel();
System.out.println(channel.getRemoteAddress()+":"+channel.getLocalAddress());
ByteBuffer byteBuffer=ByteBuffer.allocate(1024);
SocketAddress receive = channel.receive(byteBuffer);
saveIP(receive);
byteBuffer.flip();
String msg=new String(byteBuffer.array(),"utf-8");
System.out.println("收到消息:"+msg);
return msg;
}
}

client 代码

public class Client {
public static DatagramSocket socket=null;
public static void main(String[] args) throws Exception{
try {
socket=new DatagramSocket();
Scanner scanner=new Scanner(System.in);
String msg;
new Thread(()->{
try{
while (true){
byte[] arr=new byte[1024];
DatagramPacket packet=new DatagramPacket(arr,arr.length);
socket.receive(packet);
String m1=new String(packet.getData(),"utf-8");
System.out.println("受到服务器消息:"+m1);
}
}catch (Exception e){
e.printStackTrace();
}
}).start();
while (!(msg=scanner.nextLine()).equals("exit")){
DatagramPacket packet=new DatagramPacket(msg.getBytes(),msg.getBytes().length,new InetSocketAddress("127.0.0.1",8889));
socket.send(packet);
}
}finally {
socket.close();
}
}
}

JAVA NIO udp 实现 群转发的更多相关文章

  1. Java NIO UDP DEMO

    今天有人问我Netty的UDP怎么使用,我自己尝试的去写一个Demo,在网上搜索了一下,关于Netty的UDP实现还是很少的,所以,今天写下这篇文章用来记录今天的一个简单Demo实现 不使用Netty ...

  2. JAVA NIO异步通信框架MINA选型和使用的几个细节(概述入门,UDP, 心跳)

    Apache MINA 2 是一个开发高性能和高可伸缩性网络应用程序的网络应用框架.它提供了一个抽象的事件驱动的异步 API,可以使用 TCP/IP.UDP/IP.串口和虚拟机内部的管道等传输方式.A ...

  3. 使用JAVA NIO实现的UDP client和server

    //////////////////////////////////////////////////////////////////////////////////////////////////// ...

  4. 一文让你彻底理解 Java NIO 核心组件

    背景知识 同步.异步.阻塞.非阻塞 首先,这几个概念非常容易搞混淆,但NIO中又有涉及,所以总结一下. 同步:API调用返回时调用者就知道操作的结果如何了(实际读取/写入了多少字节). 异步:相对于同 ...

  5. Java NIO 之 Channel(通道)

    历史回顾: Java NIO 概览 Java NIO 之 Buffer(缓冲区) 其他高赞文章: 面试中关于Redis的问题看这篇就够了 一文轻松搞懂redis集群原理及搭建与使用 一 Channel ...

  6. Channel (Java NIO)

    [正文]netty源码死磕1.3:  Java NIO Channel 1. Java NIO Channel 1.1. Java NIO Channel的特点 和老的OIO相比,通道和NIO流(非阻 ...

  7. 5. 彤哥说netty系列之Java NIO核心组件之Channel

    你好,我是彤哥,本篇是netty系列的第五篇. 简介 上一章我们一起学习了如何使用Java原生NIO实现群聊系统,这章我们一起来看看Java NIO的核心组件之一--Channel. 思维转变 首先, ...

  8. Java NIO的理解和应用

    Java NIO是一种基于通道和缓冲区的I/O方式,已经被广泛的应用,成为解决高并发与大量连接和I/O处理问题的有效方式. Java NIO相关组件 Java NIO主要有三个核心部分组成,分别是:C ...

  9. JAVA NIO学习笔记1 - 架构简介

    最近项目中遇到不少NIO相关知识,之前对这块接触得较少,算是我的一个盲区,打算花点时间学习,简单做一点个人学习总结. 简介 NIO(New IO)是JDK1.4以后推出的全新IO API,相比传统IO ...

随机推荐

  1. 基于djiango实现简易版的图书管理系统

    介绍: 本程序仅仅实现图书数据的增删查 树形结构如下   全部代码如下: url: from django.urls import path from front import views as fr ...

  2. JS的运动1(从简单到复杂运动,从单一属性到多属性同时进行的运动过程分析)

    js运动原理 运动基础 在js中,让一个元素动起来的最简单的方式,就是点击按钮,让元素移动.下面是一个简单的案例:(下面几个案例的的html和css都是采用这个为例) <!DOCTYPE htm ...

  3. 配置文件my.cnf---配置信息注释大全

    在进行MySQL与CM+CHD之间的应用配置时,发现此前对于MySQL的配置含义过于模糊,所以将CM+CHD集群所涉及MySQL方面的配置含义进行抽取并加以注释,方便此后的配置和使用. 一.客户端设置 ...

  4. 读《深入理解Elasticsearch》点滴-查询分类

    1.如何分类,略.个人不接受书中的分类方法,建议采用官网上的分类方法 2.term查询,可以模拟No-SQL数据库

  5. 004-python面向对象,错误,调试和测试

    ---恢复内容开始--- 1.面向对象 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作 ...

  6. CentOS7下mongodb忘记密码后重置密码

    新装mongodb后,结果一段时间没有用,密码给忘记了,只能重置密码了. 步骤如下: 1.找到mongodb的配置文件 通过ps -ef|grep mongod找到mongodb的配置文件mongod ...

  7. MapReduce案例-好友推荐

    用过各种社交平台(如QQ.微博.朋友网等等)的小伙伴应该都知道有一个叫 "可能认识" 或者 "好友推荐" 的功能(如下图).它的算法主要是根据你们之间的共同好友 ...

  8. Linux下的软件管理

    一.软件包管理简介     1源码包(脚本安装)        ①.特点: a.开源 ,可以修改                        b.自由选择所需功能                   ...

  9. slf4j输出变量

    花括号表示占位符,推荐使用

  10. javascript DOM节点

    获得子节点方式: 1.将文本内容也当成节点 childNodes firstChild lastChild 2.获得标签为内容的节点 children firstElementChild lastEl ...