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

Problema con BufferedReader y readLine()

Estas en el tema de Problema con BufferedReader y readLine() en el foro de Java en Foros del Web. Hola, tengo un problema, un dispositivo GPS envía packetes en Hexadecimal a un servidor TCP. El problema está en que la función readLine() no detecta ...
  #1 (permalink)  
Antiguo 05/11/2014, 11:39
 
Fecha de Ingreso: febrero-2013
Mensajes: 119
Antigüedad: 11 años, 2 meses
Puntos: 2
Problema con BufferedReader y readLine()

Hola, tengo un problema, un dispositivo GPS envía packetes en Hexadecimal a un servidor TCP. El problema está en que la función readLine() no detecta el fin de línea del paquete y no acaba nunca, a veces coincide que el paquete contiene un fin de línea (convertido de Hex a ASCII) y por suerte se muestra como cadena recibida...

Cómo puedo solucionar este problema para que me detecte cada paquete individualmente y no se junten todos los paquetes enviados en el BufferedReader?

Gracias de antemano...

Dejo parte del código:

Código:
Socket connectionSocket = welcomeSocket.accept();
			
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
			
DataOutputStream outToClient =newDataOutputStream(connectionSocket.getOutputStream());
			
//Aquí se queda abierto hasta que por casualidad detecta un salto de línea y termina...
clientSentence = inFromClient.readLine();
			
System.out.println("Received: " + clientSentence);
  #2 (permalink)  
Antiguo 05/11/2014, 12:07
Avatar de Profesor_Falken  
Fecha de Ingreso: agosto-2014
Ubicación: Mountain View
Mensajes: 1.323
Antigüedad: 9 años, 8 meses
Puntos: 182
Respuesta: Problema con BufferedReader y readLine()

Buenas,

El readLine espera efectivamente el fin de linea, por lo que si llegan datos todos el rato sin fin de linea, efectivamente se quedará siempre ahí.
Tienes algún control sobre lo que envía el GPS? Que bytes envía como fin de paquete?
Yo creo que en este caso no puedes usar el readLine, sino que debes leer los bytes uno a uno y detectar manualmente la finalización de envío de paquetes.

Código Java:
Ver original
  1. int ch;
  2.     while ((ch == inFromClient.read()) != -1) {
  3. ....

Un saludo
__________________
If to err is human, then programmers are the most human of us
  #3 (permalink)  
Antiguo 05/11/2014, 12:25
 
Fecha de Ingreso: febrero-2013
Mensajes: 119
Antigüedad: 11 años, 2 meses
Puntos: 2
Respuesta: Problema con BufferedReader y readLine()

Cita:
Iniciado por Profesor_Falken Ver Mensaje
Buenas,

El readLine espera efectivamente el fin de linea, por lo que si llegan datos todos el rato sin fin de linea, efectivamente se quedará siempre ahí.
Tienes algún control sobre lo que envía el GPS? Que bytes envía como fin de paquete?
Yo creo que en este caso no puedes usar el readLine, sino que debes leer los bytes uno a uno y detectar manualmente la finalización de envío de paquetes.

Código Java:
Ver original
  1. int ch;
  2.     while ((ch == inFromClient.read()) != -1) {
  3. ....

Un saludo
Gracias por la respuesta! Verás, el GPS envía paquetes en Hexadecimal y cuando se almacenan en variable y se muestran se convierten a ASCII, al convertirlos de vuelta a HEX se visualiza el paquete correctamente, pero no existen bytes de fin de paquete. He consultado el manual del producto y no pone nada, como mucho pone la longitud del paquete, que dependiendo del caso, también es variable... Gracias por la ayuda
  #4 (permalink)  
Antiguo 05/11/2014, 13:38
Avatar de chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 19 años, 6 meses
Puntos: 454
Respuesta: Problema con BufferedReader y readLine()

Hola:

Cuando algo (el GPS en este caso), envía mensajes, los envía de forma que en recepción puedan separarse e interpretarse. Hay muchas formas de hacer esto y tendrías que ven el manual de tu GPS cual está usando.

Si los mensajes son caracteres de texto ascii, una forma válida es enviar un retorno de carro al final del mensaje. Pero parece que no es el caso.

Si los mensajes no son caracteres de texto ascii, sino bytes cualesquiera, lo habitual es que delante de cada mensaje de envíe una pequeña cabecera (un conjunto de bytes) que sirven para indicarte como leer el resto del mensaje. En tu caso, parece que parte de esa cabecera es la longitud del mensaje. También suele ser habitual que la cabecera contenga algún tipo de byte fijo (por ejemplo, oxFF) para identificar cuándo empieza una cabecera.

Si este último caso es el tuyo, deberías leer byte a byte buscando ese inicio de cabecera (el 0xFF en mi ejemplo, que no tiene que ser el real de tu GPS), leer entonces la cebecera (unos pocos bytes, los que diga el manual) y ahí obtener la longitud del mensaje que viene detrás. Lees entonces ese número de bytes para construir el mensaje. Si hay varios tipos de mensajes, también suele ser habitual que algún byte/s de la cabecera indique qué mensaje es.

Todo esto son ideas generales y habituales al enviar mensajes, sin ver el manual es difícil decirte el caso concreto.

Se bueno.
__________________
Apuntes Java
Wiki de Programación
  #5 (permalink)  
Antiguo 05/11/2014, 15:04
 
Fecha de Ingreso: febrero-2013
Mensajes: 119
Antigüedad: 11 años, 2 meses
Puntos: 2
Respuesta: Problema con BufferedReader y readLine()

Cita:
Iniciado por chuidiang Ver Mensaje
Hola:

Cuando algo (el GPS en este caso), envía mensajes, los envía de forma que en recepción puedan separarse e interpretarse. Hay muchas formas de hacer esto y tendrías que ven el manual de tu GPS cual está usando.

Si los mensajes son caracteres de texto ascii, una forma válida es enviar un retorno de carro al final del mensaje. Pero parece que no es el caso.

Si los mensajes no son caracteres de texto ascii, sino bytes cualesquiera, lo habitual es que delante de cada mensaje de envíe una pequeña cabecera (un conjunto de bytes) que sirven para indicarte como leer el resto del mensaje. En tu caso, parece que parte de esa cabecera es la longitud del mensaje. También suele ser habitual que la cabecera contenga algún tipo de byte fijo (por ejemplo, oxFF) para identificar cuándo empieza una cabecera.

Si este último caso es el tuyo, deberías leer byte a byte buscando ese inicio de cabecera (el 0xFF en mi ejemplo, que no tiene que ser el real de tu GPS), leer entonces la cebecera (unos pocos bytes, los que diga el manual) y ahí obtener la longitud del mensaje que viene detrás. Lees entonces ese número de bytes para construir el mensaje. Si hay varios tipos de mensajes, también suele ser habitual que algún byte/s de la cabecera indique qué mensaje es.

Todo esto son ideas generales y habituales al enviar mensajes, sin ver el manual es difícil decirte el caso concreto.

Se bueno.
La verdad que estoy empezando con esto de paquetes TCP y tal (se nota...). En efecto, el paquete enviado por el GPS tiene una cabecera fija en Hex (0x67 0x67) y a continuación la longitud del paquete... Estructura completa:

Header: 0x67 0x67
Protocol: 0x01
Length: 0x00 0x0A
Serial: 0x00 0x01
Device ID: 0x01 0x23 0x45 0x67 0x89 0x01 0x23 0x45
Language: 0x01

Gracias por la ayuda, me ha aclarado varios conceptos, seguiré investigando.

Etiquetas: socket, tcp
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 13:26.