2
        NetworkStream stream = socket.GetStream();

        if (stream.CanRead)
        {
            while (true)
            {
                int i = stream.Read(buf, 0, 1024);
                result += Encoding.ASCII.GetString(buf, 0, i);
            }
        }

TcpClient上記のコードは、別のスレッドで実行中にメッセージを取得するように設計されています。Readメソッドが -1 を返して、読み取るものがもうないことを示すまでは、メソッドは正常に動作します。代わりに、明らかな理由なしに実行中のスレッドを終了するだけです。デバッガーを使用して各ステップをトレースすると、その行の直後に実行が停止することが示されます。

try ... catchまた、あまり成功せずにカプセル化しようとしました。

何が原因でしょうか?

編集:試しました

        NetworkStream stream = socket.GetStream();

    if (stream.CanRead)
    {
        while (true)
        {
            int i = stream.Read(buf, 0, 1024);
            if (i == 0)
            {
                break;
            }
            result += Encoding.ASCII.GetString(buf, 0, i);
        }
    }

@JonSkeetに感謝しますが、問題はまだあります。スレッドはそのread行で終了します。

EDIT2:このようにコードを修正したところ、うまくいきました。

    while (stream.DataAvailable)
    {
        int i = stream.Read(buf, 0, 1024);
        result += Encoding.ASCII.GetString(buf, 0, i);
    }

問題は単純だと思います。十分に考えていなかっただけです。これを見てくれてありがとう!

4

3 に答える 3

5

いいえ、Stream.Read読み取るものが何もない場合は、-1 ではなく 0 を返します。

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

私の推測では、実際には例外はスローされておらず、スレッドは中止されていませんが、永遠にループしているだけです。デバッガーでステップスルーすると、これを確認できるはずです。何が起こっても、あなたの「幸せな」終了条件は決してヒットしません...

于 2012-05-10T06:02:45.323 に答える
3

ストリームから ASCII 文字を読み込もうとしているので、それを行うためのより簡単な方法として、次を見てください。

public IEnumerable<string> ReadLines(Stream stream)
{
    using (StreamReader reader = new StreamReader(stream, Encoding.ASCII))
    {
        while (!reader.EndOfStream)
            yield return reader.ReadLine();
    }
}

これはまさにあなたが望むものではないかもしれませんが、重要なポイントは次のとおりです。

  • a を使用しStreamReaderて、すべての面倒な作業を行ってください
  • while ループを使用し!reader.EndOfStreamて、ストリームをループします
  • reader.Read(buffer, 0, 1024)チャンクをバッファに読み込み、結果に追加したい場合は、引き続き使用できます。char[]これらはチャンクではなくチャンクになることに注意してくださいbyte[]。これはおそらくあなたが望むものです。
于 2012-05-10T06:12:43.300 に答える
1

単にブロックしているように見えます-つまり、ストリームの最後を待っています。正でない数を返すには、ストリームが閉じられている必要があります。つまり、呼び出し元はデータを送信しただけでなく、送信ソケットを閉じています。そうしないと、システムは「パケットが到着するのを待っている」ことと「ストリームの終わり」を区別できません。

発信者が 1 つのメッセージのみを送信している場合は、送信後に送信ソケットを閉じる必要があります (応答のために受信ソケットを開いたままにしておくことができます)。

発信者が複数のメッセージを送信している場合は、フレーミング アプローチを使用して個々のサブメッセージを読み取る必要があります。テキストベースのプロトコルの場合、これは通常「改行を探す」ことを意味します。

于 2012-05-10T06:11:52.663 に答える