lq1115
lq1115
2017-05-08 13:27

java nio selector怎么达到与Linux select一样的效果

  • select
  • java
  • nio
  • linux

前几天做了一个linux下的socket实验使用了select,可以让程序在不使用多线程的情况下,实现io的异步,也就是可以收数据,也可以发数据,但不阻塞。
于是我就想能不能移植到Java下来实现。结果我发现Java也有select类似的功能,但是我发现Java nio的Chanel无法对标准输入进行处理,要发数据的时候就会阻塞。
可能是我技术不够,我想问问大家Java nio到底能不能实现与linux select一样的效果?
package server;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Scanner;
import java.nio.ByteBuffer;
import java.nio.channels.Channel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;

public class ServerSock {
public ServerSock() {
// TODO Auto-generated constructor stub
try {
ServerSocketChannel server= ServerSocketChannel.open();
server.bind(new InetSocketAddress(InetAddress.getLocalHost(), 8899), 5);
System.out.println("服务器启动....");
Selector selector = Selector.open();
server.configureBlocking(false);
server.register(selector, SelectionKey.OP_ACCEPT);

        ByteBuffer buf = ByteBuffer.allocate(48);
        SocketChannel channel = null;
        while(true){
            int a=selector.select();

            Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator();
            while(keyIter.hasNext()){
                SelectionKey key = keyIter.next();
                if (key.isAcceptable()) {
                    channel = server.accept();
                    System.out.println("接受: ");
                    channel.configureBlocking(false);
                    channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
                }else if (key.isReadable()) {
                    System.out.println("读取:");
                    int bytesRead = channel.read(buf);
                    buf.flip();
                    String aString = new String(buf.array()).trim();
                    System.out.println(aString);
                    buf.clear();
                }else if (key.isWritable()) {
                    System.out.println("写入:");

                    Scanner scanner = new Scanner(System.in);
                    String b = scanner.nextLine();
                    buf.put(b.getBytes());
                    buf.flip();
                    channel.write(buf);
                    buf.clear();
                }
                keyIter.remove();
            }
        }

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
public static void main(String[] args) {
    new ServerSock();
}

}


  • 点赞
  • 回答
  • 收藏
  • 复制链接分享

3条回答

为你推荐