前言
本章將會介紹如何使用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