2017-07-03 8 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) 
      } 
     } 
    } 
} 

私はSocketChannelを作成し、それをセレクタに登録し、Objectをキーにアタッチします。java nioのselectionKey.attachment()に関するバグはありますか?

最初のOP_CONNECTイベントを受け取ったときに、正常に添付ファイルを取得できます。 次のOP_READイベントで、attachment()はnullを返しますか?

なぜですか?

+0

使用している言語を示すタグを含めることができます。 – matt

+0

私は鍵を印刷します、それは鍵が同じものであることを示します。 – Tony

+0

問題を引き起こしているラインはどれですか? –

答えて

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

これは新しいSelectionKeyで、新しい登録を作成します。この場合nullには、あなたが1を供給していなかったとして。以前の添付ファイルを保存したい場合は、新しい引数でinterestOps()を呼び出すか、以前と同じ添付ファイルオブジェクトでregister(Selector, int, Object)を呼び出してください。

ただし、接続コードは無意味です。チャネルを非ブロッキングモードにしてから、本質的にブロッキングモードを実行すると、睡眠中にハードに接続されます。チャネルをブロックモードにしておけば、接続する必要がある場合はを非ブロックモードにして、選択ループを開始します。しかし、多くのサーバーに接続する予定がある場合や、たくさんの接続(スパイダーのような)があるサーバーを接続する場合を除いて、クライアントのノンブロッキング、つまりNIOの問題点は、常に私を逃げてきました。

関連する問題