java 的nio是有bug的,而使用起来也是不方便的,netty框架可以很好的实现高并发并且可以实现自定义协议。
Channel一个客户端与服务器通信的通道ChannelHandler,业务逻辑处理器,分为ChannelInboundHandler和ChannelOutboundHandler
ChannelPipeline,用于存放ChannelHandler的容器
ChannelContext,通信管道的上下
ByteBuf是一个存储字节的容器
自定义协议通过decode和encode实现
client启动类
package nettystudy;
import java.net.InetSocketAddress;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
public class Client {
private EventLoopGroup work= new NioEventLoopGroup();
Bootstrap bS= new Bootstrap();
public void run() throws InterruptedException {
try{
bS.group(work)
.channel(NioSocketChannel.class)
.remoteAddress(new InetSocketAddress("localhost",8088))
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch)
throws Exception {
ch.pipeline().addLast(new EchoClientHandler());
}
});
ChannelFuture f= bS.connect().sync();
f.channel().closeFuture().sync();
}finally{
work.shutdownGracefully().sync();
}
}
public static void main(String[] args) throws Exception {
new Client().run();
}
}
客户端处理类
package nettystudy;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil;
@Sharable //1
public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
//
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("正在连接... ");
super.channelActive(ctx);
ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks!",
CharsetUtil.UTF_8));
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx,Throwable cause) throws Exception{
cause.printStackTrace();
ctx.close();
}
@Override
protected void channelRead0(ChannelHandlerContext arg0, ByteBuf arg1) throws Exception {
byte[] req = new byte[arg1.readableBytes()];
arg1.readBytes(req);
String body = new String(req,"UTF-8");
System.out.println(body);
}
}
服务端启动类
package nettystudy;
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;
public class DiscardService {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workGroup = new NioEventLoopGroup();
ServerBootstrap boot = new ServerBootstrap();
public void run() throws InterruptedException {
System.out.println("准备运行端口:" );
try {
boot.group(bossGroup,workGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>(){
@Override
public void initChannel(SocketChannel ch)throws Exception{
ch.pipeline().addLast(new DiscardServerHandler());
}
});
boot=boot.option(ChannelOption.SO_BACKLOG, 128);
boot=boot.childOption(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture f= boot.bind(8088).sync();
ChannelFuture f1= boot.bind(8089).sync();
f.channel().closeFuture().sync();
}finally {
workGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
System.out.println("准备运行端口:");
}
}
public static void main(String args[]) throws InterruptedException {
DiscardService dS= new DiscardService();
dS.run();
}
}
服务端处理类
package nettystudy;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
public class DiscardServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx,Object msg) {
try {
ByteBuf in = (ByteBuf)msg;
System.out.println(in.toString(CharsetUtil.UTF_8));
ctx.writeAndFlush(Unpooled.copiedBuffer("Netdsfsfty rocks!",
CharsetUtil.UTF_8));
}finally {
ReferenceCountUtil.releaseLater(msg);
}
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx,Throwable cause) throws Exception{
cause.printStackTrace();
ctx.close();
}
}