当前位置: 首页 > news >正文

netty编程之UDP

写在前面

源码 。
UDP,user datagram protocol,是internet协议簇中无连接的传输协议,因为无连接所以相比于TCP需要维护更少的信息以及网络交互,所以具有更高的效率。本文看下netty是如何实现的,和TCP方式差别不大,下面具体代码实现过程中看下哪里不同。虽然小有不同,但套路相同。

1:代码实现

1.1:server

server main:

package com.dahuyou.netty.udp.server;import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
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 NettyServer {public static void main(String[] args) throws InterruptedException {EventLoopGroup group = new NioEventLoopGroup();try {Bootstrap b = new Bootstrap();b.group(group).channel(NioDatagramChannel.class).option(ChannelOption.SO_BROADCAST, true)    //广播.option(ChannelOption.SO_RCVBUF, 2048 * 1024)// 设置UDP读缓冲区为2M.option(ChannelOption.SO_SNDBUF, 1024 * 1024)// 设置UDP写缓冲区为1M.handler(new MyChannelInitializer());ChannelFuture f = b.bind(7397).sync();System.out.println("udp server start done.");f.channel().closeFuture().sync();} finally {//优雅的关闭释放内存group.shutdownGracefully();}}}

这里有个不同之处,使用的通道类是NioDatagramChannel,而TCP的是.channel(NioServerSocketChannel.class)
MyChannelInitializer如下:

package com.dahuyou.netty.udp.server;import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;public class MyChannelInitializer extends ChannelInitializer<NioDatagramChannel> {private EventLoopGroup group = new NioEventLoopGroup();@Overrideprotected void initChannel(NioDatagramChannel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline();// 解码转String,注意调整自己的编码格式GBK、UTF-8//pipeline.addLast("stringDecoder", new StringDecoder(Charset.forName("GBK")));pipeline.addLast(group, new MyServerHandler());}}

MyServerHandler:

package com.dahuyou.netty.udp.server;import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;public class MyServerHandler extends SimpleChannelInboundHandler<DatagramPacket> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {String msg = packet.content().toString(Charset.forName("GBK"));System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " UDP服务端接收到消息:" + msg);//向客户端发送消息String json = "通知:我已经收到你的消息\r\n";// 由于数据报的数据是以字符数组传的形式存储的,所以传转数据byte[] bytes = json.getBytes(Charset.forName("GBK"));DatagramPacket data = new DatagramPacket(Unpooled.copiedBuffer(bytes), packet.sender());ctx.writeAndFlush(data);//向客户端发送消息}}

这里有一个不同点,继承的是SimpleChannelInboundHandler,而TCP是ChannelInboundHandlerAdapter。

1.2:client

client main:

package com.dahuyou.netty.udp.client;import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel;import java.net.InetSocketAddress;
import java.nio.charset.Charset;public class NettyClient {public static void main(String[] args) {EventLoopGroup group = new NioEventLoopGroup();try {Bootstrap b = new Bootstrap();b.group(group).channel(NioDatagramChannel.class).handler(new MyChannelInitializer());Channel ch = b.bind(7398).sync().channel();//向目标端口发送信息ch.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer("我是客户端小爱,你在吗!", Charset.forName("GBK")),new InetSocketAddress("127.0.0.1", 7397))).sync();ch.closeFuture().await();} catch (Exception e) {e.printStackTrace();} finally {group.shutdownGracefully();}}}

这里写数据需要使用DatagramPacket类进行封装,而TCP是直接写就行。同样channel类也不同。

MyChannelInitializer如下:

package com.dahuyou.netty.udp.client;import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.nio.NioDatagramChannel;public class MyChannelInitializer extends ChannelInitializer<NioDatagramChannel> {@Overrideprotected void initChannel(NioDatagramChannel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline();// 解码转String,注意调整自己的编码格式GBK、UTF-8//pipeline.addLast("stringDecoder", new StringDecoder(Charset.forName("GBK")));pipeline.addLast(new MyClientHandler());}}

MyClientHandler如下:

package com.dahuyou.netty.udp.client;import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;public class MyClientHandler extends SimpleChannelInboundHandler<DatagramPacket> {//接受服务端发送的内容@Overrideprotected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {String msg = packet.content().toString(Charset.forName("GBK"));System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " UDP客户端接收到消息:" + msg);}}

启动server:
在这里插入图片描述
启动client:
在这里插入图片描述
在这里插入图片描述

写在后面

参考文章列表


http://www.mrgr.cn/news/10648.html

相关文章:

  • IT统一运维平台案例
  • 【目标检测】YOLOV2
  • Python中的逻辑魔术:解锁逻辑运算符的力量
  • Vue3搜索框(InputSearch)
  • Robot Operating System——兴趣区域信息
  • 已解决:java.lang.ClassNotFoundException: com.mysql.jdbc.Driver 异常的正确解决方法,亲测有效!!!
  • TCP、UDP
  • Pytorch:torch.diag()创建对角线张量方式例子解析
  • react 修改对象参数的值
  • FFmpeg 实现从设备端获取音视频流并通过RTMP推流
  • Python分布式任务处理库之dramatiq使用详解
  • JVM的内存模型和垃圾回收
  • MongoDB 查询分享 包含( 筛选 分组 排序 脱敏 格式化日期)
  • 数据库里的幽灵数据 - SQLite WAL模式探秘
  • 【前端面试】React深度学习(上)
  • 贪心算法---分发糖果
  • C# 匿名函数 delegate(参数...){ }
  • 《5G 与区块链融合:智能城市服务质量的飞跃》
  • 用命令行工具(nmcli)模仿ubuntu21图形界面的热点功能
  • 【学习笔记】STM32F407探索者HAL库开发(二)STM32F4最小系统设计