0

私はJavaマルチスレッドが初めてです。実際には、Socket プログラミングを使用して、LAN 上の Java で 2 人用のゲームを作成したいと考えています。その後、両方のプレイヤーがサーバーに接続したときにゲームが開始されるようにしたいだけです。私の GameServer は基本的にスレッドを使用しています。クライアントがサーバーに接続するときに誰がスレッドを作成するか。私の論理は、1 つのクライアントがサーバーとの接続を確立した後、このスレッドは 2 番目のスレッドが接続を確立するまで待機するというものです。2 番目のスレッドが正常に接続されたら。その後、両方のスレッドがライブになり、作業が開始されます。これは私の GameServer ロジックの接続部分です。

for(int i = 0; i <= 1; i++) {
    connectionSocket = welcomeSocket.accept();
    System.out.println("Connection has been accepted");
    no++;              
}

しかし、このコードは論理的に機能しません。アイデアや提案はありますか?

4

2 に答える 2

2

サーバーは、1 回の実行で 1 つのマッチのみをサポートします。サーバーを起動し、プレイヤーが接続し、ゲームをプレイします。別のゲームを開始するには、サーバーを強制終了して再起動する必要があります。これは、for ループが記述されているためです。

while(true) {
    playerOneSocket = welcomeSocket.accept(); // 1
    playerTwoSocket = welcomeSocket.accept(); // 2
    startNewMatch(playerOneSocket,playerTwoSocket);
}

public void startNewMatch(final Socket pOne, final Socket pTwo) {
    new Thread(new Runnable() {
        @Overrride
        public void run() {
            // pOne, pTwo variables visible here       
        }
      }).start();
}

(Any) サーバーは、新しいリクエストを受け入れるために常に自由である必要があります。そのため、単一の一致ロジックを処理する新しいスレッドで 2 つのソケットを渡します。startNewMatch 関数の引数は、run メソッド内で確認できるように最終的なものになっていますが、おそらく Thread を拡張する新しいクラスを作成し、それらをコンストラクターに渡したいと思うでしょう。それが役立つことを願っています。

編集:

while ループはメイン スレッドで実行されます。

public static void main(String[] args) 

関数を使用し、一致ごとに1 つの新しいスレッドを開始します。すべてのプレーヤーが自分のスレッドにいるわけではありません。それはリソースの無駄になり(EDIT^3 を参照)、そのようなコードを書くのは非常に重くなるからです。次のチュートリアルを見てください1 , 2 , 3

編集^ 2:

「しかし、私の混乱は、サーバーが現在プレーヤー1が通信していて、プレーヤー2が通信していることをどのように知るかということです.... Bczサーバーは両方のクライアントに対して同じソケットを持っています。」

いいえ、サーバーは常に指定されたポートでリッスンし、accept メソッドによって各要求に新しい接続 (ポート) が与えられます。

Java API doc はあなたの親友です - 特にServerSocketの場合は、次のように受け入れます。

このソケットへの接続をリッスンし、それを受け入れます。メソッドは、接続が確立されるまでブロックします

そうするとき

playerOneSocket = welcomeSocket.accept();

が実行され、playerOneSocket 変数で、プレーヤー 1 (サーバーとプレーヤーの両方に認識されている他のポート) への確立された「接続」が得られ、サーバーは同じポートで別の接続を受け入れることができます - 2 番目についても同じことが言えます。プレーヤー。たとえば、1345 はゲームのポートです。

P1: connect @ server:1345
accept method start - 1 行
目 SERVER: ポート 9999 で会いましょう
P1: connect @ server:9999
SERVER: ok connected
accept method end - 1 行
目 P2: connect @ server:1345
accept method start - line 2
SERVER: ポート 10000 で会いましょう
P2: connect @ server:10000
SERVER: ok connected
accept method end - 2 行目

編集^ 3:

このようにすることをお勧めします: まず、試合ごとに 1 つのスレッドで動作するようにし、次に (Tudor で示されているように) プレーヤーごとに 1 つのスレッドに移行します。ゲームは、より大きなネットワーク ラグ (インターネット経由など) でより応答性が高くなります。プレーヤー モデルごとに 1 つのスレッドを実行するには、優れたスレッド化とスレッド通信を理解する必要があります。このチュートリアルを参照してください。

于 2012-10-06T07:07:04.997 に答える
1

このようなことを意味していると思いますか?

class Player implements Runnable {

     private Socket socket;

     public Player(Socket socket) {
         this.socket = socket;
     }

     public void run() {
     }
}

List<Socket> players = new ArrayList<Socket>();
// accept two connections
for(int i = 0; i <= 1; i++)
{
     Socket playerSocket = welcomeSocket.accept();
     players.add(playerSocket);
}

// start one thread per connection
for(Socket socket: players) {
     new Thread(new Player(socket)).start();         
}
于 2012-10-06T08:23:00.947 に答える