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删除的重要性!否则会死循环!

  • 相关阅读:
    hdu6199 gems gems gems dp+博弈
    codeforces 429 On the Bench dp+排列组合 限制相邻元素,求合法序列数。
    hdu6153 扩展kmp求一个字符串的后缀在另一个字符串出现的次数。
    hdu6149 Valley Numer II 分组背包+状态压缩
    hdu6125 Free from square 分组背包+状态压缩
    hdu1712 ACboy needs your help 分组背包
    hdu6121 Build a tree 模拟
    hdu6134 Battlestation Operational 莫比乌斯第一种形式
    hdu6143 Killer Names 容斥+排列组合
    将Long类型转为字母数字组合的jar包---Hashids
  • 原文地址:https://www.cnblogs.com/juepei/p/4368510.html
Copyright © 2011-2022 走看看