zoukankan      html  css  js  c++  java
  • JAVA NIO 笔记(2)

    1.key.attachment为空?   sc.register(selector,  SelectionKey.OP_WRITE|SelectionKey.OP_READ,bb);  使用这种方法注册事件时,需要添加第三个参数:attachment对象;或者使用  key.interestOps(SelectionKey.OP_WRITE | SelectionKey.OP_READ)方法;  

    2.如何捕捉到客户端断开事件?断开时会触发readable key,所以在isreadable中判断read的返回值是否为-1

    3.如果不注册写事件则写操作无疑和同步方式一样了,如果注册了写事件则需要在写完时取消该事件

    4.key.cancel会同时取消读与写事件 

    package my;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.net.InetSocketAddress;
    import java.net.ServerSocket;
    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.util.Iterator;
    
    public class NIOS {
    	public static final int SIZE = 1024;
    	void start(int port) {
    		ByteBuffer buffer = ByteBuffer.allocate(SIZE);
    		try {
    			ServerSocketChannel s = ServerSocketChannel.open();
    			ServerSocket socket = s.socket();
    			Selector selector = Selector.open();
    			InetSocketAddress addr = new InetSocketAddress(port);
    			socket.bind(addr);
    			s.configureBlocking(false);
    			s.register(selector, SelectionKey.OP_ACCEPT);
    			while (true) {
    				int selCount = selector.select();
    				Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
    				while (keys.hasNext()) {
    					System.out.println("select Count:" + selCount);
    					SelectionKey key = (SelectionKey) keys.next();
    					keys.remove();
    					if (key.isAcceptable()) {
    						System.out.println("isacc...");
    						ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
    						SocketChannel sc = ssc.accept();
    						sc.configureBlocking(false);
    						sc.register(selector, SelectionKey.OP_READ);
    					} else if (key.isReadable()) {
    						System.out.println("readable..");
    						SocketChannel sc = (SocketChannel) key.channel();
    						try {
    							
    							int count = sc.read(buffer);
    							System.out.println("Read byte:" + count);
    							//log(buffer);
    							if(count==SIZE){
    								//如果count等于缓冲区大小,则说明此条消息没读完
    								//需要设计复杂点的消息结构
    								
    							}else
    							if (count == -1) {
    								//当客户端断开连接时会触发read事件,并且可以读到-1,这时关闭通道
    								sc.close();
    								key.cancel();
    								continue;
    							}
    
    						} catch (Exception e) {
    							// TODO: handle exception
    							sc.close();
    							key.cancel();
    							System.out.println("close!");
    							continue;
    						}
    						buffer.flip();
    						ByteBuffer bb = buffer.duplicate();
    						key.attach(bb);
    						buffer.clear();
    						// sc.register(selector,
    						// SelectionKey.OP_WRITE|SelectionKey.OP_READ,bb);
    						//等价于
    						key.interestOps(SelectionKey.OP_WRITE | SelectionKey.OP_READ);
    						//通常不会注册写事件,除非写的内容巨大,注册写事件后注意取消
    						
    					} else if (key.isWritable()) {
    						System.out.println("writable..");
    						SocketChannel sc = (SocketChannel) key.channel();
    						ByteBuffer att = (ByteBuffer) key.attachment();
    						if (att.hasRemaining()) {
    							int count = sc.write(att);
    							System.out.println("write:" + count + " byte,hasRemain:" + att.hasRemaining());
    						} else {
    							//写完后取消可写事件,仅监听可读事件
    							key.interestOps(SelectionKey.OP_READ);
    						}
    					}
    				}
    			}
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    	public static void log(ByteBuffer buf){
    		try {
    			System.out.println(new String(buf.array(),0,buf.limit(),"utf8"));
    		} catch (UnsupportedEncodingException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    	public static void main(String[] args) {
    		new NIOS().start(802);
    	}
    }
    

    JAVA NIO 笔记(1)

    躲猫猫社团团长 http://t.sina.com.cn/coolria

  • 相关阅读:
    .net core Ocelot Consul 实现API网关 服务注册 服务发现 负载均衡
    .net core grpc 实现通信(一)
    Shell脚本
    LNMP学习内容总结①
    2018/12/18学习内容摘要
    2019/12/16学习内容摘要(Vim)
    第一周进度及学习总结
    2019/12/12学习内容摘要(Linux系统用户与用户组管理②)
    2019/12/13学习内容摘要(Linux磁盘管理①)
    2019/12/11学习内容摘要(Linux系统用户与用户组管理①)
  • 原文地址:https://www.cnblogs.com/yangyh/p/2200469.html
Copyright © 2011-2022 走看看