洪城义警-正式版后台
zhongrj
2023-06-27 2ca9993b57bdd090c4345ea6767687e2fbb83014
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package org.springblade.modules.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.modules.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();
    }
 
 
    //给管道抽象出接口,给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();
    }
 
}