2011-08-09 6 views
1

私はソケットを使って作成したクライアント/サーバーアプリケーションを持っています。 問題は、いくつかの情報を要求するコマンドを送信し、返信を待つときにその返信が来るまでブロックすることです。これにより、双方向のリクエスト/応答を実装することが難しくなります。 私は一つの例を使って説明しましょう: クライアントは、サーバーのディレクトリ内のファイルを一覧表示することができますので、私はコードでそのようにいろいろ書い操作を行います。クライアント/サーバーの会話 - 間違っていますか?

クライアントコード: 1 - 送信要求コマンド:LS/ 2 - ブロックLSが応答するのを待つ。 3ファイルリストを取得します。

私がした理由は、クライアントがファイルを転送する必要があるためです。 1ファイルの転送要求を送信します。 2サーバが受け入れるかどうかを調べるためにread()をブロックします。 3そうした場合にのみ、ファイルを送信します。

それで、サーバーに何かを要求する機能を追加するまで、それは問題ありませんでした。 私のコードでは、クライアントは何かを要求し、応答を待つのをブロックすることができます。 サーバは、クライアントが待っているレスポンスに意味をなさないリクエストコマンドを送信することがあります。これは会話をねじ込むだろう。

1つの解決策は、決して応答をブロックしないことです。 私はリクエストコマンドを送信してから、サーバーからの任意の要求または応答を待つために戻ります。応答が到着したら、ファイルを送信します。 それで、どのリクエストがどのレスポンスであるかを知るために、各リクエスト/レスポンスのペアにIDのように追加する必要がありますか?

PS:ホスト間のネットワーク会話をどのように設計するか、ネットワークアプリケーションのデザインパターンについての本を読んだことはありません。

PS2:SRY私の悪い英語;)

+0

私はすべてのメソッドが(Javaで)そのようなものであるクラスクライアントを持っています:publicリスト listRemoteDir(String dir)は例外をスローします – fredcrs

答えて

0

あなたが探しているものは、サーバとクライアント間のアプリケーションレベルprotocolです。

最も簡単な方法は、サーバーが次に送信するものを先に伝えることです。メッセージの前にメッセージタイプバイトを入れてください。例えば、0とは、1というのは応答を意味します。それをswitchというステートメントに貼り付ければ完了です。

メッセージ長をそのヘッダーにも含めることをお勧めします。受信コードは、完全なメッセージを取得するためにネットワークからフェッチするバイト数を認識します。

+0

私は文字列デリミタを使用します\ r \ n ISO-8859-1でエンコードされています。双方向で行うと、リストのようなクライアントでメソッドを実装することができなくなります listRemoteDir(String dir)は私になりますか? – fredcrs

+0

区切られたメッセージも問題ありません。あなたはメッセージの先頭にメッセージ*タイプ*を入れる方法が必要です。たとえば、最初の単語/トークンをタイプとします。たとえば、HTTPで見てください - 最初のトークンはHTTPの "メソッド"です - 'GET'、' POST'などです。事実上メッセージタイプです。 –

+0

私はそれを試みます。また、クラス内の人々のメッセージを読んだこともありますが、それは良い練習ですか? – fredcrs

関連する問題