ネットワーク経由でデータをストリーミングするときのランダムバイト損失

StackOverflow https://stackoverflow.com//questions/20011324

質問

私の問題は、ローカルLANネットワーク上で連続的なデータストリームをストリーミングするとき、ランダムバイトがプロセスで失われることがあることです。

今のとおり、コードはLAN上で約1027バイトまたは~40倍になるように設定され、時には(非常にまれな)1つ以上のバイトが失われます。

私をバッフルすることは、実際のバイトが「失われた」とは限らないことは、元のデータに関係なく0に設定されます。(方法でTCPを使っています)

これは送信コードです:

    public void Send(byte[] data)
    {
        if (!server)
        {
            if (CheckConnection(serv))
            {
                serv.Send(BitConverter.GetBytes(data.Length));
                serv.Receive(new byte[1]);
                serv.Send(data);
                serv.Receive(new byte[1]);
            }
        }
    }
.

と受信コード:

    public byte[] Receive()
    {
        if (!server)
        {
            if (CheckConnection(serv))
            {
                byte[] TMP = new byte[4];
                serv.Receive(TMP);
                TMP = new byte[BitConverter.ToInt32(TMP, 0)];
                serv.Send(new byte[1]);
                serv.Receive(TMP);
                serv.Send(new byte[1]);
                return TMP;
            }
            else return null;
        }
        else return null;
    }
.

空のバイトの送受信は、システムをSync Sortaに保つためのものです。 個人的に私は問題がシステムの受信側にあると思います。そのジェットを証明することができなかった。

役に立ちましたか?

解決

Receive(TMP)に4バイト配列があるため、4バイトの配列を入力しようとしているという意味ではありません。受信呼び出しは、1TMP.Lengthバイトの間のどこにでも配列に置くことができます。返されたintをチェックして、埋められた配列のバイト数を確認する必要があります。

ネットワーク接続は、ストリームベースのメッセージベースではありません。あなたがワイヤーに入れたバイトは、大きなキューに連結され、それが利用可能になるにつれて反対側に読んで読んでください。したがって、2つの配列1,1,1,12,2,2,2を送信した場合、受信側では、4バイトの配列でReceiveを3回呼び出して

を取得することが完全に可能です。

  • 1,1,0,0(受信元の2
  • 1,1,2,2(受信元の4
  • 2,2,0,0(受信元の2

だからあなたがする必要があるのはあなたがReceiveから戻ってきた値を見ることであり、あなたのバイト配列がいっぱいになっているまでループし続けます。

byte[] TMP = new byte[4];

//loop till all 4 bytes are read
int offset = 0;
while(offset < TMP.Length)
{
    offset += serv.Receive(TMP, offset, TMP.Length - offset, SocketFlags.None);
}
TMP = new byte[BitConverter.ToInt32(TMP, 0)];

//I don't understand why you are doing this, it is not necessary.
serv.Send(new byte[1]); 

//Reset the offset then loop till TMP.Length bytes are read.
offset = 0;
while(offset < TMP.Length)
{
    offset += serv.Receive(TMP, offset, TMP.Length - offset, SocketFlags.None);
}

//I don't understand why you are doing this, it is not necessary.
serv.Send(new byte[1]);

return TMP;
.

最後に、「ネットワークストリームがあなたを混乱させる」と言った、私は上記の問題を賭けても構わないと思っています、より低いレベルになることはそれらの複雑さを除去することはできません。これらの複雑な部分がなくなったら、それらを処理する必要はなく、ライブラリ内でそれを処理する3番手ライブラリを使用する必要があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top