telnetストリームから大きなバイト配列への読み取りは、バイト配列がいっぱいになるまで待機しますか?
質問
ここでいくつかの質問と回答を読むと、telnetストリームが実際に閉じられることはないようです。 DataAvailable()を使用しても戻りません。
非常に長い時間がかかるコードを継承しましたが、問題はtelnetサーバーであると考えました。ただし、telnetサーバーの応答をコードが保存しようとするバイト[32757]があります。
次のようなもの:
Byte byteArray[] = new Byte[32757];
TcpClient sock = new TcpClient();
sock.GetStream().read(byteArray, 0 byteArray.length);
32757バイト以上ない場合、このコードは、バイト配列のサイズを構成するのに十分な空のパケットが送信されるまで待機すると想定しています。これは正しいですか?
Telnetサーバーが必要なものをすべて送信し終わったかどうかを確認する方法はありますか? telnetセッションの各「ページ」に目に見える終了文字または文字列はありません。
このコードを修正する方法は、一度に数バイトを読み取り、それを文字列に追加し、文字列で終端文字または一連の文字を確認し、見つかった場合に返すことだと考えていました。それ以外の場合は、さらにバイトを読み取って文字列に追加し、もう一度確認してください。
提案?
解決
いいえ、 Stream.Read
は通常、すべてを読み取るまで待機しません。また、ネットワークストリームの可能性はさらに低くなります。利用可能なデータをすべて読み取るか、利用可能なデータが一部になるまでブロックしますが、それがすべてです。
サーバーの実際の概念はありません"仕上げ&quot ;;次のいずれかの場合を除き、送信する内容を送信します。
- a)送信する量を事前に通知します
- b)何らかの終了データで終了したことを示します
- c)接続を閉じます
「読み取りの1つが5秒以上かかるまで読み取りを続ける」という効果を得るために、何らかのタイマーを使用することができます。ただし、読み取りはまだ行われていることに注意してください-UI(または何でも)を更新するのにその時間を選ぶだけです。それは非常にトリッキーなトピックであり、あなたは自分が何をしたいのか、そしてどのスレッドが何を処理するのかを自分の頭の中(そしてドキュメント!)で本当に明確にする必要があります。
別の方法として、 TcpClient
に読み取りタイムアウトを設定する方法がありますが、私はその経験はありません。おそらく TcpClient.ReceiveTimeout
を読み取り、結果の IOException
を読み取り時に適切に処理しますが、提供するアドバイスはありません。
他のヒント
Jon Skeetsの説明に加えて、ちょっとしたヒント:
telnetはテキスト(行)ベースのプロトコルなので、byte []で読み取ると、テキストを再構成する必要があります。 TextReaderの方が良いでしょう:
System.IO.TextReader reader = new System.IO.StreamReader(
sock.GetStream(), Encoding.ASCII);
string line;
while ((line = reader.ReadLine()) != null) ...;
ここでは、telnetがASCIIを使用していると推測しています。