1

編集 2名前を変更した質問

C# (サーバー) で記述された別のプロセスを開始する Java コード (クライアント) があります。C# プロセスには、ソケットのペアが渡されます (1 対listenon、1 対reply)。ソケットで接続を受信するとlisten、送信されたデータを処理し、replyソケット上の同じ IP に応答します。このプロセスは、継続的に実行され、接続をリッスンして応答するように設計されています。常に同じ IP に応答するため、もちろん多くの異なるクライアントからのメッセージを受け入れることができます。Java コードは、プロセスの応答をリッスンします。

非常に基本的なシステムですが、セットアップは 1 つの問題を除いて完全に機能しています。Process.waitFor()Java コードは、や などのメソッドを使用して、メッセージを送信する前にプロセスが実行されているかどうかを判断しますProcess.exitValue()。私が抱えている問題は、プロセスが開始してから数秒間、実際にメッセージを受信する準備ができていないことです。

私の質問は、サーバーがクライアントに起動したことを伝えるために使用する最適なパターンは何ですか? 私が考えたオプションは次のとおりです。

  1. Java プロセスは接続とテスト メッセージの送信を繰り返し試行し、応答を受信したときにのみ停止します
  2. C# プロセスは、開始時にクライアント IP のリストにブロードキャストします。
  3. Java は数秒待ってから接続を試みます。

私はオプション1に傾いていますが、上記のオプションのどれも特に好きではありません)。ここで使用する確立されたパターンはありますか?

この通信に既存のフレームワークを使用したくないことに注意してください。実際のメッセージは非常に単純で、メッセージ コードが両端に「手動で」エンコードされ、バイト ストリームにデコードされます。数百行のコードを節約するために、これを変更したくありません。

この種の「最善の方法」の質問は非建設的であるために閉じられる可能性があることは理解していますが、何時間もグーグル検索しても何も思いつきません. どんな助けやアドバイスも大歓迎です:)

編集 - もう少しコンテキスト

ほとんどのクライアント/サーバー関係では、クライアントが接続を試みるかなり前にサーバーを起動する必要がありますが (したがって、この問題を完全に回避できます)、ここでのセットアップは少し異なります。

この場合、クライアントは必要に応じてサーバーを効果的に起動します。さらに、サーバー プロセスが実行されていないことをクライアントが確認できる場合、クライアントは新しいプロセスを開始します。どちらの場合も、クライアントは最初のメッセージを送信する前に、(プロセスが開始されたときだけでなく) サーバーがいつ初期化されたかを知る必要があります。

4

1 に答える 1

2

私は一方の端をサーバーとして機能させます。そのサーバーは、新しい接続を受け入れる準備が整うまで、たとえば十分に初期化されるまで、新しい接続のリッスンを開始しないでください。

もう一方の端をクライアントとして機能させます。クライアントは、接続の準備ができるまで接続を試みるべきではありません。

この方法では、両端が十分に初期化されるまで接続できないため、どちらの端も初期化されていることを相手に伝える必要はありません。

この 1 つのソケット接続を使用して、メッセージを一方の方向に要求として送信し、他方の方向に応答として返すことができます。これはどちらの方向でもかまいません。

これは、同じサーバーに接続しようとする複数のクライアントをどのように処理しますか? また、非同期通信についてはどうでしょうか。

サーバーは、任意の数の接続を持つことができます。これは一般的な方法です。

単一のソケットを共有するということは、通信が同期している必要があることをどこかで読みましたが、間違っている可能性があります。

プレーン IO または NIO を使用している場合、書き込み/読み取りの呼び出しは同期的です。NIO2は非同期IO(またはそれをシミュレートするもの)の呼び出しを狂わせますが、余分な複雑さは私見を持っているかもしれない利点には値しません。

サーバーの起動時間が可変の場合、クライアントは接続前により長く待機する必要があることを知る方法がありません。

クライアントはこれを知る必要はありません。サーバーが起動するまで、N 秒ごとに接続を試みることができます。

于 2013-08-08T15:26:36.707 に答える