0

ここでいくつかの質問と回答を読んだところ、telnetストリームが実際に閉じられることはないようです。DataAvailable()を使用しても戻りません。

完了するまでに非常に長い時間がかかったコードをいくつか継承しましたが、問題はtelnetサーバーであると考えました。ただし、コードがtelnetサーバーの応答を格納しようとするバイト[32757]があります。

次のようなもの:

Byte byteArray[] = new Byte[32757];
TcpClient sock = new TcpClient();
sock.GetStream().read(byteArray, 0 byteArray.length);

32757バイト以上がない場合、このコードは、バイト配列のサイズを構成するのに十分な空のパケットが送信されるまで待機すると想定しています。これは正しいです?

telnetサーバーが必要なものをすべて送信し終えたかどうかを確認する方法はありますか?telnetセッションの各「ページ」に表示される終了文字または文字列はありません。

このコードを修正する方法は、一度に数バイトを読み取り、それを文字列に追加し、文字列で終了文字または文字のセットをチェックして、見つかった場合は返すことだと考えていました。それ以外の場合は、さらにバイトを読み取り、それを文字列に追加して、もう一度確認します。

提案?

4

2 に答える 2

4

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を使用していると推測しています。

于 2009-05-01T11:03:20.953 に答える
3

いいえ、Stream.Read通常はすべてが読み取られるまで待機しません。また、ネットワークストリームの可能性はさらに低くなります。利用可能なデータを読み取るか、利用可能なデータが見つかるまでブロックしますが、それだけです。

次のいずれかを除いて、サーバーが送信しようとしているものを「終了」して送信するという実際の概念はありません。

  • a)送信する金額を事前に通知します
  • b)ある種の終了データでいつ終了したかを示します
  • c)接続を閉じます

ある種のタイマーを使用して、「読み取りの1つが5秒以上かかるまで読み取りを続ける」という効果を実現することができます。ただし、読み取りは引き続き行われることに注意してください。UI(またはその他)を更新するためにその時間を選択するだけです。これは非常にトリッキーなトピックであり、自分が何をしたいのか、そしてどのスレッドが何を処理するのかを自分の心(およびドキュメント!)で非常に明確にする必要があります。

別の方法は、に読み取りタイムアウトを設定することTcpClientですが、私はその経験がありません。おそらく、読んだときTcpClient.ReceiveTimeoutに結果をIOException適切に使用して処理する必要があるでしょうが、私はそれについて提供するアドバイスはありません。

于 2009-05-01T10:52:47.360 に答える