2013-12-23 26 views
8

Mein Server verwendet einen AsynchronousServerSocketChannel, der Clientverbindungen unter Verwendung einer CompletionHandler überwacht. Wenn eine Client-Verbindung akzeptiert wird, wird AsynchronousSocketChannel gelesen, wobei wiederum eine CompletionHandler verwendet wird, um die Daten ohne Zeitüberschreitung zu empfangen.Wie schließen Sie einen AsynchronousSocketChannel sauber?

So weit so gut, mein Client verbindet, schreibt Daten, die vom Server gelesen werden, der in der Lage ist, Daten über den gleichen Socket zurück an den Client zu senden.

Wenn mein Client beendet wird, ruft er AsynchronousSocketChannel.close() auf, um den Socket zu schließen. Wenn dieser Aufruf erfolgt, wartet der Server darauf, Daten aus dem Socket zu lesen.

ich den Anruf zu AsynchronousSocketChannel.close() auf dem Client erwartet hatte in einen Rückruf zu CompletionHandler.completed mit einer Leselänge von -1 auf dem Server zu übersetzen, was auf die Socket geschlossen worden war, aber der Rückruf ist CompletionHandler.failed mit folgenden Ausnahme:

java.io.IOException: The specified network name is no longer available. 
    at sun.nio.ch.Iocp.translateErrorToIOException(Iocp.java:309) 
    at sun.nio.ch.Iocp.access$700(Iocp.java:46) 
    at sun.nio.ch.Iocp$EventHandlerTask.run(Iocp.java:399) 
    at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:744)  

Wie sollte ein Client einen Socket schließen, damit er nicht als Fehler auf dem Server betrachtet wird?

Antwort

1

Die documentation on close sagt, dass es auf der anderen Seite AsynchronousCloseException oder ClosedChannelException verursacht.

Um completed(-1) zu verursachen, sollte der Klient shutdownInput anrufen.

Allerdings würde ich AsynchronousCloseException und ClosedChannelException als normales Herunterfahren behandeln, zusammen mit abgeschlossen (-1).

+1

Es sagt nichts über "die andere Seite". Beide Ausnahmen sollten als Programmierfehler behandelt werden, nicht als "normales Herunterfahren". – EJP

+0

Ich habe auf der Client-Seite den Aufruf von 'AsynchronousSocketChannel.shutdownInput' hinzugefügt, der tatsächlich einen Rückruf zu' CompletionHandler.completed' mit einer Leselänge von -1 auf dem Server verursacht. –

+0

Es ist eine Schande, dass die Client-Seite eine 'AsynchronousCloseException' bekommt, obwohl es nicht die sehr allgemeine' IOException' ist und weil der Client die Schließung initiiert hat, kann ich ein 'closing' Flag hinzufügen, um diesen Fehler zu ignorieren. –