programar - messenger en java
¿Por qué nunca se llega al final de la secuencia de entrada utilizando Java Sockets? (3)
HTTP 1.1, admitido por todos los navegadores modernos, tiene una función llamada "keep-alive", o "persistent connections", en la cual los clientes pueden reutilizar por defecto una conexión HTTP 1.1 a un servidor para varias solicitudes (ver http: // www.w3.org/Protocols/rfc2616/rfc2616-sec8.html ). Por lo tanto, si está apuntando FF a http://www.google.com , la conexión a www.google.com:80 permanecerá abierta durante un tiempo, incluso si la primera solicitud se ha completado. Por lo tanto, no puede saber si su aplicación ha enviado todos los datos sin una comprensión básica del protocolo HTTP. De alguna manera puede eludir eso utilizando un tiempo de espera en la conexión, esperando que el cliente no se quede atascado en algún lugar y ese silencio en realidad signifique el final del bloque de datos. Otra forma sería reescribir los encabezados de respuesta del servidor, anunciar su proxy como compatible con HTTP 1.0, y no 1.1, impidiendo así que el cliente use conexiones persistentes.
Estoy escribiendo un proxy simple en Java. Tengo problemas para leer la totalidad de una solicitud determinada en una matriz de bytes. Específicamente, en el siguiente ciclo, la llamada a "leer" bloquea aunque el cliente haya enviado todos los datos que desea (es decir, nunca se llega al final de la transmisión). Como no puedo estar seguro de que sea el momento de comenzar a escribir la salida hasta que haya leído la totalidad de la entrada, esto está causando un poco de problema. Si elimino la conexión al servidor, finalmente se llega al final de la transmisión y todo se activa sin problemas (todos los datos del cliente, en este caso Firefox que solicita www.google.com, han sido leídos por el servidor). , y puede procesarlo según sea necesario, aunque obviamente no puede enviar nada al cliente).
public static void copyStream(InputStream is, OutputStream os) throws IOException
{
int read = 0;
byte[] buffer = new byte[BUFFER_SIZE];
while((read = is.read(buffer, 0, BUFFER_SIZE)) != -1)
{
os.write(buffer, 0, read);
}
return;
}
El InputStream proviene directamente del socket del cliente (getInputStream (), luego se almacena en el búfer); el OutputStream es un ByteArrayOutputStream.
¿Qué estoy haciendo mal?
Normalmente, en HTTP, el encabezado Content-Length
indica la cantidad de datos que debe leer de la transmisión. Básicamente le dice cuántos bytes siguen la doble línea nueva (en realidad, doble- /r/n
) que indica el final de los encabezados HTTP. Ver W3C para más información ...
Si no se envía un encabezado Content-Length
, puede intentar interrumpir la lectura después de que pase cierto tiempo sin que se envíen datos a través de la conexión, aunque eso definitivamente no es preferible.
(Supongo que va a procesar los datos que está leyendo de alguna manera, de lo contrario, podría escribir cada byte mientras lo lee)
Tenga en cuenta que no todas las conexiones tendrán un encabezado Content-Length
; algunos pueden estar usando Transfer-Encoding: chunked
donde la longitud del contenido está codificada e incluida como parte del cuerpo.