2010-05-19 6 views
14

Ich möchte eine SocketChannel verwenden und ein Timeout für seine Lese-/Schreibmethoden haben. Ich habe versucht, ein Timeout für den Sockel gesetzt, dass meine SocketChannel wie diese besitzt:Timeout für SocketChannel funktioniert nicht

channel.socket().setSoTimeout(TIMEOUT); 

aber das funktioniert nicht. Gibt es eine andere Lösung?

+3

SocketChannel unterstützt die setSoTimeout-Methode leider nicht direkt. Die Verwendung wird leider vernachlässigt. – casey

+5

SocketChannel implementiert die InterruptibleChannel-Schnittstelle, was bedeutet, dass Sie vor dem Aufruf Ihres read() -Aufrufs einen separaten Thread erstellen konnten, der andere Thread einen Timer gesetzt hat und nach Ablauf des Timers den Thread, in dem Ihr SocketChannel read() Anruf blockiert. Wenn der Aufruf read() zuerst zurückkehrt, könnte der Timer-Thread beendet werden. –

+4

@StevensMiller Und der Kanal wird geschlossen, und das Lesen wird 'ClosedByInterruptException.' werfen. Nicht sehr nützlich. Mir wurde gesagt, dass diese bizarre Implementierung durch das Verhalten von Linux bedingt ist. – EJP

Antwort

14

Entsprechend dieser article, SocketChannel wird nicht Timeout für seine Lesevorgang, aber Sie können diesen Effekt vom Lesen aus dem Kanal auf andere Weise erhalten.

Lesen von dem WrappedChannel wird Timeout entsprechend dem SocketTimeOut, das Sie festgelegt haben.

+0

gute Lösung. Java ist ... festgefahren –

+1

Dies ist nicht der richtige Weg, dies zu tun, nur ein Workaround. Der richtige Weg ist, Selector.select (timeout) in einer Schleife zu verwenden und das soTimeout/connectTimeout mit einem if-check zu überprüfen. – wzona

+0

'setSocketTimeout' ist jetzt' setSoTimeout', funktioniert aber genauso. –

-1

Sie könnten auch in Betracht ziehen, Ihren Kanal nicht blockierbar zu machen und nur System.currentTimeMillis() zu verwenden.

2

Wenn Sie mit der Verwendung von Java Selector vertraut sind, können Sie das Socket-Timeout mithilfe des Selektors selbst emulieren. Es ist hilfreich, sun.nio.ch.SocketAdaptor zu sehen.

Es sollte vorsichtig sein, Thread.interrupt() zu verwenden. SocketChannel ist InterruptibleChannel. Wenn Sie die Beschreibung von InterruptibleChannel lesen, führt Thread.interrupt() zu Schließen SocketChannel. Wenn Sie SocketChannel nach einem Timeout verwenden möchten, können Sie die InterruptibleChannel-Funktion nicht verwenden.