0

インターネットから、NetworkStream から巨大な文字列を読み取る方法を手に入れました。

 static NetworkStream ns = null;
 static StringBuilder sb = null;
 static byte[] buffer = null;
 static int position = 0;
 //.......................................
 //other codes skipped for simplicity
 //....................................... 
 private static string Read()
 {
        if (ns.CanRead)
        {
            sb.Clear();
            position = 0;
            while (ns.DataAvailable)
            {
                position = ns.Read(buffer, 0, buffer.Length);
                sb.Append(Encoding.Unicode.GetString(buffer, 0, position));
            }

            return sb.ToString().Trim();
        }
        else
        {
            return null;
        }
 }

ただし、巨大な文字列を NetworkStream に書き込む方法の例が見つかりません。

読むのと同じように、書くのに「対称的な」パターンはありますか?

前もって感謝します。

4

1 に答える 1

6

その読み取りコードは、多くの点で危険なほど間違っています。

  • このように静的変数を使用すると、マルチスレッド タスクにはどうしようもなく不向きになります。(単純化したからだといいのですが...)
  • 変数をnull以外の値に初期化することは決してありません-繰り返しますが、それが実際のコードではないことを願っています
  • プロパティを使用して、DataAvailableいつ「実行」する必要があるかを決定します。これは、パケットがストリームで遅延した場合、予想の半分のデータを読み取る可能性があるため、非常に危険です。
  • 常に使用しますEncoding.Unicodeが、これがエンコーディングの最良の選択になることはめったにありません
  • 常に整数の文字を読み取ると想定しています。読み取り間で 1 文字が分割された場合はどうなりますか? それがEncoder/Decoderクラスの目的です...しかし、とにかくここでそれらを実際に使用する必要はありません-以下を参照してください。

NetworkStreamをa StreamReaderfor reading と a StreamWriterfor writingでラップすることを強くお勧めします。それが彼らの目的です。次に、一度に 1 行ずつ、またはバッファーだけを読み取るかchar[]、ストリームの最後まで (「ソケットが閉じられるまで」を意味します) 読み取ることができます。これは、テキストのみのプロトコルでは問題ありません。

テキスト データとバイナリ データが混在するプロトコルを使用すると、作業はさらに困難になります。個人的には、メッセージに長さのプレフィックスを付けるプロトコルが好きです。これにより、目的のデータのみを読み取り、必要な変換を実行できます。

とにかく、このランダムな考えの選択がお役に立てば幸いです...さらに詳細な支援が必要な場合は、使用しているプロトコルの詳細を提供してください.

于 2010-07-27T07:18:06.077 に答える