Foros del Web » Programación para mayores de 30 ;) » Java »

DataInputStream read

Estas en el tema de DataInputStream read en el foro de Java en Foros del Web. Hola a todos, Tengo que implementar un proxy web en Java. Y tengo un pequeño problemilla con los sockets. Cuando conecto al servidor web, envio ...
  #1 (permalink)  
Antiguo 26/10/2007, 07:37
 
Fecha de Ingreso: abril-2006
Mensajes: 76
Antigüedad: 18 años
Puntos: 0
Mensaje DataInputStream read

Hola a todos,

Tengo que implementar un proxy web en Java. Y tengo un pequeño problemilla con los sockets. Cuando conecto al servidor web, envio la cabecera HTTP del cliente y espero la respuesta de la siguiente manera:

do
try
{
if ( servidor.isConnected() )
{
contador = datos_in_servidor.read( buffer );
if ( contador > 0 )
{
datos_out_client.write( buffer );
}
}
}
catch(Throwable e )
{
System.err.print("Error lectura datos servidor:" + e.getMessage() );
contador = 0;
}
while ( contador > 0 );


datos_in_servidor es la instancia de un DataInputStream del socket del servidor, que funciona perfectamente. La teroria dice que al hacer datos_in_servidor.read( buffer ) retorna el nº de bytes que se ha leido, 0 o -1.

En mi caso la primera vez que entra en el read me devuelve 417 bytes (por ejemplo) y en teoria ha acabado la connexion porque ya no existen mas datos.

Como hago el bucle, vuelve a realizar el read por segunda vez, pero el read no me devuelve -1 (no hay mas datos) y tengo que poner un timeout para saltar del bucle. La pregunta és como se detecta que no existen más datos sin realizar timeouts?!?!?
  #2 (permalink)  
Antiguo 26/10/2007, 10:13
Avatar de chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 19 años, 7 meses
Puntos: 454
Re: DataInputStream read

Hola:

Debes tener en cuenta varias cosas:

Si hay datos, read() devuelve el número de datos leídos, pero eso no implica que haya leído todos los datos disponibles. Deberías meter eso en un bucle hasta que hayas leído la cantidad de datos que esperas.

Se devuelve 0 si en el otra lado cierran la conexión. Si recibes un cero, debes a tu vez cerrar la conexión, puesto que en el otro lado han cerrado.

Se devuelve -1 si hay un error, NO si no hay más datos. Si hay un error -se devuelve -1- debes tratar de recuperar la conexión. Si el socket está abierto y no hay más datos, la llamada a read() se queda bloqueada hasta que haya datos, el otro lado cierre la conexión o salte un error.

Lo suyo es que crees un hilo con un blucle para read(), dejándole que se quede bloqueado si hace falta.

Se bueno.
__________________
Apuntes Java
Wiki de Programación
  #3 (permalink)  
Antiguo 31/10/2007, 10:18
 
Fecha de Ingreso: abril-2006
Mensajes: 76
Antigüedad: 18 años
Puntos: 0
Re: DataInputStream read

No me acaba de ir bien esta solución y he modificado la forma de leer los datos. Ahora leo todos los datos a nivel de byte. Te pongo otro ejemplo a ver si damos en el clavo.

Tengo un clase con un ServerSocket que espera una connexión y al recibirla crea un thread para atender al cliente. Para leer la petición HTTP del cliente realizo el siguiente codigo:

/* Creamos streams de connexión */
socket_cliente.setSoTimeout( TIMEOUT_LECTURA_CLIENT );
in = new DataInputStream( socket_cliente.getInputStream() );

Ahora leo los datos en un bucle:

private boolean leer_peticion( )
{

byte actual = 0;
byte anterior = 0;
while ( true )
{
byte[] linea = new byte[ MAX_STRING ];
int i = 0;
try
{
while ( ( anterior != CR ) && ( actual != LF ) )
{
anterior = actual;
actual = in.readByte();
linea[i++] = actual;
}
String campo = new String( linea , 0 , i-2 );
peticion.AddHeader( campo );
anterior = actual = 0;
}
catch ( EOFException e)
{
break;
}
catch ( IOException e )
{
System.err.println("Error:" + e.getMessage() );
break;
}
}
return true;
}

Como se puede ver entro en un bucle infinito (dentro de un hilo), hasta que leo todos los datos. El problema que tengo es que siempre salgo del bucle por timeout, nunca porque la función readByte() me devuelve EOFException que seria lo normal. Los datos los leo perfectamente, pero tengo que esperar siempre el timeout en lugar del EOF y no se porque. He comprobado que leo todos los bytes perfectamente uno a uno, pero en teoria al hacer un readByte() tocaria lanzar una exception EOF pero no la suelta y tampoco entrega ningun dato. Estoy un poco perdido. Si no realizo establezco un timeout de lectura, se me queda el hilo estancado en la funcion getBytes esperando nuevos datos, que nunca llengan claro.

Y esto mismo me pasa con la conexion que realizo al servidor. Pero este caso es mas simple de entender por no copiar todo el codigo.

Gracias por la ayuda.
Saludos.
  #4 (permalink)  
Antiguo 31/10/2007, 10:20
 
Fecha de Ingreso: abril-2006
Mensajes: 76
Antigüedad: 18 años
Puntos: 0
Re: DataInputStream read

Mejor pongo espacios en lugar de tabulaciones a ver si se ve mejor:
private boolean leer_peticion( )
{

byte actual = 0;
byte anterior = 0;
while ( true )
{
byte[] linea = new byte[ MAX_STRING ];
int i = 0;
try
{
while ( ( anterior != CR ) && ( actual != LF ) )
{
anterior = actual;
actual = in.readByte();
linea[i++] = actual;
}
String campo = new String( linea , 0 , i-2 );
peticion.AddHeader( campo );
anterior = actual = 0;
}
catch ( EOFException e)
{
break;
}
catch ( IOException e )
{
System.err.println("Error:" + e.getMessage() );
break;
}
}
return true;
}
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 07:37.