NIO SocketChannel simple demo

    技术2022-07-17  73

    /**  * nio 客户端  * @author Administrator  *  */ public class NIOClient implements Runnable{     private Logger  logger=LoggerFactory.getLogger("nio client");          private String host="127.0.0.1";     private int port=7001;     private SocketAddress server;     private Selector selector;      private SocketChannel sc;      private ByteBuffer buffer;           public NIOClient(String host,int port) throws IOException {             this.host=host;         this.port=port;         server=new InetSocketAddress(host,port);         selector=Selector.open();         buffer=ByteBuffer.allocate(100);     }     public NIOClient() throws IOException {                 server=new InetSocketAddress(host,port);         selector=Selector.open();         buffer=ByteBuffer.allocate(100);     }     private void connect() {         try {             logger.info("建立连接......."); if(sc!=null)sc.close();//断开重连             sc=SocketChannel.open();             sc.configureBlocking(false);             //sc.setOption(name, value);             //System.out.println(sc.getOption(StandardSocketOptions.SO_RCVBUF));             //sc.setOption(name, value)             //sc.setOption(StandardSocketOptions.SO_RCVBUF, 100);             //System.out.println(sc.getOption(StandardSocketOptions.SO_RCVBUF));             sc.socket().setSoTimeout(1000);             sc.socket().setReceiveBufferSize(100);             sc.connect(server);             sc.register(selector, SelectionKey.OP_CONNECT);                     }catch(IOException e) {             logger.info("连接失败:"+e.toString());         }     }     @Override     public void run() {         connect();         while(true) {             try {                 selector.select(1000);             } catch (IOException e) {                 logger.info("提取select信号失败:"+e.toString());               }             Iterator<SelectionKey> iter=selector.selectedKeys().iterator();             while(iter.hasNext()) {                 SelectionKey key=iter.next();                 iter.remove();                 if(key.isConnectable()) {                     try {                         sc.finishConnect();                         //sc.configureBlocking(true);                         write();                     }catch(Exception e) {                         logger.info("建立链接异常:"+e.toString());                          connect();                                             }                 }else if(key.isReadable()) {                     try {                         read();                     } catch (IOException e) {                         logger.info("读取数据异常:"+e.toString());  connect();                     }                 }                         }             }     }     private void write() throws IOException {         //buffer.clear();         buffer.put("welcome\n\r".getBytes());         buffer.flip();         while(buffer.hasRemaining()){              sc.write(buffer);         }         sc.register(selector, SelectionKey.OP_READ);     }     private void read() throws IOException {         buffer.clear();         //buffer.flip();         int flag=0,counter=0;         while(true) {             flag=sc.read(buffer);             counter+=flag;             //if(buffer.remaining()==0) break;             System.out.println(flag+" "+counter+" "+buffer.remaining());             if(flag==0)break;             //buffer.clear();         }         if(counter>0) {             buffer.flip();             byte[] read=new byte[counter];             //("缓冲区: "+readCounter+"  "+read.length);             buffer.get(read,0,read.length);             String expression=new String(read,"utf-8");             System.out.println(expression);                                     buffer.flip();             sc.write(buffer);         }     }         public static void main(String[] args) throws IOException {         NIOClient client=new NIOClient();         ExecutorService exec=Executors.newCachedThreadPool();         exec.submit(client);     } }

    socketchannel 关键参数说明:

    1、socket().setSoTimeout(1000) ;                   read 超时时间 单位毫秒 2、socket().setReceiveBufferSize(100);         read 缓冲区尺寸 

    3、ByteBuffer.clear();                                   buffer limit = capacity;position = 0;mark = -1

    4、ByteBuffer.flip();                                      buffer limit = position;position=0;mark = -1

    5、ByteBuffer.rewind()                                    buffer position=0 

    读流程: 

                1、buffer.clear();

                2、读取数据 flag=sc.read(buffer);   flag==0 结束读取 

                3、buffer.flip(); 处理数据

    Processed: 0.008, SQL: 9