Socket NIO2 Problem mit AsynchronousSocketChannel beim Schließen

Grizzly

Top Contributor
Hallo alle zusammen, 🙂

ich kämpfe mit der Klasse [JAPI]AsynchronousSocketChannel[/JAPI] bzw. ihrem verhalten. Und zwar ist mir aufgefallen, dass beim Schließen derselbigen nicht in allen Fällen die Daten, die ich über diese geschrieben / abgesetzt habe, übertragen werden. In manchen Fällen kommen die letzten zur Übertragung übergebenen Daten bei der Gegenstelle einfach nicht an. Wenn ich einen Thread.sleep(1000); zwischen der letzten Übergabe und dem Schließen einbaue, funktioniert wunderbar. Dass das Problem nicht immer auftritt, wird wahrscheinlich an irgendwelchen Nebenläufigkeiten liegen, vermute ich einmal.

Um etwas mehr ins Detail zu gehen: Ich übergebe der write Methode des Channels die Daten inkl. einem [JAPI]CompletionHandler[/JAPI]. Dieser fragt nach einem erfolgreich Schreiben ab, ob alle Daten geschrieben wurde. Wenn nein, wird versucht den Rest zu versenden. Wenn ja, wird eine Queue abgefragt, ob noch weitere Daten anliegen und wenn ja, werden diese mit einem weiteren write Aufruf versendet. Holt sich der Handler ein spezielles Schließ-Paket aus der Queue, wird innerhalb des Handlers der Channel geschlossen und der Verarbeitung signalisiert, dass die Verbindung beendet wurde.



Hier ist ein Blog Eintrag, der ein ähnliches Problem bei [JAPI]AsynchronousFileChannel[/JAPI] beschreibt. Leider lässt sich die Lösung, so weit ich es gesehen habe, nicht auf [JAPI]AsynchronousSocketChannel[/JAPI] übertragen.
Niklas' Blog: Java 7: Closing NIO.2 file channels without loosing data



Hat jemand von Euch schon mit ähnlichen Problemen zu kämpfen gehabt?
 
Das Problem hab ich jetzt nicht direkt, weil meine Implementierung damit endet, das der Client die Verbindungen schließt wenn er fertig ist und zuvor eine "Abmeldung" schickt und der Server die Verbindung nur schließt, wenn der Client sich illegal verhält / zu viele Fehler produziert oder geblockt wird.

Ich könnte mir aber vorstellen, dass auch wenn dein Schreibvorgang als fertig angezeigt wird (der zu schreibene Buffer leer ist) evtl. noch was in einem VM Buffer u.O. nativen Buffer ist und noch nicht fertig geschickt wurde (der Versuch mit einem sleep() deutet stark darauf hin. (EDIT: ... da ja alles async. läuft) EDITENDE)

Als Lösung könntest du auf eine Bestätigung vom Client warten, dass alles angekommen ist oder eine "Shutdown Benachrichtigung" schicken und auf antwort warten, falls keine innerhalb von x Sekunden kommt automatisch schließen. Es ist ja nicht so, dass ein Verbindung, die bei NIO etwas länger aufbleibt einen großen Performanz Verlust darstellt.

EDIT2: Ich versuch mal ob ich das Problem repliziert kriege, interressiert mich auch...
EDIT3: Das Problem kann ich bestätigen... Eine Serverseitige Lösung hab ich dafür jetzt aber auch nicht... nur die Idee für die "Shutdown Benachrichtigung" oder halt abwarten...
 
Zuletzt bearbeitet:
Leider geht es in dem Fall um die Verarbeitung von HTTP Paketen. Da bleibt nur abwarten, da ich mich an den Standard halten muss. :-(
 
Ahso, das konnte ich aus deinem ersten Post ja nicht lesen. Vielleicht mal angucken wie das Problem in bekannten Frameworks, die HTTP unterstützten (netty & mina) gelöst wurde? Ich schreibe zwar beruflich Netzwerk Anwendungen, allerdings keine die HTTP benutzen/unterstützen.
 

Zurück
Oben