2016-04-27 12 views
1

Warum erhalte ich eine Fehlermeldung über die Ausnahme abgebrochener Schlüssel? Kann mir bitte jemand helfen? Welcher Teil des Codes des Kunden ist falsch gelaufen? HierWarum bekomme ich eine CancelledKeyException?

java.nio.channels.CancelledKeyException 
at sun.nio.ch.SelectionKeyImpl.ensureValid(SelectionKeyImpl.java:73) 
at sun.nio.ch.SelectionKeyImpl.interestOps(SelectionKeyImpl.java:82) 
at viaNIO.clientasync2.write(clientasync2.java:130) 
at viaNIO.clientasync2.run(clientasync2.java:53) 
at java.lang.Thread.run(Thread.java:745) 

java.nio.channels.CancelledKeyException 
at sun.nio.ch.SelectionKeyImpl.ensureValid(SelectionKeyImpl.java:73) 
at sun.nio.ch.SelectionKeyImpl.readyOps(SelectionKeyImpl.java:87) 
at java.nio.channels.SelectionKey.isReadable(SelectionKey.java:289) 
at viaNIO.clientasync2.run(clientasync2.java:55) 
at java.lang.Thread.run(Thread.java:745) 

ist der Code für die Auftraggeber:

 while (!Thread.interrupted()) { 

      selector.select(); 

      Iterator<SelectionKey> keys = selector.selectedKeys().iterator(); 

      while (keys.hasNext()) { 
       SelectionKey key = keys.next(); 
       keys.remove(); 

       if (key.isValid()) { 
        if (key.isConnectable()) { 
         System.out.println("Connected to the server"); 
         connect(key); 
        } 
        if (key.isWritable()) { 
         System.out.println("Writing to the server"); 
         write(key); 
        } 
        if (key.isReadable()) { 
         System.out.println("Reading from the server"); 
         read(key); 
        } 
       } 
      } 
     } 

Hier ist der aktualisierte Code:

while (!Thread.interrupted()) { 

      selector.select(); 

      Iterator<SelectionKey> keys = selector.selectedKeys().iterator(); 

      while (keys.hasNext()) { 
       SelectionKey key = keys.next(); 
       keys.remove(); 

       if (key.isValid() && key.isConnectable()) { 
        connect(key); 
       } else { 
        if (key.isValid() && key.isWritable()) { 
         System.out.println("Writing to the server"); 
         write(key); 
        } 
        if (key.isValid() && key.isReadable()) { 
         System.out.println("Reading from the server"); 
         read(key); 
        } 
       } 
      } 
     } 

Dies ist auch mein Code für die Schreibmethode

private void write(SelectionKey key) throws IOException { 
    SocketChannel socket = (SocketChannel) key.channel(); 
    RandomAccessFile aFile = null; 
    try { 
     File f = new File("D:/test.rar"); 
     aFile = new RandomAccessFile(f, "r"); 
     ByteBuffer buffer = ByteBuffer.allocate(300000000); 

     FileChannel inChannel = aFile.getChannel(); 
     while (inChannel.read(buffer) > 0) { 
      buffer.flip(); 
      socket.write(buffer); 
      buffer.clear(); 
     } 
     aFile.close(); 
     socket.close(); 
     inChannel.close(); 
     Thread.sleep(1000); 

     key.interestOps(SelectionKey.OP_READ); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

Der Code für die Lesemethode

private void read(SelectionKey key) throws IOException { 
    SocketChannel channel = (SocketChannel) key.channel(); 
    ByteBuffer readBuffer = ByteBuffer.allocate(1000); 
    readBuffer.clear(); 
    int length; 
    try { 
     length = channel.read(readBuffer); 
    } catch (IOException e) { 
     System.out.println("Reading problem, closing connection"); 
     key.cancel(); 
     channel.close(); 
     return; 
    } 
    if (length == -1) { 
     System.out.println("Nothing was read from server"); 
     channel.close(); 
     key.cancel(); 
     return; 
    } 
    readBuffer.flip(); 
    byte[] buff = new byte[1024]; 
    readBuffer.get(buff, 0, length); 
    System.out.println("Server said: " + new String(buff)); 
    if (readCnt != 1) { 
     key.interestOps(SelectionKey.OP_WRITE); 
     readCnt++; 
    } else { 
     key.cancel(); 
     close(); 
    } 
} 

Der Code für die Methode connect

private void connect(SelectionKey key) throws IOException { 
    SocketChannel channel = (SocketChannel) key.channel(); 
    if (channel.isConnectionPending()) { 
     channel.finishConnect(); 
    } 
    channel.configureBlocking(false); 
    channel.register(selector, SelectionKey.OP_READ); 
} 

Antwort

1

Denn entweder connect() oder write() den Kanal geschlossen oder die Taste abgebrochen, bevor Sie zum isReadable() Test bekam. Sie müssen erneut testen isValid(). Sie müssen auch ein else nach dem isConnectable() Block, als op_connect nicht mit einem der OP_WRITE oder OP_READ Feuer entlang kann:

if (key.isValid() && key.isConnectable()) { 
    System.out.println("Connected to the server"); // see below 
    connect(key); 
} else { 
    if (key.isValid() && key.isWritable()) { 
     System.out.println("Writing to the server"); 
     write(key); 
    } 
    if (key.isValid() && key.isReadable()) { 
     System.out.println("Reading from the server"); 
     read(key); 
    } 
} 

Auch die Nachricht "Connected to the server" ist an der falschen Stelle. Sie sind dabei, Versuch, um die Verbindung abzuschließen: wenn und nur wennfinishConnect() zurückgibt true sind Sie tatsächlich verbunden.

+0

änderte ich bereits meinen Code so, wie Sie geraten, aber ich bekomme immer noch einen Fehler ‚java.nio.channels.CancelledKeyException \t bei sun.nio.ch.SelectionKeyImpl.ensureValid (SelectionKeyImpl.java:73) \t bei sun.nio.ch.SelectionKeyImpl.interestOps (SelectionKeyImpl.java:82) \t bei viaNIO.clientasync2.write (clientasync2.java:128) \t bei viaNIO.clientasync2.run (clientasync2.java:51) \t bei Java .lang.Thread.run (Thread.java:745) ' – jnapor

+0

So ist der Kanal geschlossen oder der Schlüssel wurde abgebrochen. Sie müssen Ihren neuen Code mit den Methoden 'connect() ',' write() 'und' read() 'posten. Bearbeiten Sie es in Ihre Frage. Warum überprüfen Sie die 'interestOps' erneut in der 'write() 'Methode? – EJP

+0

Ich habe bereits meinen Beitrag @EJP bearbeitet. Kannst du bitte helfen, wo mein Code schief gelaufen ist? Danke – jnapor