0

私は人々がログインできるJavaアプリケーションを持っています(そしてデータベースでさまざまなことをすることができますが、それは重要ではありません)。.getInetAddress()を使用して、サーバーにログインしているユーザーのIPアドレスを取得できますが、スレッド間で正確に通信する方法がわかりません。この既存のプログラムにチャットサービスを追加しようとしています。

私のプログラムは標準のマルチスレッドサーバーを使用しており、clinetはシングルスレッドのAWTアクションリスナープログラムです。これを行うための最良の方法は何ですか?私のコードには、新しい「クライアントハンドラー」クラスを作成し、それを処理するための新しいスレッドを作成するmainを含むクラスが含まれています。現在、スレッド間通信はありません。スレッドは独自のソケットポートで生成され、サーバー上で独立して実行されます。私の以前の考えは次のとおりです。

ObjectInputStreamを使用してクライアントをブロック状態にし、クライアントがメッセージを受信するのを待ちます(ボタンが押されるのを待つのではなく)。ただし、クライアントがアクションを実行する(フィールドを編集する)場合は、ブロッキングI/Oを解放してメソッドを実行してから、プログラムのブロックされたI/Oの「待機」段階に戻ります。

これについてよくわからないこと:

  1. ブロッキングI/Oを呼び出すと、AWTActionListenerはブロッキングI/ Oのブロックを解除し、イベントハンドラーにジャンプしますか?

  2. クライアントがコード内にあり(ブロッキングInputStream上にない)、メッセージが送信される場合、サーバーは、プログラムがinputStreamに戻るまで待ってからメッセージを送信するか、メッセージを送信してキューを作成するかを認識します。またはさらに悪い現金、問題。

  3. サーバーはマルチスレッドです。Johnが192.168.1.100にあり、Larryが192.168.1.152にあり、JohnがLarryにメッセージを送信したい場合、スレッド処理*.100からスレッド処理*.152にメッセージを取得するにはどうすればよいですか。適切なソケットで適切なクライアントに出力できます。

私の他の考え(そしておそらくもっと簡単なもの)は、クライアントをマルチスレッド化し、別のポートでサーバーに接続し、まったく異なるソケット接続のセットを使用してイベントを処理することです。この場合、ブロッキングI / O待機を使用して、メッセージを取得して出力し、ブロッキングI/Oに戻ることができます。プロダクションコードとチャットコードの間の通信ミスに問題はなく、そのスタンスからはより良いですが、これは、接続するクライアントごとに異なるポートで2つの開いている接続が必要になることを意味します。このプログラムには、最終的には一度に数千人のユーザーが接続することになります。1つのアプリケーションですべてのサーバーポートを占有したくありません。

ポートをフラッディングしたり、通信エラーのリスクを冒したりせずにこれを行う他の方法はありますか?

4

1 に答える 1

1

クライアントは3つのスレッドを使用している必要があります。すべてのGUIインタラクションは、EDTから実行する必要があります。次に、ソケットInputStream用のスレッドとソケットOutputStream用のスレッドが必要です(どちらのブロックも潜在的にブロックできます)。メッセージを送信する場合、GUIスレッドはある種のスレッドセーフキューを使用してメッセージをOutputStreamスレッドに渡す必要があります。InputStreamスレッドによって受信されたメッセージはSwingUtilities.invokeLater、メッセージをGUIにプッシュするようなものを使用する必要があります。

ソケットとポートについてあなたが何を言っているのか正確にはわかりません。 サーバーに接続されているすべてのクライアントには、個別のソケット接続が必要です(個別のポートが必要になります)

于 2012-07-03T13:55:56.787 に答える