¿Alguien puede señalar el error en este código? Estoy recuperando algo de HTML con TcpClient. NetworkStream.Read() nunca parece terminar cuando habla con un servidor IIS. Si utilizo el proxy Fiddler, funciona bien, pero cuando se habla directamente con el servidor de destino, el ciclo .read() no saldrá hasta que la conexión salga con un error como "el servidor remoto ha cerrado la conexión".C# NetworkStream.Read oddity
internal TcpClient Client { get; set; }
/// bunch of other code here...
try
{
NetworkStream ns = Client.GetStream();
StreamWriter sw = new StreamWriter(ns);
sw.Write(request);
sw.Flush();
byte[] buffer = new byte[1024];
int read=0;
try
{
while ((read = ns.Read(buffer, 0, buffer.Length)) > 0)
{
response.AppendFormat("{0}", Encoding.ASCII.GetString(buffer, 0, read));
}
}
catch //(SocketException se)
{
}
finally
{
Close();
}
actualización
En el depurador, puedo ver toda la respuesta que viene a través inmediatamente y se añade a mis StringBuilder (respuesta). Simplemente parece que la conexión no se cierra cuando el servidor termina de enviar la respuesta o mi código no la detecta.
Conclusión Como se ha dicho aquí, lo mejor es aprovechar las ofertas del protocolo (en el caso de HTTP, la cabecera Content-Length) para determinar cuando una transacción se ha completado. Sin embargo, descubrí que no todas las páginas tienen una longitud de contenido establecida. Por lo tanto, ahora estoy usando una solución híbrida:
para todas las transacciones, establecer la cabecera de la solicitud
Connection
para "cerrar", por lo que el servidor no se le aconseja mantener el socket abierto. Esto mejora las posibilidades de que el servidor cierre la conexión cuando está respondiendo a su solicitud.Si está configurado
Content-Length
, utilícelo para determinar cuándo se completa una solicitud.De lo contrario, establezca la propiedad RequestTimeout de NetworkStream en un valor grande, pero razonable, como 1 segundo. A continuación, realice un bucle en
NetworkStream.Read()
hasta que a) se agote el tiempo de espera, o b) lea menos bytes de los que solicitó.
Gracias a todos por sus excelentes y detalladas respuestas.
Creo que deberías escribir la solicitud por partes. Esto te ayudará a depurar. – ChaosPandion
La escritura está funcionando bien; es la lectura la que está causando el problema. –
¿Está bloqueando en la llamada 'Lectura', o está obteniendo una ejecución infinita del ciclo? Si es el último, ¿qué está saliendo de la corriente? ¿Has verificado el contenido de 'respuesta'? – Aaronaught