netty-第一个案例
netty-第一个demo
搭建环境
maven引入
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.12.Final</version>
</dependency>
服务端
Netty 服务器都需要以下两部分
- 至少一个 ChannelHandler — 该组件实现了服务器对从客户端接收的数据的处理,即它的业务逻辑。
- 引导 — 这是配置服务器的启动代码。至少,它会将服务器绑定到它要监听连接请求的端口上
channelHandler
@Sharable
public class EchoServerHandler extends ChannelInboundHandlerAdapter {
// 对于每个传入的消息都要调用
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf in = (ByteBuf) msg;
System.out.println("server recevied:"+ in.toString(StandardCharsets.UTF_8));
ctx.write(in);
}
// 通知ChannelInboundHandler最后一次对channel-
//Read()的调用是当前批量读取中的最后一条消息
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
}
// 在读取操作期间,有异常抛出时会调用
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.out.println("读取操作错误信息");
cause.printStackTrace(); //打印错误
ctx.close();//关闭channel
}
}
BootStrap
public class EchoServer {
private final int port;
public EchoServer(int port) {
this.port = port;
}
public static void main(String[] args) throws InterruptedException {
int port = Integer.parseInt("1234");
new EchoServer(port).start();
}
//绑定到服务器将在其上监听并接受传入连接请求的端口;
//配置 Channel ,以将有关的入站消息通知给 EchoServerHandler 实例
private void start() throws InterruptedException {
final EchoServerHandler serverHandler = new EchoServerHandler();
NioEventLoopGroup group = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap(); //创建bootstrap
b.group(group)
.channel(NioServerSocketChannel.class) //使用nio传输channel
.localAddress(port) // 绑定端口
.childHandler(new ChannelInitializer<SocketChannel>() {
// 添加一个EchoServer-
//Handler 到子Channel
//的 ChannelPipeline
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(serverHandler);
// EchoServerHandler被标注为@Shareable,所以我们可以总是使用同样的实例
}
});
// 异步地绑定服务器;调用 sync()方法阻塞等待直到绑定完成
ChannelFuture f = b.bind().sync();
// 获取 Channel 的CloseFuture,并且阻塞当前线程直到它完成
f.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
group.shutdownGracefully().sync();
}
}
}
客户端
EchoClientHandler
@Sharable
public class EchoClientHandler
extends SimpleChannelInboundHandler<ByteBuf> {
@Override
public void channelActive(ChannelHandlerContext ctx) {
ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks!",
CharsetUtil.UTF_8));
}
@Override
public void channelRead0(ChannelHandlerContext ctx, ByteBuf in) {
System.out.println(
"Client received: " + in.toString(CharsetUtil.UTF_8));
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx,
Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
BootStrap
public class EchoClient {
private final String host;
private final int port;
public EchoClient(String host, int port) {
this.host = host;
this.port = port;
}
public static void main(String[] args) throws InterruptedException {
final String host = "127.0.0.1";
final int port = Integer.parseInt("1234");
new EchoClient(host, port).start();
}
private void start() throws InterruptedException {
NioEventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.remoteAddress(host,port)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new EchoClientHandler());
}
});
ChannelFuture future = b.connect().sync();
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
group.shutdownGracefully().sync();
}
}
}
运行
- 先启动服务端
- 再启动客户端
服务端结果
server recevied:Netty Socket!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NoEjY2Eb-1571234128207)(C:\Users\ronny\OneDrive\笔记\高并发\picture\1571232070255.png)]
参考文档
[Netty 拆包粘包和服务启动流程分析](https://segmentfault.com/a/1190000013039327)
Netty序章之BIO NIO AIO演变
java nio与bio —— 阻塞IO与非阻塞IO的区别
Java实战之从同步阻塞IO到NIO
netty实战
还没有评论,来说两句吧...