Netty-UDP协议

实现一个UDP应用关键的点:

1、和tcp的不同,udp没有接收的说法,所以即使是接收端,也使用Bootstrap

89345b21b9c94a5d12d9c666527c3ea799d.jpg

2、指定channel为NioDatagramChannel

ec32e80ae9713cfd3b736f4f935e78e777e.jpg

3、发送的时候发送数据包,并需要指定发送的ip和端口号

f450f18e96017c252c44bdedf27b3cc3ac9.jpg

 

实战:发送一个消息hello,返回world

接收端

UDPReceiver

public class UDPReceiver {
    private int port;
    private EventLoopGroup group;
    private Bootstrap b;

    public UDPReceiver(int port) {
        this.port = port;
        group = new NioEventLoopGroup();
        //和tcp的不同,udp没有接受的说法,所以即使是接收端,也使用Bootstrap
        b = new Bootstrap();
        b.group(group)
                //由于我们用的是UDP协议,所以要用NioDatagramChannel来创建
                .channel(NioDatagramChannel.class)
                //向ChannelPipeline里添加业务处理handler
                .handler(new UDPReceiveHandler());
    }
    /**
     * 启动
     * @throws InterruptedException
     */
    public void start() throws InterruptedException {
        try {
            //没有接受客户端连接的过程,监听本地端口即可
            b.bind(this.port).sync();
            System.out.println("服务器启动成功");
        } finally {

        }
    }
    /**
     * 资源优雅释放
     */
    public void close() {
        try {
            if (group != null)
                group.shutdownGracefully().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) throws InterruptedException, IOException {
        UDPReceiver udpReceiver = new UDPReceiver(9999);
        try {
            udpReceiver.start();
            //防止主程序退出
            System.in.read();
        } finally {
            udpReceiver.close();
        }
    }
}

UDPReceiveHandler 

public class UDPReceiveHandler extends SimpleChannelInboundHandler<DatagramPacket> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
        //获得请求
        String req = packet.content().toString(CharsetUtil.UTF_8);
        System.out.println("UDPReceiveHandler:" + req);
        if (req.equals("hello")){
            /**
             * 重新 new一个DatagramPacket对象,我们通过packet.sender()
             * 来获取发送者的地址。
             * 重新发送出去!
             */
            ctx.writeAndFlush(
                    new DatagramPacket(
                            Unpooled.copiedBuffer("world", CharsetUtil.UTF_8),
                            packet.sender()));
        }
    }
}

 

发送端

public class UDPSender {

    private Channel channel;
    private EventLoopGroup group;
    private Bootstrap b;
    public UDPSender() {
        //第一个线程组是用于接收Client连接的
        group = new NioEventLoopGroup();
        //服务端辅助启动类
        b = new Bootstrap();
        b.group(group)
                //由于我们用的是UDP协议,所以要用NioDatagramChannel来创建
                .channel(NioDatagramChannel.class)
                //向ChannelPipeline里添加业务处理handler
                .handler(new UDPSenderHandler());
        try {
            //不需要建立连接
            channel = b.bind(0).sync().channel();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    /**
     * 发送消息
     * @param msg
     * @return
     */
    public boolean send(String ip,int port,String msg) throws InterruptedException {
        //将UDP请求的报文以DatagramPacket打包发送给接受端
        channel.writeAndFlush(new DatagramPacket(
                Unpooled.copiedBuffer("hello",CharsetUtil.UTF_8),
                new InetSocketAddress(ip,port)
        )).sync();//同步调用

        return true;
    }
    /**
     * 关闭释放资源
     */
    public void close(){
        try {
            if (group != null)
            group.shutdownGracefully().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        UDPSender udpSender = new UDPSender();
        udpSender.send("127.0.0.1",9999,"hello");//单播

//        udpSender.send("255.255.255.255",9999,"hello");//广播

    }
}

如果是广播,把ip改成255.255.255.255,发送到这个地址的消息都将会被定向给本地网络(0.0.0.0)上的所有主机,而不会被路由器
转发给其他的网络。

public class UDPSenderHandler extends SimpleChannelInboundHandler<DatagramPacket> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
        //获得请求
        String req = packet.content().toString(CharsetUtil.UTF_8);
        System.out.println(req);
    }
}

 

运行接收端,运行客户端

57f3593d1b27724fe39ee40cb164e56b355.jpg

b5c6dc92945b10c162cb6fb08cbb215ad82.jpg

 

转载于:https://my.oschina.net/suzheworld/blog/3006818

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值