AIO案例
1,ChannelAdapter.java
package com.forezp.util.io.aio; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousServerSocketChannel; import java.nio.channels.AsynchronousSocketChannel; import java.nio.channels.CompletionHandler; import java.nio.charset.Charset; import java.util.concurrent.TimeUnit; /*** * aio消息处理器 * CompletionHandler事件处理类(回调函数) */ public abstract class ChannelAdapter implements CompletionHandler<Integer,Object> { private AsynchronousSocketChannel channel; private Charset charset; public ChannelAdapter( AsynchronousSocketChannel channel,Charset charset) { this.charset = charset; this.channel = channel; if(channel.isOpen()){ channelActive(new ChannelHandler(channel, charset)); } } /*** * 在操作完成时调用,result是操作完成返回的结果, * attachment是注册该回调函数时添加的附件,在回调函数调用时又会传递回来 * @param result * @param attachment */ public void completed(Integer result, Object attachment){ try { final ByteBuffer buffer=ByteBuffer.allocate(1024); final long timeout=60*60l; channel.read(buffer, timeout, TimeUnit.SECONDS, null, new CompletionHandler<Integer, Object>() { @Override public void completed(Integer result, Object attachment) { if (result == -1) { try { channelInactive(new ChannelHandler(channel, charset)); channel.close(); } catch (IOException e) { e.printStackTrace(); } return; } buffer.flip(); channelRead(new ChannelHandler(channel, charset), charset.decode(buffer)); buffer.clear(); channel.read(buffer, timeout, TimeUnit.SECONDS, null, this); } @Override public void failed(Throwable exc, Object attachment) { exc.printStackTrace(); } }); }catch (Exception e){ e.printStackTrace(); } } /*** * 当操作失败时调用,Throwable是操作失败发生的异常对象, * attachment是注册该回调函数时添加的附件,在回调函数调用时又会传递回来 * @param exc * @param attachment */ public void failed(Throwable exc, Object attachment){ exc.getStackTrace(); } /*** * 处理连接 * @param ctx */ public abstract void channelActive(ChannelHandler ctx); public abstract void channelInactive(ChannelHandler ctx); // 读取消息抽象类 public abstract void channelRead(ChannelHandler ctx, Object msg); }
2,AioServiceHandler.java
package com.forezp.util.io.aio.service; import com.forezp.util.io.aio.ChannelAdapter; import com.forezp.util.io.aio.ChannelHandler; import java.io.IOException; import java.nio.channels.AsynchronousSocketChannel; import java.nio.charset.Charset; public class AioServiceHandler extends ChannelAdapter { public AioServiceHandler(AsynchronousSocketChannel channel, Charset charset) { super(channel, charset); } @Override public void channelActive(ChannelHandler ctx) { try { System.out.println("已连接的IP:"+ctx.channel().getLocalAddress()); ctx.writeAndFlush("服务端连接建立成功!"+ctx.channel().getLocalAddress()); }catch (Exception e){ e.printStackTrace(); } } @Override public void channelInactive(ChannelHandler ctx) { } @Override public void channelRead(ChannelHandler ctx, Object msg) { System.out.println("接收到客户端消息:"+msg); ctx.writeAndFlush("服务端信息处理成功!消息内容:"+msg); } }
3,ChannelInitializer.java
package com.forezp.util.io.aio; import com.forezp.util.io.aio.service.AioServer; import com.forezp.util.io.aio.service.AioServerChannelInitializer; import java.nio.channels.AsynchronousServerSocketChannel; import java.nio.channels.AsynchronousSocketChannel; import java.nio.channels.CompletionHandler; /*** *当I/O操作成功完成时,将调用completed方法。 * 如果I/O操作失败,将调用failed方法 */ public abstract class ChannelInitializer implements CompletionHandler<AsynchronousSocketChannel, AioServer> { public void completed( AsynchronousSocketChannel result, AioServer attachment){ try { initChannel(result); }catch (Exception e){ e.printStackTrace(); }finally { //重新接收 attachment.serverSocketChannel().accept(attachment,this); } } public void failed(Throwable exc, AioServer attachment){ exc.getStackTrace(); } /*** * 初始化 * @param channel * @return * @throws Exception */ protected abstract void initChannel(AsynchronousSocketChannel channel) throws Exception; }
4,AioServer.java
package com.forezp.util.io.aio.service; import java.net.InetSocketAddress; import java.nio.channels.AsynchronousChannelGroup; import java.nio.channels.AsynchronousServerSocketChannel; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; public class AioServer extends Thread{ private AsynchronousServerSocketChannel channel; @Override public void run() { try { //利用工厂方法产生一个异步通道 channel = AsynchronousServerSocketChannel.open( AsynchronousChannelGroup.withCachedThreadPool(Executors.newCachedThreadPool(),10)); channel.bind(new InetSocketAddress(6000)); System.out.println("服务端启动成功!...."); CountDownLatch count=new CountDownLatch(1); //注册事件和事件完成后的处理器,这个CompletionHandler就是事件完成后的处理器 channel.accept(this,new AioServerChannelInitializer()); count.await(); }catch (Exception e){ e.printStackTrace(); } } public AsynchronousServerSocketChannel serverSocketChannel(){ return channel; } public static void main(String[] args) { new AioServer().start(); } }
5,AioServiceHandler.java
package com.forezp.util.io.aio.service; import com.forezp.util.io.aio.ChannelAdapter; import com.forezp.util.io.aio.ChannelHandler; import java.io.IOException; import java.nio.channels.AsynchronousSocketChannel; import java.nio.charset.Charset; public class AioServiceHandler extends ChannelAdapter { public AioServiceHandler(AsynchronousSocketChannel channel, Charset charset) { super(channel, charset); } @Override public void channelActive(ChannelHandler ctx) { try { System.out.println("已连接的IP:"+ctx.channel().getLocalAddress()); ctx.writeAndFlush("服务端连接建立成功!"+ctx.channel().getLocalAddress()); }catch (Exception e){ e.printStackTrace(); } } @Override public void channelInactive(ChannelHandler ctx) { } @Override public void channelRead(ChannelHandler ctx, Object msg) { System.out.println("接收到客户端消息:"+msg); ctx.writeAndFlush("服务端信息处理成功!消息内容:"+msg); } }
6,AioServerChannelInitializer.java
package com.forezp.util.io.aio.service; import com.forezp.util.io.aio.ChannelInitializer; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousSocketChannel; import java.nio.charset.Charset; import java.util.concurrent.TimeUnit; public class AioServerChannelInitializer extends ChannelInitializer { @Override protected void initChannel(AsynchronousSocketChannel channel) throws Exception { channel.read(ByteBuffer.allocate(1024),10, TimeUnit.SECONDS,null,new AioServiceHandler(channel, Charset.forName("utf-8"))); } }
7,客服端AioClient.java
package com.forezp.util.io.aio.client; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousSocketChannel; import java.nio.charset.Charset; import java.util.concurrent.Future; public class AioClient { public static void main(String[] args) throws Exception{ AsynchronousSocketChannel channel= AsynchronousSocketChannel.open(); Future<Void> future=channel.connect(new InetSocketAddress("127.0.0.1",6000)); System.out.println("aio client start...."); future.get(); channel.read(ByteBuffer.allocate(1024),null,new AioClientHandler(channel, Charset.forName("utf-8"))); Thread.sleep(1000000); } }
8,AioClientHandler.java
package com.forezp.util.io.aio.client; import com.forezp.util.io.aio.ChannelAdapter; import com.forezp.util.io.aio.ChannelHandler; import java.io.IOException; import java.nio.channels.AsynchronousSocketChannel; import java.nio.charset.Charset; public class AioClientHandler extends ChannelAdapter { public AioClientHandler(AsynchronousSocketChannel channel, Charset charset) { super(channel, charset); } @Override public void channelActive(ChannelHandler ctx) { try { System.out.println("客户端连接成功!"+ ctx.channel().getLocalAddress()); } catch (IOException e) { e.printStackTrace(); } } @Override public void channelInactive(ChannelHandler ctx) { } @Override public void channelRead(ChannelHandler ctx, Object msg) { System.out.println("客户端接收消息:"+msg); ctx.writeAndFlush("客户端接收消息成功!消息内容:"+msg); } }
测试,启动服务端,客户端:

netty框架学习之基础
好记性不如烂笔头
浙公网安备 33010602011771号