NIO案例
1,NioServer.java
package com.forezp.util.io.nio.service; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.charset.Charset; public class NioServer { private Selector selector; private ServerSocketChannel socketChannel; public static void main(String[] args) { new NioServer().bind(6000); } private void bind(int port) { try { selector=Selector.open(); socketChannel=ServerSocketChannel.open(); socketChannel.configureBlocking(false); //绑定端口 socketChannel.socket().bind(new InetSocketAddress(port),1024); //注册通道 socketChannel.register(selector, SelectionKey.OP_ACCEPT); System.out.println("nio server start ..."); new NioServerHandler(selector, Charset.forName("UTF-8")).start(); }catch (IOException e){ e.printStackTrace(); } } }
2,NioServerHandler.java
package com.forezp.util.io.nio.service; import com.forezp.util.io.nio.ChannelAdapter; import com.forezp.util.io.nio.ChannelHandler; import java.io.IOException; import java.nio.channels.Selector; import java.nio.charset.Charset; import java.text.SimpleDateFormat; import java.util.Date; public class NioServerHandler extends ChannelAdapter { public NioServerHandler(Selector selector, Charset charset) { super(selector, charset); } /*** * 通道 * @param ctx */ @Override public void channelActive(ChannelHandler ctx) { try { System.out.println("LocalAddress:" + ctx.channel().getLocalAddress()); ctx.writeAndFlush("hello,NioServer to msg for you\r\n"); } catch (IOException e) { e.printStackTrace(); } } /*** * 处理信息 * @param ctx * @param msg */ @Override public void channelRead(ChannelHandler ctx, Object msg) { System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "服务端接收到消息:" + msg); ctx.writeAndFlush("hello,服务端已经收到你的消息Success!\r\n"); ctx.writeAndFlush("服务端消息内容:"+msg); } }
3,ChannelAdapter.java
package com.forezp.util.io.nio; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; import java.util.Iterator; import java.util.Set; public abstract class ChannelAdapter extends Thread { private Selector selector; private ChannelHandler channelHandler; private Charset charset; public ChannelAdapter(Selector selector, Charset charset) { this.selector = selector; this.charset = charset; } @Override public void run() { while (true) { try { //选择通道,设置超时时间 selector.select(1000); Set<SelectionKey> selectedKeys = selector.selectedKeys(); Iterator<SelectionKey> it = selectedKeys.iterator(); SelectionKey key = null; while (it.hasNext()) { key = it.next(); it.remove(); handleInput(key); } } catch (Exception ignore) { } } } /*** * 处理接收到的消息块 * @param key */ private void handleInput(SelectionKey key) throws IOException { //调用key的isValid()方法来测试其有效性,无效则退出 if (!key.isValid()) return; // 客户端SocketChannel Class<?> superclass = key.channel().getClass().getSuperclass(); if (superclass == SocketChannel.class){ SocketChannel socketChannel = (SocketChannel) key.channel(); if (key.isConnectable()) { if (socketChannel.finishConnect()) { channelHandler = new ChannelHandler(socketChannel, charset); channelActive(channelHandler); socketChannel.register(selector, SelectionKey.OP_READ); } else { System.exit(1); } } } // 服务端ServerSocketChannel if (superclass == ServerSocketChannel.class){ if (key.isAcceptable()) { ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel(); SocketChannel socketChannel = serverSocketChannel.accept(); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ); channelHandler = new ChannelHandler(socketChannel, charset); channelActive(channelHandler); } } if (key.isReadable()) { SocketChannel socketChannel = (SocketChannel) key.channel(); ByteBuffer readBuffer = ByteBuffer.allocate(1024); int readBytes = socketChannel.read(readBuffer); if (readBytes > 0) { readBuffer.flip(); byte[] bytes = new byte[readBuffer.remaining()]; readBuffer.get(bytes); channelRead(channelHandler, new String(bytes, charset)); } else if (readBytes < 0) { key.cancel(); socketChannel.close(); } } } // 链接通知 public abstract void channelActive(ChannelHandler ctx); // 读取消息 public abstract void channelRead(ChannelHandler ctx, Object msg); }
4,ChannelHandler.java
package com.forezp.util.io.nio; import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; public class ChannelHandler { private SocketChannel channel; private Charset charset; public ChannelHandler(SocketChannel channel, Charset charset) { this.channel = channel; this.charset = charset; } //获取消息 public void writeAndFlush(Object msg) { try { byte[] bytes = msg.toString().getBytes(charset); ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length); writeBuffer.put(bytes); writeBuffer.flip(); channel.write(writeBuffer); } catch (IOException e) { e.printStackTrace(); } } public SocketChannel channel() { return channel; } }
5,NioClient.java
package com.forezp.util.io.nio.client; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; public class NioClient { public static void main(String[] args) { try { Selector selector=Selector.open(); SocketChannel channel=SocketChannel.open(); channel.configureBlocking(false); boolean isConnect=channel.connect(new InetSocketAddress("127.0.0.1",6000)); if(isConnect){ channel.register(selector, SelectionKey.OP_READ); }else { channel.register(selector,SelectionKey.OP_CONNECT); } new NioClientHandler(selector, Charset.forName("UTF-8")).start(); }catch (IOException e){ e.printStackTrace(); } } }
6,NioClientHandler.java
package com.forezp.util.io.nio.client; import com.forezp.util.io.nio.ChannelAdapter; import com.forezp.util.io.nio.ChannelHandler; import java.io.IOException; import java.nio.channels.Selector; import java.nio.charset.Charset; import java.text.SimpleDateFormat; import java.util.Date; public class NioClientHandler extends ChannelAdapter { public NioClientHandler(Selector selector, Charset charset) { super(selector, charset); } @Override public void channelActive(ChannelHandler ctx) { try { System.out.println("LocalAddress:" + ctx.channel().getLocalAddress()); ctx.writeAndFlush("hello,NioClient to msg for you \r\n"); } catch (IOException e) { e.printStackTrace(); } } @Override public void channelRead(ChannelHandler ctx, Object msg) { System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "客户端接收到消息:" + msg); ctx.writeAndFlush("hello,客户端已经收到你的消息Success!\r\n"); ctx.writeAndFlush("客户端消息内容:"+msg); } }
运行服务端,客户端测试:
netty框架学习之基础
好记性不如烂笔头
浙公网安备 33010602011771号