洪城义警-正式版后台
zengh
2021-06-22 d8facdcffa9b7424ab0a12c51c9b934ec447d173
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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();
    }
 
    /**
     * 不用
     */
    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();
    }
 
}