zoukankan      html  css  js  c++  java
  • java nio selector

    package com.selector;
    
    import org.junit.Test;
    
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.nio.ByteBuffer;
    import java.nio.channels.*;
    import java.util.Iterator;
    
    /**
     * Created by wang on 15-3-26.
     */
    public class SelectorSocket {
    
        private  int PORT = 8888;
        private ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
    
        @Test
        public void selectSocket() throws IOException, InterruptedException {
            System.out.println("listening on port "+PORT);
            ServerSocketChannel  serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.configureBlocking(false);
    
            ServerSocket serverSocket = serverSocketChannel.socket();
            serverSocket.bind(new InetSocketAddress(PORT));
    
            Selector selector = Selector.open();
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
    
            while (true){
                int n = selector.select();
                if (n == 0){
                    continue;
                }
    
                Iterator iterator = selector.selectedKeys().iterator();
                while (iterator.hasNext()){
                    SelectionKey  key = (SelectionKey) iterator.next();
                    if (key.isAcceptable()){
                        ServerSocketChannel  server = (ServerSocketChannel) key.channel();
                        SocketChannel socketChannel = server.accept();
                        registeChannel(selector,socketChannel,SelectionKey.OP_READ);
                        sayHello(socketChannel);
                    }
                    else if (key.isReadable()){
                        System.out.println(" ready to read");
                        readDateFromSocket(key);
                    }
                    iterator.remove();
                }
            }
        }
    
        private void registeChannel(Selector selector,SelectableChannel channel , int ops) throws IOException {
            channel.configureBlocking(false);
            channel.register(selector,ops);
        }
    
        private void sayHello(SocketChannel channel) throws IOException {
            byteBuffer.clear();
            byteBuffer.put("Hello , You Have Connected on Server !".getBytes());
            byteBuffer.flip();
            channel.write(byteBuffer);
        }
    
        private void readDateFromSocket(SelectionKey key) throws IOException {
            SocketChannel socketChannel = (SocketChannel) key.channel();
            Socket socket = socketChannel.socket();
            int count;
            byteBuffer.clear();
            while ((count = socketChannel.read(byteBuffer))>0 ){
                System.out.println("the buffer size is > 0");
                byteBuffer.flip();
                while (byteBuffer.hasRemaining()){
                    System.out.print((char)byteBuffer.get() );
                }
                System.out.println(" on Port :"+ socket.getPort());
                byteBuffer.clear();
            }
            if (count < 0){
                socketChannel.close();
            }
        }
    }

    java使用epoll默认会使用水平触发,即如果有事件发生,如果你不处理,那么下次还会触发

    但经过java 中EPollSelectorImpl实现之后有了小小的变化,如果某个事件发生,你不做任何处理,那么下次调用select的时候,虽然底层epoll仍然会返回事件,但上面的代码会判断本次事件和上次事件是否一致,如果是一样,java认为没有事件发生,如果要做到一致,必须将selectedKeys中的key删掉,否则会有差别,所以请注意selectedKeys删除的重要性!否则会死循环!

  • 相关阅读:
    git 命令速查及使用
    Centos6.5 LAMP环境源码包安装与配置,附安装包百度网盘地址 (转做笔记)
    不再为Apache进程淤积、耗尽内存而困扰((转))
    centos6.5 安装linux 环境
    window 配置wnmp(转下整理 ,全)
    mac下安装 xampp 无法启动apache (转,留用)
    Git命令行(转用于学习和记录)
    apache 局域网访问
    华为云GaussDB(for opengauss)如何绑定公网,实现putty的远程访问gaussdb数据库。
    Day9 打卡acwing.429 奖学金
  • 原文地址:https://www.cnblogs.com/juepei/p/4368510.html
Copyright © 2011-2022 走看看