2010-01-25 15 views
0

Je convertis un code Java NIO à exécuter dans Scala et j'obtiens une erreur car le SelectionKey que j'appelle renvoie un SelectableChannel plutôt qu'un DatagramChannel, qui est une sous-classe de SelectableChannel et une instance que je déclare au début du code. Je ne suis pas venu à Scala de Java, donc ma connaissance de Java est vraiment très limitée. Il me semble que le code Java DatagramChannel channel = (DatagramChannel) key.channel(); typecasts le canal à un DatagramChannel. Est-ce ce que je dois faire dans le code Scala?Pourquoi une SelectionKey enregistrée dans un DatagramChannel renvoie-t-elle un SelectableChannel dans Scala mais pas Java?

Code Scala:

val channel = DatagramChannel.open() 
val selector = Selector.open() 
println("Attempting to bind to socket " + port) 
channel.socket().bind(new InetSocketAddress(port)) 
println("Bound to socket " + port) 
channel.configureBlocking(isBlocking) 
println("Attempting to registered selector") 
channel.register(selector, SelectionKey.OP_READ) 
println("Registered selector") 

println("Ready to receive data!"); 
while (true) { 
    try { 
    while(selector.select() > 0) { 
     val keyIterator = selector.selectedKeys().iterator(); 
     while (keyIterator.hasNext()) { 
     val key = keyIterator.next(); 
     if (key.isReadable()) { 
      val channel = key.channel(); // FIXME: returning a SelectableChannel instead of a DatgramChannel 
      var buffer: Array[Byte] = Array(); 
      val byteBuffer = ByteBuffer.wrap(buffer); 
      val sockAddress = channel.receive(byteBuffer); 
// ... 

Code d'origine Java:

channel = DatagramChannel.open(); 
selector = Selector.open(); 
System.out.println("Attempting to bind to socket " + port); 
channel.socket().bind(new InetSocketAddress(port)); 
System.out.println("Bound to socket " + port); 
channel.configureBlocking(isBlocking); 
System.out.println("Attempting to registered selector"); 
channel.register(selector, SelectionKey.OP_READ); 
System.out.println("Registered selector"); 
System.out.println("Ready to receive data!"); 
while (true) { 
    try { 
    while(selector.select() > 0) { 
     Iterator keyIterator = selector.selectedKeys().iterator(); 
     while (keyIterator.hasNext()) { 
     SelectionKey key = (SelectionKey) keyIterator.next(); 
     if (key.isReadable()) { 
      DatagramChannel channel = (DatagramChannel) key.channel(); 
      byte[] buffer = new byte[2048]; 
      ByteBuffer byteBuffer = ByteBuffer.wrap(buffer); 
      SocketAddress sockAddress = channel.receive(byteBuffer); 
// ... 

Répondre

2

SelectionKey.channel() retourne toujours un SelectableChannel. Le type assigné du canal n'est pas vraiment pertinent à ce stade, vous devrez donc le lancer.

+0

Ok, merci. 'val canal = key.channel(). asInstanceOf [DatagramChannel];' fait l'affaire. – pr1001

+0

ou: val canal = key.channel.asInstanceOf [DatagramChannel] –

+0

Est-ce que cette distribution est garantie? Que faire si le mauvais type de canal est sélectionné en raison d'une erreur de programmation? Serons-nous en train de regarder ClassCastExceptions? Ou des erreurs subtiles? – hexafraction