1

を通じて 2 つのクライアントを管理しているサーバーを取得しましたNetworkStream.Read

アプリケーション プロトコルは次のとおりです。

ClientMessage [128 Bytes] → サーバーからの応答 [128 Bytes]

サーバー側:MyTcpClient.GetStream().Read()クライアント側からのすべてのメッセージは正確に 128 バイトの長さですが、< 128 バイトのみを返すことは可能ですか?

このようなクライアント メッセージは、tcp/ip レイヤーの 1 つのパケットに収まるほど短いと思いますが、ある種の断片化やランダムが発生する可能性はありますか?

NetworkStream.DataAvailableこれに対して防御するための正しい属性はありますか?

何時間もスムーズに実行した後、奇妙なエラーや接続の切断が発生することがあります。

前もって感謝します。

4

2 に答える 2

1

簡潔な答え:

Readパケットが 1 回の呼び出しで送信され、Writeそれがネットワーク MTU よりも小さくても、1 回の呼び出しでパケット全体を受信するという保証はまったくありません。また、実際にループバック インターフェイスとの間で送信/読み取りを行っていたとしてもです。 . この動作については何もできません。

のドキュメントには、次のReadように明確に記載されています。

実装は、ストリームの終わりに達していない場合でも、要求されたよりも少ないバイト数を自由に返すことができます。

あなたができることは次のようになります(疑似コード)

While (true) {
    Read from stream
    If bytes read == 0 {
        Socket was closed (buffer should be empty here)
        Break
    }
    Append read data to persistent buffer
    While (buffer.Length >= 128) {
        Extract first 128 bytes from buffer (buffer length now reduced by 128)
        Process message
    }
}
于 2011-03-27T00:47:55.750 に答える
1

MyTcpClient.GetStream().Read() が 128 バイト未満しか返さない可能性はありますか

はい。Read( ) の呼び出しが 128 バイトを返すとは限りません。

ドキュメントを参照してください:

バッファーに読み取られた合計バイト数。これは、要求されたバイト数が現在使用できない場合は要求されたバイト数よりも少なくなる可能性があり、ストリームの終わりに達した場合はゼロ (0) になる可能性があります。

ストリームから適切に読み取る方法については、このリンクを参照してください

代わりに次のようなことを試してください: (長さ 128 のバイト配列を渡します)

private static void ReadWholeArray (Stream stream, byte[] data)
    {
        int offset=0;
        int remaining = data.Length;
        while (remaining > 0)
        {
            int read = stream.Read(data, offset, remaining);
            if (read <= 0)
                throw new EndOfStreamException 
                    (String.Format("End of stream reached with {0} bytes left to read", remaining));
            remaining -= read;
            offset += read;
        }
    }
于 2011-03-27T00:47:58.547 に答える