Я играю с проектом RserveCLI , который является клиентом .net, взаимодействующим со статистической средой R. Основная идея заключается в отправке данных / комментариев между этим клиентом .NET и сеансом R по протоколу TCP.
Одна ошибка, которую я и другие обнаружили, заключается в том, что магистраль больших данных, скажем, более 10 Кбайт, не может успешно передать передачу. Я нашел, но в следующем фрагменте кода:
// 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<object>();
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 + ".");
}
Причина в том, что код .NET работает слишком быстро, и сторона R не может отправить данные так быстро. Таким образом, строка приема после моего вставленного Thread.Sleep (500) не получает все данные. Если я подожду там некоторое время, тогда он сможет получить все данные. Но я не знаю, как долго.
У меня есть некоторая основная идея для решения этой проблемы, например, постоянно использовать this.socket.Receive () для получения данных, но если там нет данных. Receive будет блокироваться там.
У меня мало опыта в программировании сокетов, поэтому я прошу наилучшую практику для такого рода проблем. Спасибо!