Cómo pedirle al socket que espere a que lleguen más datos

Estoy jugando con el proyecto RserveCLI , que es un cliente .net que se comunica con el entorno estadístico R. La idea básica es enviar datos / recomendaciones entre este cliente .NET y una sesión R a través del protocolo TCP.

Un error que otros y yo encontramos es que el tronco de big data, por ejemplo, de más de 10k bytes, no se puede transferir con éxito. Encontré el pero en el siguiente fragmento de código:

// send the commend to R, then R will do some computation and get the data ready to send back int toConsume = this.SubmitCommand(cmd, data); var res = new List(); while (toConsume > 0) { var dhbuf = new byte[4]; if (this.socket.Receive(dhbuf) != 4) { throw new WebException("Didn't receive a header."); } byte typ = dhbuf[0]; // ReSharper disable RedundantCast int dlength = dhbuf[1] + (((int)dhbuf[2]) << 8) + (((int)dhbuf[3]) << 16); // ReSharper restore RedundantCast var dvbuf = new byte[dlength]; // BUG: I added this sleep line, without this line, bug occures System.Threading.Thread.Sleep(500); // this line cannot receive the whole data at once var received = this.socket.Receive(dvbuf); // so the exception throws if (received != dvbuf.Length) { var tempR = this.socket.Receive(dvbuf); throw new WebException("Expected " + dvbuf.Length + " bytes of data, but received " + received + "."); } 

La razón es que el código .NET se ejecuta demasiado rápido y el lado R no puede enviar los datos tan rápido. Así que la línea de recepción después de mi Thread.Sleep insertado (500) no obtiene todos los datos. Si espero algún tiempo allí, entonces puede obtener todos los datos. Pero no sé cuánto tiempo.

Tengo una idea básica para lidiar con el problema, por ejemplo, usar continuamente this.socket.Receive () para obtener datos, pero si no hay datos allí, recibirá bloques allí.

Tengo poca experiencia en la progtwigción de zócalos, por lo que solicito la mejor práctica para este tipo de problema. ¡Gracias!

Según los documentos :

Si está utilizando un Socket orientado a la conexión, el método Receive leerá tantos datos como estén disponibles, hasta el tamaño del búfer.

Por lo tanto, nunca se le garantiza que obtenga todos los datos solicitados en la llamada de recepción. Debe verificar cuántos bytes devolvió realmente la Recepción y luego emitir otra llamada de recepción para los bytes restantes. Continúe ese bucle hasta que obtenga todos los bytes que estaba buscando.

Por definición, TCP es un protocolo de transmisión, mientras que UDP se basa en mensajes. Si los datos que está tratando de recibir no contienen un recuento de bytes para el mensaje completo, o algún tipo de indicador de fin de mensaje, solo tendrá que hacer un bucle en el socket.Reciba hasta que haya expirado algún tiempo de espera arbitrario. En ese momento, verifique que los datos recibidos acumulados estén completos.