Estoy escribiendo una aplicación cliente/servidor en C#, y está funcionando muy bien. Por ahora, todo funciona y es bastante robusto. Mi problema es que me encuentro con algunas demoras al enviar paquetes a través de la conexión.¿Forma más rápida de comunicarse usando TcpClient?
En el lado del cliente que esté haciendo esto:
NetworkStream ns = tcpClient.GetStream();
// Send packet
byte[] sizePacket = BitConverter.GetBytes(request.Length);
byte[] requestWithHeader = new byte[sizePacket.Length + request.Length];
sizePacket.CopyTo(requestWithHeader, 0);
request.CopyTo(requestWithHeader, sizePacket.Length);
ns.Write(requestWithHeader, 0, requestWithHeader.Length);
// Receive response
ns.Read(sizePacket, 0, sizePacket.Length);
int responseLength = BitConverter.ToInt32(sizePacket, 0);
byte[] response = new byte[responseLength];
int bytesReceived = 0;
while (bytesReceived < responseLength)
{
int bytesRead = ns.Read(response, bytesReceived, responseLength - bytesReceived);
bytesReceived += bytesRead;
}
(Izquierda a cabo la captura de alguna excepción, etc.) El servidor hace lo contrario, es decir, que bloquea en NetworkStream.Read() hasta que tenga en su conjunto solicitar, luego lo procesa y envía una respuesta usando Write().
La velocidad bruta de Write()/Read() no es un problema (es decir, enviar paquetes grandes es rápido), pero enviar varios paquetes pequeños, uno tras otro, sin cerrar la conexión puede ser terriblemente lento (retrasos de 50-100 ms). Lo extraño es que estos retrasos aparecen en las conexiones LAN con tiempos de ping típicos < 1 ms, pero no ocurren si el servidor se ejecuta en localhost, aunque el tiempo de ping sería efectivamente el mismo (al menos la diferencia no debería ser del orden de 100 ms). Eso tendría sentido para mí si volviera a abrir la conexión en cada paquete, causando mucho apretón de manos, pero no lo hago. Es como si el servidor entrara en estado de espera y fuera de sincronización con el cliente, y luego tropieza un poco, ya que restablece lo que esencialmente es una conexión perdida.
Entonces, ¿lo estoy haciendo mal? ¿Hay alguna forma de mantener sincronizada la conexión entre TcpServer y TcpClient para que el servidor siempre esté listo para recibir datos? (Y viceversa: a veces el procesamiento de la solicitud del cliente tarda unos pocos ms, y luego el cliente no parece estar listo para recibir la respuesta del servidor hasta que ha tenido unos minutos para despertar después de bloquear en Read() .)
¿Solo por curiosidad intentó usar un StreamReader? –
¿Alguna razón en particular por la que no usa [WCF] (http://msdn.microsoft.com/en-us/netframework/aa663324)? Este marco tiene todo lo que intenta hacer y más incorporado. – Jay
; por el contrario, IMO; WCF está muy hinchado, y la mayoría de la gente solo usa una pequeña fracción de él. Los sockets crudos a menudo están bien, y generalmente son significativamente más eficientes. –