最近研究NIO Netty
下载地址:http://netty.io/downloads.html
本文使用的是:netty-all-4.1.9.Final.jar
直接上代码
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
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 NettyServer
{
private int port;
public NettyServer(int port)
{
this.port = port;
}
private void bind()
{
// 创建一个EventLoopGroup,可以简单认为是Netty框架下的线程池,默认最大线程数量是处理器数量的2倍
EventLoopGroup worker = new NioEventLoopGroup();
try
{
// 引导辅助程序
ServerBootstrap bootstrap = new ServerBootstrap();
// 配置服务器的NIO线程租
bootstrap.group(worker);
// 设置nio类型的channel
bootstrap.channel(NioServerSocketChannel.class);
// 设置连接数
bootstrap.option(ChannelOption.SO_BACKLOG, 1024);
// 设置不延迟,消息立即发送
bootstrap.option(ChannelOption.TCP_NODELAY, true);
// 设置成长连接
bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
// 有连接到达时会创建一个channel
bootstrap.childHandler(new ChannelInitializer<SocketChannel>()
{
@Override
protected void initChannel(SocketChannel socketChannel)
throws Exception
{
// pipeline管理channel中的Handler,在channel队列中添加一个handler来处理业务
ChannelPipeline p = socketChannel.pipeline();
p.addLast(new NettyServerHandler());
}
});
// 配置完成,开始绑定server,通过调用sync同步方法阻塞直到绑定成功
ChannelFuture f = bootstrap.bind(port).sync();
if (f.isSuccess())
System.out.println("启动Netty服务成功,端口号:" + this.port);
// 等待服务端监听端口关闭
f.channel().closeFuture().sync();
} catch (Exception e)
{
e.printStackTrace();
} finally
{
// 优雅退出,释放线程池资源
worker.shutdownGracefully();
}
}
public static void main(String[] args) throws InterruptedException
{
// 创建一个ServerBootstrap实例
NettyServer server = new NettyServer(9999);
server.bind();
}
}
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import java.io.UnsupportedEncodingException;
public class NettyServerHandler extends ChannelInboundHandlerAdapter
{
public void channelRead(ChannelHandlerContext ctx, Object msg)
{
System.out.println("server received.. ");
ByteBuf buf = (ByteBuf) msg;
byte[] req = new byte[buf.readableBytes()];
buf.readBytes(req);
String body;
try
{
body = new String(req, "UTF-8");
System.out.println("client say : " + body);
} catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
ByteBuf resp = Unpooled.copiedBuffer("hello client".getBytes());
ctx.write(resp);
}
public void channelReadComplete(ChannelHandlerContext ctx)
{
System.out.println("server channelReadComplete..");
// 刷新后才将数据发出到SocketChannel
ctx.flush();
}
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
{
// 捕捉异常信息
cause.printStackTrace();
// 出现异常时关闭channel
ctx.close();
}
}
import io.netty.bootstrap.Bootstrap;
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.NioSocketChannel;
public class NettyClient
{
private int port;
private String host;
public NettyClient(int port, String host)
{
this.port = port;
this.host = host;
}
private void connect() throws InterruptedException
{
// 配置客户端NIO线程组
EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
try
{
// 引导辅助程序
Bootstrap bootstrap = new Bootstrap();
// 设置nio类型的channel
bootstrap.channel(NioSocketChannel.class);
// 长连接
bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
// 添加线程组
bootstrap.group(eventLoopGroup);
// 绑定server 通过ip 端口号
bootstrap.remoteAddress(host, port);
// 有连接到达时会创建一个channel
bootstrap.handler(new ChannelInitializer<SocketChannel>()
{
@Override
protected void initChannel(SocketChannel socketChannel)
throws Exception
{
socketChannel.pipeline().addLast(new NettyClientHandler());
}
});
// 发起异步连接操作
ChannelFuture future = bootstrap.connect(host, port).sync();
if (future.isSuccess())
System.out.println("----------------connect server success----------------");
// 等待客户端链路关闭
future.channel().closeFuture().sync();
} finally
{
// 优雅退出,释放线程池资源
eventLoopGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws InterruptedException
{
NettyClient client = new NettyClient(9999, "localhost");
client.connect();
}
}
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
public class NettyClientHandler extends ChannelInboundHandlerAdapter
{
// 此方法会在连接到服务器后被调用
public void channelActive(ChannelHandlerContext ctx)
{
System.out.println("client channelActive..");
ctx.writeAndFlush(Unpooled.copiedBuffer("hello server!", CharsetUtil.UTF_8));
}
// 此方法会在接收到服务器数据后调用
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception
{
System.out.println("client channelRead..");
//服务端返回消息后
ByteBuf buf = (ByteBuf) msg;
byte[] req = new byte[buf.readableBytes()];
buf.readBytes(req);
String body = new String(req, "UTF-8");
System.out.println("server say : " + body);
}
// 捕捉到异常
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
{
cause.printStackTrace();
ctx.close();
}
}