netty-netty基本使用
摘自<netty权威r指南>
编写netty服务器和客户端三部曲:
- 绑定Group(EventLoopGroup,即一组EventLoop集合,可以理解成socket线程组)
- 声明Channel
- 指定ChannelHandler
服务器端
public class TimeServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx,
Object msg) throws Exception {
ByteBuf buf = (ByteBuf) msg;
byte[] req = new byte[buf.readableBytes()];
buf.readBytes(req);
String body = new String(req, "UTF-8");
System.out.println("time server recv[x]: "+ body);
String currentTime = "time".equals(body) ?
new Date(System.currentTimeMillis()).toString() : "bad time";
ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes());
ctx.write(resp);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx)
throws Exception {
// ctx.flush();
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
.addListener(ChannelFutureListener.CLOSE);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx,
Throwable cause) throws Exception {
ctx.close();
}
}
服务器启动类:
public class TimeServer {
public static void main(String[] args) {
int port = 8080;
new TimeServer().bind(port);
}
public void bind(int port) {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1024)
.childHandler(new ChildChannelHandler());
//阻塞到启动成功
// ChannelFuture future = serverBootstrap.bind(port).sync();
ChannelFuture future = serverBootstrap.bind(port);
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future)
throws Exception {
if (future.isSuccess()){
System.out.println("server started success...");
}else {
System.out.println("server started failed...");
future.cause().printStackTrace();
}
}
});
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
}
客户端
public class TimeClientHandler extends ChannelInboundHandlerAdapter {
private final ByteBuf firstMsg;
public TimeClientHandler() {
String time = "time";
firstMsg = Unpooled.copiedBuffer(time.getBytes());
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(firstMsg);
}
@Override
public void channelRead(ChannelHandlerContext ctx,
Object msg) throws Exception {
ByteBuf buf = (ByteBuf)msg;
byte[] bytes = new byte[buf.readableBytes()];
buf.readBytes(bytes);
String body = new String(bytes,"utf-8");
System.out.println("now is :"+ body);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx,
Throwable cause) throws Exception {
ctx.close();
}
}
客户端启动类:
public class TimeClient {
public static void main(String[] args) throws InterruptedException {
int port = 8080;
String host = "127.0.0.1";
new TimeClient().connect(port, host);
}
public void connect(int port, String host) throws InterruptedException {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group).channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY,true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch)
throws Exception {
ch.pipeline().addLast(new TimeClientHandler());
}
});
//阻塞到连接成功
// ChannelFuture future= bootstrap.connect(host, port).sync();
ChannelFuture future= bootstrap.connect(host, port);
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future)
throws Exception {
if (future.isSuccess()){
System.out.println("client established success...");
}else {
System.out.println("client established failed...");
future.cause().printStackTrace();
}
}
});
future.channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}
}
}
运行结果
1.服务器端运行结果:
server started success...
time server recv[x]: time
2.客户端运行结果:
client established success...
now is :Mon Feb 03 15:51:51 CST 2020