私はRserveCLIプロジェクト(これは統計環境Rと通信する.netクライアントです)で遊んでいます。基本的なアイデアはこの.NETクライアントとTCPプロトコルを介してRセッション。ソケットが多くのデータを待つようにする方法
他の人と私が気付いたバグは、大きなデータトランク、たとえば10kバイトを超えるものが転送を正常に行えないということです。私が見つかりましたが、次のコードスニペットに:
// 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)の後の受信ラインは、すべてのデータを取得しません。そこにある時間を待つと、すべてのデータを取得できます。しかし、私はどれくらいの時間がかかりません。
私はこの問題に対処するためにいくつかの基本的な考え方を持っています。たとえば、このソケットを使用してデータを取得するには、Receive()を使用します。
私はソケットプログラミングの経験が少ないので、この種の問題のベストプラクティスを尋ねています。ありがとう! docsによると
この問題の典型的な解決方法は、受信するたびに独自のバッファにデータを蓄積して解析し、処理するメッセージがあるかどうかを確認することです。 2つのメッセージが連続して送信されるケースも処理する必要があることに注意してください。 –