package org.springblade.system.nettyUdpServer.server;
|
|
import io.netty.bootstrap.Bootstrap;
|
import io.netty.channel.*;
|
import io.netty.channel.nio.NioEventLoopGroup;
|
import io.netty.channel.socket.nio.NioDatagramChannel;
|
import io.netty.handler.codec.json.JsonObjectDecoder;
|
import io.netty.handler.codec.string.StringDecoder;
|
import io.netty.handler.codec.string.StringEncoder;
|
import io.netty.util.concurrent.DefaultEventExecutorGroup;
|
import io.netty.util.concurrent.EventExecutorGroup;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springblade.system.nettyUdpServer.handle.UdpServerHandler;
|
|
import java.net.InetAddress;
|
import java.util.concurrent.Executors;
|
|
/**
|
* updServer udp服务端
|
*/
|
public class UdpServer {
|
private static Logger LOG = LoggerFactory.getLogger(UdpServer.class);
|
|
public int port;
|
|
private Channel channel;
|
|
public UdpServer(int port) {
|
this.port = port;
|
run();
|
}
|
|
/**
|
* 不用
|
*/
|
public void init() {
|
final NioEventLoopGroup group = new NioEventLoopGroup();
|
try {
|
Bootstrap b = new Bootstrap();
|
b.group(group).channel(NioDatagramChannel.class)
|
.option(ChannelOption.SO_BROADCAST, true)
|
.handler(new ChannelInitializer<NioDatagramChannel>() {
|
@Override
|
public void initChannel(NioDatagramChannel ch) throws Exception {
|
ChannelPipeline p = ch.pipeline();
|
p.addLast("decoder", new JsonObjectDecoder());
|
p.addLast(new UdpServerHandler());
|
}
|
});
|
InetAddress address = InetAddress.getLocalHost();
|
channel = b.bind(address, port).sync().channel();
|
Executors.newSingleThreadExecutor().execute(new Runnable() {
|
@Override
|
public void run() {
|
try {
|
channel.closeFuture().sync();
|
} catch (InterruptedException e) {
|
e.printStackTrace();
|
} finally {
|
group.shutdownGracefully();
|
}
|
}
|
});
|
LOG.info("UDP服务器启动, host:{},port:{}", address.getHostAddress(), port);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
|
|
//给管道抽象出接口,给Channel更多的能力和配置,例如Channel的状态,参数,IO操作
|
//使用ChannelPipeline实现自定义IO
|
//Channel channel;
|
public void run() {
|
Thread thread = new Thread(new Runnable() {
|
@Override
|
public void run() {
|
//InetSocketAddress socketAddress = new InetSocketAddress("s16s652780.51mypc.cn", 21403);
|
//启动服务
|
EventLoopGroup workerGroup = new NioEventLoopGroup();
|
//优化使用的线程
|
final EventExecutorGroup group = new DefaultEventExecutorGroup(16);
|
|
try {
|
Bootstrap b = new Bootstrap();//udp不能使用ServerBootstrap
|
b.group(workerGroup).channel(NioDatagramChannel.class)//设置UDP通道
|
//设置udp的管道工厂
|
.handler(new ChannelInitializer<NioDatagramChannel>() {
|
//NioDatagramChannel标志着是UDP格式的
|
@Override
|
protected void initChannel(NioDatagramChannel ch)
|
throws Exception {
|
// TODO Auto-generated method stub
|
//创建一个执行Handler的容器
|
ChannelPipeline pipeline = ch.pipeline();
|
pipeline.addLast(new StringDecoder());
|
pipeline.addLast(new StringEncoder());
|
//执行具体的处理器
|
pipeline.addLast(group, "handler", new UdpServerHandler());//消息处理器
|
}
|
|
})//初始化处理器
|
//true / false 多播模式(UDP适用),可以向多个主机发送消息
|
.option(ChannelOption.SO_BROADCAST, true)// 支持广播
|
.option(ChannelOption.SO_RCVBUF, 2048 * 1024)// 设置UDP读缓冲区为2M
|
.option(ChannelOption.SO_SNDBUF, 1024 * 1024);// 设置UDP写缓冲区为1M
|
|
// 绑定端口,开始接收进来的连接
|
ChannelFuture f = b.bind(port).sync();
|
//获取channel通道
|
//channel=f.channel();
|
System.out.println("UDP Server 启动,端口:"+port);
|
// 等待服务器 socket 关闭 。
|
// 这不会发生,可以优雅地关闭服务器。
|
f.channel().closeFuture().sync();
|
} catch (InterruptedException e) {
|
e.printStackTrace();
|
} finally {
|
// 优雅退出 释放线程池资源
|
group.shutdownGracefully();
|
workerGroup.shutdownGracefully();
|
}
|
}
|
});
|
thread.start();
|
}
|
|
}
|