2017-07-03 1 views
-1
fun main(args: Array<String>) { 
    val selector = Selector.open() 
    val sc = SocketChannel.open() 
    sc.configureBlocking(false) 
    sc.connect(InetSocketAddress(1234)) 
    val key = sc.register(selector, SelectionKey.OP_CONNECT) 
    println("key=$key") 
    key.attach(ClientAttachment()) 

    writeThread(sc) 

    while (selector.isOpen) { 
     if (selector.select() == 0) continue 

     val keys = selector.selectedKeys().iterator() 
     while (keys.hasNext()) { 
      val key = keys.next() 
      println("key=$key") 
      println("ac=${key.attachment()}") 
      keys.remove() 
      if (key.isConnectable) { 
       val c = key.channel() as SocketChannel 
       while (!c.finishConnect()) { 
        Thread.sleep(100) 
       } 
       println("连接服务器成功") 
       c.register(selector, SelectionKey.OP_READ) 
      } else if (key.isReadable) { 
       handleRead(key) 
      } 
     } 
    } 
} 

Je crée un SocketChannel et l'enregistre dans un sélecteur, puis attacher un objet à la clé. Lorsque je reçois le premier événement OP_CONNECT, je peux obtenir la pièce jointe avec succèsy a-t-il un bug sur selectionKey.attachment() dans java nio?

mais lors de l'événement OP_READ suivant, la pièce jointe() renvoie null?

pourquoi?

+0

Vous pouvez inclure une balise indiquant la langue que vous utilisez. – matt

+0

J'imprime la touche, cela montre que la clé est la même. – Tony

+0

Quelle ligne semble causer le problème? –

Répondre

1
c.register(selector, SelectionKey.OP_READ); 

Cela crée un nouvel enregistrement , avec une nouvelle SelectionKey: dans ce cas null, comme vous ne l'avez pas fourni un. Si vous souhaitez conserver la pièce jointe précédente, appelez simplement interestOps() avec de nouveaux arguments, ou appelez register(Selector, int, Object) avec le même objet pièce jointe que précédemment.

MAIS Votre code de connexion est inutile. Vous mettez le canal en mode non bloquant, puis vous exécutez essentiellement un mode de blocage connecter à la dure, avec sleeps. Il suffit de quitter le canal en mode blocage, faites le connecter, puis mettez-le en mode non-bloquant si vous le devez et démarrez la boucle de sélection. Mais le point de non-blocage, ou même NIO d'ailleurs, chez un client, m'a toujours échappé, sauf si vous prévoyez de vous connecter à beaucoup de serveurs, ou à un serveur avec beaucoup de connexions (comme une araignée).