style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

comportamiento erratico

estoy revisando el siguiente codigo que es un socket que algunas veces se comporta de manera erratica, como que la trama que le llega de respuesta la corta no llega completa ..

    public String enviaData(String mensaje, int timeOut) throws IOException {
   
        String msn;
        int i;
        int longitud = mensaje.length();
        Socket socket = null;        
        try {
           
            socket = new Socket(ip, puerto);
            socket.setSoTimeout(timeOut);
            OutputStream os = socket.getOutputStream();
            InputStream is = socket.getInputStream();
            byte[] sbytes = converByte(mensaje, longitud);
            os.write(sbytes);
   
            int lenInput = 0;
            long time = System.currentTimeMillis() + timeOut;            
            try{              
            while (System.currentTimeMillis() < time) {
               
           
                lenInput = is.available();
                if (lenInput > 0) {
                    byte[] textoBytes = new byte[lenInput];
                    for (i = 0; i < lenInput; i++) {
                        textoBytes[i] = (byte) is.read();
                        texto = texto + (char) textoBytes[i];
                       
                    }
                    break;
                }
            }
            }catch(Exception e){
               System.out.println("EEROR:"+e.getMessage());
            }
            msn=texto;
        } catch (UnknownHostException ex) {
            throw new UnknownHostException(ex.getMessage());
        } catch (IOException ex) {
            throw new IOException(ex.getMessage() + " Error " + ip + " " + puerto);
        } finally {
            try {
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException ex) {
                throw new IOException(ex.getMessage() + " Error  " + ip + " " + puerto);
            }
        }
        return msn;
    }

 public byte[] StringToByte(String string) throws
            UnsupportedEncodingException {

        return string.getBytes(ENCODING);
    }    

    private byte[] converByte(String mensaje, int longitud) {
        byte[] mensajeAux = new byte[longitud];
        try {
            mensajeAux = StringToByte(mensaje);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(Transmision.class.getName()).log(Level.SEVERE, null, ex);
        }
        return mensajeAux;
    }

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

buffered streams

Dos cosas:

Envuelve los streams del socket en buffered streams para evitar esas broncas.

Después de escribir un mensaje completo, dale flush al output stream.

InputStream.available regresa

InputStream.available regresa la cantidad de bytes que se pueden leer de jalón, pero no el total, entonces si tu total es por ejemplo 2,000 y tu llamada regresó 1024 te van a quedar 976 bytes sin leer, porque solo les la cantidad reportada.

Si estás leyendo la respuesta de un servidor HTTP puedes leer hasta obtener -1. Si estás leyendo un protocolo propio ese protocolo debe de indicar cuando termina el mensaje, ya sea regresando un número mágico ( como -1 en HTTP ) o indicando la longitud del mensaje en el primer valor del paquete.

Aquí está un ejemplo de como leer HTTP hasta encontrar -1
Puedes usar try( Recurso e = algo ) {} para cerrar automáticamente el socket y los streams y dejar el manejo de timeout al socket en vez de intentar manejarlo con un while.

inputStream tiene un método para leer más de un byte a la vez, es muchísimo más rápido, lo escribiendo en un arreglo la cantidad de bytes que le indiques y te dice cuantos leyó ( si tu arreglo mide 1024 y leyó 10, te dice que leyó 10)

import java.io.*;
import java.net.*;
class Ejemplo {

    private String ip;
    private int port;
    private int BUFFER_SIZE=1024;
    private String ENCODING = "UTF-8";

    public String envia(String mensaje, int timeout ) throws IOException {

        try( Socket s = new Socket(ip, port);
             OutputStream out = s.getOutputStream();
             InputStream in = s.getInputStream();
         ) {
            s.setSoTimeout(timeout);

            out.write( mensaje.getBytes(ENCODING) );

            int numberOfBytesRead = -1;

            // almacen temporal mientras se lee la respuesta.
            ByteArrayOutputStream boas = new ByteArrayOutputStream();

            byte [] buffer = new byte[BUFFER_SIZE];
            while(( numberOfBytesRead = in.read(buffer)) != -1) {
                boas.write( buffer, 0, numberOfBytesRead );
            }

            return boas.toString(ENCODING);
        }
    }
    public static void main( String ... args ) throws IOException {
        Ejemplo e = new Ejemplo();
        e.ip = "example.org";
        e.port = 80;
        System.out.println(e.envia("GET / HTTP/1.0\n\n", 1000) );
    }
}

mejora v1

socket = new Socket(SERVER_IP,SERVER_PORT);
            socket.setSoTimeout(SERVER_TIMEOUT*1000);
            entrada = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            salida  = new PrintWriter(socket.getOutputStream(),true);
         
            salida.println(tramaEnvio);
            salida.flush();
           
            tramaRespuesta = entrada.readLine();
       
Imagen de ezamudio

println

PrintWriter.println creo que ya incluye flush.

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">