2010-05-19 15 views
14

Quiero usar un SocketChannel y tener un tiempo de espera para sus métodos de lectura/escritura. He tratado de establecer un tiempo de espera para el zócalo que posee mi SocketChannel así:El tiempo de espera para SocketChannel no funciona

channel.socket().setSoTimeout(TIMEOUT); 

pero que no funciona. hay alguna otra solucion?

+3

Desafortunadamente, SocketChannel no es compatible con el método setSoTimeout directamente. Su uso será tristemente desestimado. – casey

+5

SocketChannel implementa la interfaz InterruptibleChannel, lo que significa que puede crear un hilo separado antes de ingresar a su llamada read(), tener ese otro hilo establecer un temporizador y, cuando expire el temporizador, podría interrumpir el hilo en el que su lectura de SocketChannel() la llamada está bloqueando. Si la llamada de lectura() vuelve primero, puede hacer que mate el hilo del temporizador. –

+4

@StevensMiller Y el canal se cerrará, y la lectura arrojará 'ClosedByInterruptException'. No es muy útil. Me dijeron que esta implementación extraña es obligatoria por el comportamiento de Linux. – EJP

Respuesta

14

De acuerdo con este article, SocketChannel no tendrá tiempo de espera para su operación de lectura pero puede obtener este efecto leyendo del canal de otra manera.

SocketChannel socketChannel; 
socketChannel.socket().setSocketTimeout(500); 
InputStream inStream = socketChannel.socket().getInputStream(); 
ReadableByteChannel wrappedChannel = Channels.newChannel(inStream); 

lectura desde el wrappedChannel excederá el tiempo de espera según el socketTimeOut que haya configurado.

+0

buena solución. Java está ... atascado –

+1

Esta no es la forma correcta de hacerlo, solo una solución. La forma correcta es usar Selector.select (timeout) en un bucle y comprobar soTimeout/connectTimeout con if-check – wzona

+0

'setSocketTimeout' ahora' setSoTimeout', pero funciona de la misma manera. –

-1

También podría considerar hacer que su canal no sea bloqueable y simplemente usar System.currentTimeMillis().

2

Si está familiarizado con el uso de Java Selector, puede emular el tiempo de espera del socket utilizando el selector. Es útil ver sun.nio.ch.SocketAdaptor.

Se debe tener cuidado de usar Thread.interrupt(). SocketChannel es InterruptibleChannel. A medida que lee la descripción de InterruptibleChannel, Thread.interrupt() provoca que cierre SocketChannel. Si desea usar SocketChannel después de tiempo de espera, no puede usar la función InterruptibleChannel.

Cuestiones relacionadas