2014-09-02 64 views
0

我是新來的NIO我理解異步套接字的概念,但我對非阻塞部分感到困惑。如何java-nio是非阻塞混淆

我正在使用java的NIO選擇器。我的服務器代碼是

public class EcoNonBlockingIOServer_7 { 
public static int PORT_NUMBER = 5555; 

public static void main(String[] argv) throws Exception { 
    new EcoNonBlockingIOServer_7().go(argv); 
} 

public void go(String[] argv) throws Exception { 
    int port = PORT_NUMBER; 
    if (argv.length > 0) { // Override default listen port 
     port = Integer.parseInt(argv[0]); 
    } 
    System.out.println("Listening on port " + port); 
    // Allocate an unbound server socket channel 
    ServerSocketChannel serverChannel = ServerSocketChannel.open(); 
    // Get the associated ServerSocket to bind it with 
    ServerSocket serverSocket = serverChannel.socket(); 
    // Create a new Selector for use below 
    Selector selector = Selector.open(); 
    // Set the port the server channel will listen to 
    serverSocket.bind(new InetSocketAddress(port)); 
    // Set nonblocking mode for the listening socket 
    serverChannel.configureBlocking(false); 
    // Register the ServerSocketChannel with the Selector 
    serverChannel.register(selector, SelectionKey.OP_ACCEPT); 
    while (true) { 
     // This may block for a long time. Upon returning, the 
     // selected set contains keys of the ready channels. 
     int n = selector.select(); 
     if (n == 0) { 
      continue; // nothing to do 
     } 
     // Get an iterator over the set of selected keys 
     Iterator it = selector.selectedKeys().iterator(); 
     // Look at each key in the selected set 
     while (it.hasNext()) { 
      SelectionKey key = (SelectionKey) it.next(); 
      // Is a new connection coming in? 
      if (key.isAcceptable()) { 
       ServerSocketChannel server = (ServerSocketChannel) key.channel(); 
       SocketChannel channel = server.accept(); 
       registerChannel(selector, channel, SelectionKey.OP_READ); 
       sayHello(channel); 
      } 

      // Is there data to read on this channel? 
      if (key.isReadable()) { 
       readDataFromSocket(key); 
      } 
      // Remove key from selected set; it's been handled 
      it.remove(); 
     } 
    } 
} 

現在我的查詢是:

  1. 如果註冊成爲我們與它總是被封鎖在selector.select(任何操作選擇的頻道)它再怎麼是非阻塞。

  2. 如果我們承認它使用OP_ACCEPT作爲鍵並相應地映射通道但是鍵值是可以接受的我將這個通道選擇器修改爲OP_READ,因爲它已經被接受。讀事件上selector.select()它再次塊

*請糾正我的理解,如果我錯*

+0

此鏈接可能會幫助你。 http://www.javaworld.com/article/2078654/java-se/five-ways-to-maximize-java-nio-and-nio-2.html – 2014-09-02 11:58:59

回答

0

如果我們在任何操作註冊選擇一個通道,都能得到,在selector.select()上阻塞,然後它是如何阻塞的。

select()正在阻塞。在無阻塞通道本身每一次操作是非阻塞的,即read()write().

如果我們承認它使用OP_ACCEPT爲重點,並相應地,但再次映射渠道在關鍵的是可以接受的我正在修改該通道選擇器OP_READ因爲它已經被接受了。

非常困惑。其興趣操作== OP_ACCEPT是監聽套接字的頻道。信道您接受從偵聽套接字是一個連接的插座,並且它是這個插座您放入非阻塞模式,與OP_ACCEPT寄存器等

上selector.select它再次塊()讀事件

正確的,但它並不在read()write()accept()finishConnect()阻塞。使用選擇器實際上稱爲多路複用 I/O:您在單個操作中同時等待多個通道和多個事件。

+0

Thanx EJP ...我認爲你是對的它可能沒有被阻止讀取和寫入它應該再次被阻止下一次連接OP_ACCEPT – 2014-09-02 13:46:49

+0

不,它僅在select()中阻塞。它告訴你下一次嘗試什麼非阻塞操作:read(),write(),accept(),finishConnect()。 – EJP 2014-09-02 22:16:35