前言
本章将会介绍如何使用Netty搭建一个UDP服务器。
UDP 协议
UDP 协议是无连接且不保证可靠交付的。它是面向报文的,相对TCP来说额外的开销会小很多。
Netty 支持
导入依赖包
// gradle
compile group: 'io.netty', name: 'netty-all', version: '4.1.50.Final'
// maven
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.50.Final</version>
</dependency>
Server 服务端
创建事件线程组
因为UDP是无连接的,因此不再有channel,只需用一个线程监听端口即可。
EventLoopGroup group = new NioEventLoopGroup(1);
服务启动器
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)
.channel(NioDatagramChannel.class)
.option(ChannelOption.SO_BROADCAST, true)
.handler(new UdpNettyHandler());
- NioDatagramChannel:异步UDP通道
- ChannelOption.SO_BROADCAST:广播模式
- UdpNettyHandler 消息入站处理器
handler处理器
public class UdpNettyHandler extends SimpleChannelInboundHandler<DatagramPacket> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
//获取消息内容
ByteBuf content = msg.content();
//写到bytes中
int length = content.readableBytes();
byte[] bytes = new byte[length];
content.readBytes(bytes);
//根据数据类型处理,以下当作十六进制处理
ByteArrayInputStream bs = new ByteArrayInputStream(bytes);
DataInputStream in = new DataInputStream(bs);
byte b1 = in.readByte();
byte b2 = in.readByte();
int i1 = in.readInt();
int i2 = in.readInt();
System.out.println(b1 + "_" + b2 + "_" + i1 + "_" + i2);
}
}
该处理器处理来自UDP的报文。
Bind
bootstrap.bind(8080).sync().channel().closeFuture().await();
到此,服务接收端已完成。
Client 客户端
EventLoopGroup group = new NioEventLoopGroup(1);
try {
Bootstrap b = new Bootstrap();
b.group(group).channel(NioDatagramChannel.class);
Channel ch = b.bind(8081).sync().channel();
//向目标端口发送信息
ch.writeAndFlush(new DatagramPacket(
Unpooled.copiedBuffer("hello, 8080", Charset.forName("UTF-8")),
new InetSocketAddress("127.0.0.1", 8080))).sync();
ch.closeFuture().await();
} catch (Exception e) {
e.printStackTrace();
} finally {
group.shutdownGracefully();
}
客户端较为简单。
总结
Netty具体的组件或用法可以参考我其他文章。
协议系列文章:
框架系列文章:
源码可以见:Netty-Learn