什么是Netty:
netty官网给的解释:
Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.
Netty是提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
maven依赖如下:这里使用的版本是4.1.31.Final
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.31.Final</version>
</dependency>
下面是一个简单的Hello World的代码:
- 客户端:
package cn.jonah.netty;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
/**
* @description: netty客户端
*
* @author Jonah @date 2018/11/29
*
*/
public class Client {
public static void main(String[] args) throws Exception{
EventLoopGroup workgroup = new NioEventLoopGroup();
Bootstrap b = new Bootstrap();
b.group(workgroup)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel sc) throws Exception {
sc.pipeline().addLast(new ClientHandler());
}
});
ChannelFuture cf1 = b.connect("127.0.0.1", 8765).sync();
cf1.channel().writeAndFlush(Unpooled.copiedBuffer("Hello Hello ".getBytes()));
cf1.channel().closeFuture().sync();
workgroup.shutdownGracefully();
}
}
- 客户端处理器:
package cn.jonah.netty;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;
/**
* @description: client处理器,用来监听处理服务端发送的信息
*
* @author Jonah @date 2018/11/29
*
*/
public class ClientHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
ByteBuf buf = (ByteBuf) msg;
byte[] data = new byte[buf.readableBytes()];
buf.readBytes(data);
String request = new String(data, "utf-8");
System.out.println(String.format("Client------> %s",request));
Thread.sleep(1000);
ctx.writeAndFlush(Unpooled.copiedBuffer("Hello World".getBytes()));
} finally {
ReferenceCountUtil.release(msg);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
- 服务端:
package cn.jonah.netty;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
/**
* @description: netty服务端
*
* @author Jonah @date 2018/11/29
*
*/
public class Server {
public static void main(String[] args) throws Exception {
//第一个线程组,用于接收Client端连接
EventLoopGroup bossGroup = new NioEventLoopGroup();
//第二个线程组,用于接收实际业务处理操作
EventLoopGroup workerGroup = new NioEventLoopGroup();
//创建一个辅助类Bootstrap,对server进行一系列配置
ServerBootstrap b = new ServerBootstrap();
//把两个工作线程组加进来
b.group(bossGroup,workerGroup);
//指定NioServerSocketChannel这种通道类型
b.channel(NioServerSocketChannel.class);
//用 childHandler 去绑定具体的 事件处理器
b.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new ServerHandle());
}
});
//设置发送缓冲大小
b.option(ChannelOption.SO_SNDBUF, 50*1024);
//设置接收缓冲大小
b.option(ChannelOption.SO_RCVBUF, 50*1024);
//绑定指定的端口 进行监听
ChannelFuture f = b.bind(8765).sync();
Thread.sleep(1000);
//没有这句话则不会在此阻塞等待客户端的连接,而是直接执行后面代码
f.channel().closeFuture().sync();
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
- 服务端处理器:
package cn.jonah.netty;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
/**
* @description: server处理器,用来监听处理客户端发送的信息
*
* @author Jonah @date 2018/11/29
*
*/
public class ServerHandle extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf buf = (ByteBuf) msg;
byte[] data = new byte[buf.readableBytes()];
buf.readBytes(data);
String request = new String(data, "utf-8");
System.out.println(String.format("Server----->%s", request));
//反馈信息给客户端
String response = "nice to meet u";
//写回数据,并断开客户端的链接
ctx.writeAndFlush(Unpooled.copiedBuffer(response.getBytes()))/*.addListener(ChannelFutureListener.CLOSE)*/;
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause){
cause.printStackTrace();
ctx.close();
}
}
先启动Server,再启动Client