Netty UDP

UDP 介绍

    UDP 是无连接的数据报服务,不对数据报进行检查与修改,无须等待对方的应答,速度快,可能会丢包,UDP段结构比TCP的段结构简单,因此网络开销也小。

UDP数据报格式有  首部 数据 两个部分 

首部 为8个字节 包括以下部分

(1) 源端口:源端口号,2个字节,最大值为65525

(2)目的端口:目的端口号,2个字节,最大值为65525

 (3)长度:2字节,UDP用户数据报的总长度

 (4)校验和:2字节,用于校验UDP数据报的数字段和包含UDP数据报首部的“伪首部” 

“伪首部” :伪包头

 

UDP协议的特点

 (1)UDP传送数据前并不与对方建立连接,即UDP是无连接的,在传输数据前,发送方和接收方相到交换信息使双方同步

 (2)UDP对接收的数据报不发送确认信号,发送端不知道 数据是否被正确接收,也不会重发数据

  (3)UDP传送数据比TCP 快速,系统弄错也少。

 

UDP的优势

  • 网络环境越来越稳定、可靠,给了UDP取代TCP的机会;此时TCP的拥塞处理、超时重传等机制显得有些多余。
  • UDP相比了TCP,传输速度快,更能满足实时性的要求。若是数据量大,TCP会有拥塞控制;若是丢包,还得等待重传;会有较大延时。
  • 如果对数据有可靠传输的需求,应用可以通过一些机制来保证。 a. 发送方对所发的报文要求应答。 b. 报文头里加序号字段,交互时需检测(每次交互加1)
  • UDP分组首部开销小,可以提高数据的传输效率
  • UDP还支持一对一、一对多与多对多的交互式通信方式,所以多播和广播是需要通过UDP来实现的

①开销更小

TCP为了保证其可靠性,首部包含20字节,以及40字节的可选项,UDP首部只有8字节

②速度更快

 

UDP vsTCP

1 UDP和TCP协议的主要区别是两者在如何实现信息的可靠传递方面不同。

2 TCP协议中包含了专门的传递保证机制,当数据接收方收到发送方传来的信息时,会自动向发送方发出确认消息;发送方只有在接收到该确认消息之后才继续传送其它信息,否则将一直等待直到收到确认信息为止。

3 与TCP不同,UDP协议并不提供数据传送的保证机制。

 

UDP实列

1 UDP服务端开发启动类 UDPServer

package com.UDP;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;

public class UDPServer {
    public void run(int port)throws Exception{
        EventLoopGroup bossGroup=new NioEventLoopGroup();
        try
        {
            //通过NioDatagramChannel创建Channel,并设置Socket参数支持广播
            //UDP相对于TCP不需要在客户端和服务端建立实际的连接,因此不需要为连接(ChannelPipeline)设置handler
            Bootstrap b=new Bootstrap();
            b.group(bossGroup)
                    .channel(NioDatagramChannel.class)
                    .option(ChannelOption.SO_BROADCAST, true)
                    .handler(new UDPServerHandler());
            b.bind(port).sync().channel().closeFuture().await();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally{
            bossGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args)throws Exception
    {
        new UDPServer().run(8089);
    }

}

2 UDP服务端开发辅助处理类 UDPServerHandler

package com.UDP;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.CharsetUtil;



public class UDPServerHandler extends
        SimpleChannelInboundHandler<DatagramPacket> {


    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
        //利用ByteBuf的toString()方法获取请求消息
        String req=packet.content().toString(CharsetUtil.UTF_8);
        System.out.println(req);
        if("结果".equals(req)) {
            ctx.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(
                    "结果" + "Netty UDP", CharsetUtil.UTF_8), packet.sender()));
     }


    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx,Throwable cause)
            throws Exception{
        ctx.close();
        cause.printStackTrace();
    }

}

3 UDP客户端开发启动类

package com.UDP;


import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.channel.Channel;
import io.netty.util.CharsetUtil;

import io.netty.channel.socket.DatagramPacket;
import java.net.InetSocketAddress;


public class UDPClient {

    public void connect(int port) {
        // 配置nio线程组
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(group)
                    .channel(NioDatagramChannel.class)
                    .option(ChannelOption.SO_BROADCAST, true)
                    .handler(new UDPClientHandler());
            Channel ch = bootstrap.bind(0).sync().channel();

            ch.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(
                    "结果", CharsetUtil.UTF_8), new InetSocketAddress(
                    "255.255.255.255", port))).sync();
            if(!ch.closeFuture().await(15000)){
                System.out.println("查询超时!!!");
            }

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("出错了");
        } finally {
            group.shutdownGracefully();
        }
    }


    public static void main(String[] args) {

        new UDPClient().connect(8089);

    }
}

4 UDP客户端开发辅助处理类

package com.UDP;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.CharsetUtil;


public class UDPClientHandler  extends
        SimpleChannelInboundHandler<DatagramPacket> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
        String response=msg.content().toString(CharsetUtil.UTF_8);
      if(response.startsWith("结果")){
            System.out.println(response);
            ctx.close();
     }
    }



    @Override
    public void exceptionCaught(ChannelHandlerContext ctx,Throwable
            cause)throws Exception{
        cause.printStackTrace();
        ctx.close();
    }
}

5结果:

15:29:12.151 [main] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkAccessible: true
15:29:12.151 [main] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkBounds: true
15:29:12.154 [main] DEBUG io.netty.util.ResourceLeakDetectorFactory - Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@3712b94
15:29:12.160 [main] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.maxCapacityPerThread: 4096
15:29:12.160 [main] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.maxSharedCapacityFactor: 2
15:29:12.160 [main] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.linkCapacity: 16
15:29:12.160 [main] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.ratio: 8
结果Netty UDP

 

注解:

DatagramChannel:

Java NIO中的DatagramChannel定义在java.nio.channels包中,是一个能收发UDP包的通道。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值