2011-01-03 9 views
1

私は、外部マシン上にあるサーバープログラムとの通信を含むWindows用のJavaプログラムを作成しようとしています。私のプログラムは、サーバーに正常に接続し、 、応答を待ちます。Javaクライアントサーバー送信バイト受信者が無期限に聴く

私はサーバが一度に1バイトずつ私にバイト(応答)を返していることを知っています。私はさまざまなメソッド(read、readByteなど)でDataInputStreamオブジェクトを使用しようとしましたが、そのメソッド(readLayLineなど)でBufferedReaderオブジェクトを使用しようとしましたが、すべてのリーダーオブジェクトと、すべて同じ問題に立ち向かう。

バイトが正常に読み取られています(1バイトまたはバイトが読み取られるたびに、それらをコンソールに出力できます)。問題は読者がいつ読書をやめるのか分からないことです。サーバーがすべてのバイトを送信しても、私の最後のリーダー関数は無限に多くのデータを待っているので、プログラムは読み取り関数でハングします。

この問題は、私が試したすべてのテクニックに影響するようです。私はシンプルなクライアントプログラムとサーバープログラムを使ってテストを実行しています。クライアントプログラムとサーバープログラムはそれぞれ40〜50行ほどあり、クライアントはサーバーに接続してバイトを送信します。私がサーバーリーダーのために試したすべてのテクニックでは、上記の同じ問題が発生します(すべてのデータを送信したにもかかわらず、サーバーはクライアントからの入力を待ってハングします)。

私は本当にこれについていくつかの助けが切望しています。このプログラムはすぐに終了することが重要です。この通信の問題を除いて基本的には完全です。どんな助けでも大歓迎です!最後に

-Rob

--EDIT--

、Iは、セグメントである(読み取られたメッセージのセグメントの数を追跡することにより、バイトの読み取りを終了するアルゴリズムに定住2つのヌル値:00で区切られ、期待されるセグメントの数(引数としてread関数に渡される)と比較します。それは理想的な方法ではありませんが、それは機能し、私はもうプログラムに取り組む時間がありません。

ありがとうございました。

+0

ストリームを終了していますか? – npinti

+0

クライアント・サーバー・テスト・プログラムでデータを送信した後、クライアント側でライター・オブジェクトをクローズしようとしましたが、それが機能しましたが、サーバーはランタイム例外を引き起こし、DataOutputStreamオブジェクトを作成しようとしたときクライアントに応答を書き込む。しかし、私が書こうとしている実際のプログラムでは、サーバが何をしているのか、していないのかを制御できません。 – Rob

+0

また、データの長さを前もって送信することはオプションではありません。私が接触しているサーバーはそうしないため、サーバーコードを制御できません。 – Rob

答えて

0

もう1つのオプション(それほど素晴らしいわけではありませんが、ダウンしている可能性があります)は、受信したデータを処理しようとすることです。たとえば、シリアル化されたオブジェクトを受け取っている場合は、シリアル化されたオブジェクトを逆シリアル化することができます。成功した場合は、すべてのデータを受け取りました。そうでない場合は、もう少し読んでみてください。

受信しているデータの種類について詳しく教えてください。データには、メッセージが完全であるかどうかを調べるために調べることができるものはありますか?

+0

プログラムは、実際にはOtway-Reesセキュリティプロトコルの実装です。 3人の関係者:ClientA、ClientB、Server。 AとBはお互いに通信したいので、サーバーを使って認証し、通信に使用できるセッションキーを提供します。最終学年の大学の割り当てです。私の実装は、講師のリファレンス実装と相互運用可能でなければなりません。渡されたメッセージは、NTエンコーディング(Null Terminated Encoding)を使用してエンコードされます。メッセージの各部分は00で終わります。しかし、メッセージにはさまざまな部分があります。うーん... – Rob

+0

あなたが部品の可変数を言うとき、到着しようとしている部品の実際の数については、プロトコルに以前の表示はありませんか? – DaveC

+0

さて、はい、実際はあります。それは良い点です。メッセージが適切に送信された場合、メッセージに固定された数のNTエンコードセグメントが存在するはずです。それは調べる価値があるが、私は助けを傾けるが、それはちょうど間違っていると感じる。私は本当に別のエンティティからデータを読み込むための汎用関数を持つことができるはずです。 – Rob

1

終了条件を定義します。

一般的な単純なケースの1つは、接続を閉じることです(これはP9100印刷プロトコルの定義です)。 readは-1を返します。

そうしないと、

  • 長さでデータを前に付けることができます。 nバイトが受信された後、サーバーは読み取りを停止します。
  • 専用バイトでデータを終了します。マーカーバイトが見つかると、サーバーは受信を停止します。

これは問題なのですか、誤解しましたか?

1

接続を閉じるにはサーバーが必要です。または、特別なバイト(たとえば、ゼロバイト)を使用して、サーバーのメッセージが終了したことをデータから伝える必要があります。データそのものの前のデータ

そうしないと、アプリケーションがデータの送信を完了して(次の要求を待っている)サーバーとそのデータの送信中にサーバーが一時停止していることの違いをアプリケーションが判断できなくなります。

0

したがって、アプリケーションを実行しても、応答データを別のスレッドで読み取ることができます。

メッセージが終了したことを実際に知る方法が他にない場合は、タイムアウトを使用できます。つまり、データを取得してから100ミリ秒または1秒間それ以上受信していない場合は、それをすべて持っていると思われるかもしれません。

メッセージの終わりを知る必要がないようにコードを書く方が良いでしょう。到着時にストリーミングイベントとして扱い、各「応答」を処理するだけです。

データがどのように戻ってくるかは、データの完成時を知る必要はないと思われます。

関連する問題