validate - reader java
¿Se garantiza que Socket.getInputStream(). Read(byte[]) no se bloqueará después de que se lean al menos algunos datos? (1)
El JavaDoc para la clase InputStream dice lo siguiente:
Lee hasta len bytes de datos del flujo de entrada en una matriz de bytes. Se intenta leer tantos bytes como len, pero se puede leer un número más pequeño. La cantidad de bytes realmente leídos se devuelve como un número entero. Este método bloquea hasta que los datos de entrada estén disponibles, se haya detectado el final del archivo o se haya lanzado una excepción.
Esto corresponde a mi experiencia también. Ver por ejemplo el siguiente código de ejemplo:
Client:
Socket socket = new Socket("localhost", PORT);
OutputStream out = socket.getOutputStream();
byte[] b = { 0, 0 };
Thread.sleep(5000);
out.write(b);
Thread.sleep(5000);
out.write(b);
Server:
ServerSocket server = new ServerSocket(PORT);
Socket socket = server.accept();
InputStream in = socket.getInputStream();
byte[] buffer = new byte[4];
System.out.println(in.read(buffer));
System.out.println(in.read(buffer));
Output:
2 // Two bytes read five seconds after Client is started.
2 // Two bytes read ten seconds after Client is started.
La primera llamada para leer (buffer) bloquea hasta que los datos de entrada estén disponibles. Sin embargo, el método regresa después de que se leen dos bytes, aunque todavía hay espacio en el búfer de bytes, que corresponde con el JavaDoc que indica que ''Se intenta leer tantos bytes como len, pero se puede leer un número más pequeño ''. Sin embargo, ¿se garantiza que el método no se bloqueará cuando se lea al menos un byte de datos cuando el flujo de entrada proviene de un socket?
La razón por la que pregunto es que vi el siguiente código en el pequeño servidor web Java NanoHTTPD , y me pregunté si una Petición HTTP menor de 8k bytes (que la mayoría de las solicitudes) potencialmente podría hacer indefinidamente el bloque de subprocesos a menos que haya una garantía de que no se bloqueará una vez que se leen algunos datos.
InputStream is = mySocket.getInputStream();
// Read the first 8192 bytes. The full header should fit in here.
byte[] buf = new byte[8192];
int rlen = is.read(buf, 0, bufsize);
Editar :
Permítanme intentar ilustrar una vez más con un ejemplo de código relativamente similar. EJP dice que el método bloquea hasta que se haya señalizado EOS o haya llegado al menos un byte de datos, en cuyo caso se lee cuántos bytes de datos han llegado, sin bloquear nuevamente, y devuelve ese número , que corresponde al método JavaDoc for read (byte [], int, int) en la clase InputStream. Sin embargo, si uno realmente mira el código fuente, está claro que el método efectivamente bloquea hasta que el buffer esté lleno. Lo probé utilizando el mismo Cliente que el anterior y copiando el código de InputStream a un método estático en mi ejemplo de servidor.
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(PORT);
Socket socket = server.accept();
InputStream in = socket.getInputStream();
byte[] buffer = new byte[4];
System.out.println(read(in, buffer, 0, buffer.length));
}
public static int read(InputStream in, byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
}
else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
}
else if (len == 0) {
return 0;
}
int c = in.read();
if (c == -1) {
return -1;
}
b[off] = (byte)c;
int i = 1;
try {
for (; i < len; i++) {
c = in.read();
if (c == -1) {
break;
}
b[off + i] = (byte)c;
}
}
catch (IOException ee) {
}
return i;
}
Este código tendrá como resultado:
4 // Four bytes read ten seconds after Client is started.
Ahora, claramente, hay datos disponibles después de 5 segundos, sin embargo, el método aún bloquea el intento de llenar todo el buffer. Este no parece ser el caso con la corriente de entrada que Socket.getInputStream () devuelve, pero ¿está garantizado que nunca se bloqueará una vez que los datos estén disponibles, como dice JavaDoc, pero no como muestra el código fuente?
Sin embargo, ¿se garantiza que el método no se bloqueará cuando se lea al menos un byte de datos cuando el flujo de entrada proviene de un socket?
No creo que esta pregunta signifique nada. El método bloquea hasta que se señala EOS o cuando llega al menos un byte de datos, en cuyo caso se lee sin embargo cuántos bytes de datos han llegado, sin bloquear nuevamente, y devuelve ese número.
Vi el siguiente código en el pequeño servidor web Java NanoHTTPD
El código es incorrecto Hace la suposición no válida de que el encabezado completo se entregará en la primera lectura. Esperaría ver un bucle aquí, que bucles hasta que se detecte una línea en blanco.
Me preguntaba si una Petición HTTP menor de 8k bytes (que la mayoría de las solicitudes) potencialmente podría hacer que el hilo se bloquee indefinidamente a menos que haya una garantía de que no se bloqueará una vez que se lean algunos datos.
Nuevamente, no creo que esto signifique nada. El método se bloqueará hasta que haya llegado al menos un byte, o EOS. Período.