选择Netty的理由
- Java NIO编码比较复杂,要熟练掌握Selector、ServerSocketChannel、SocketChannel、ByteBuffer等。juejin.cn/post/744775… 可以参考笔者的这篇博文,实现一个简单demo级服务端和客户端通信需要大量的代码量。
- 需要对网络编程精通才能写出高质量的代码。
- 面对断连重连、网络闪断半包读写、失败缓存、网络拥塞和异常码流的处理等问题,NIO编程工作量和难度都非常大。
- JDK NIO的bug问题。
Netty NIO编程
使用Netty重构juejin.cn/post/744775… 代码
NettyServer
public class NettyServer {
public static void main(String[] args) throws InterruptedException {
NioEventLoopGroup bossGroup = new NioEventLoopGroup();
NioEventLoopGroup workGroup = new NioEventLoopGroup();
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChildChannelHandler());
ChannelFuture sync = bootstrap.bind(new InetSocketAddress(8080)).sync();
sync.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
}
ChildChannelHandler
public class ChildChannelHandler extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new NIOServerHandler());
}
}
NIOServerHandler
public class NIOServerHandler extends SimpleChannelInboundHandler {
@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf buf = (ByteBuf) msg;
byte[] bytes = new byte[buf.readableBytes()];
buf.readBytes(bytes);
String s = new String(bytes, "UTF-8");
System.out.println("服务端接收到客户端的消息:" + s);
String resp = "hello client-----";
ByteBuf reBuf = Unpooled.copiedBuffer(resp.getBytes());
ctx.writeAndFlush(reBuf);
}
}
NettyClient
public class NettyClient {
public static void main(String[] args) {
NioEventLoopGroup group = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
try {
Bootstrap handler = bootstrap.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new NioClientHandler());
}
});
ChannelFuture sync = handler.connect(new InetSocketAddress("127.0.0.1", 8080)).sync();
sync.channel().closeFuture().sync();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
group.shutdownGracefully();
}
}
}
NioClientHandler
public class NioClientHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
String msg = "Hello server---------";
ByteBuf buf = Unpooled.wrappedBuffer(msg.getBytes());
ctx.writeAndFlush(buf);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf buffer = (ByteBuf) msg;
byte[] bytes = new byte[buffer.readableBytes()];
buffer.readBytes(bytes);
String message = new String(bytes, "UTF-8");
System.out.println("客户端接收到服务器的消息:" + message);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
}
}