サーバーは、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 つのスレッドを実行するには、優れたスレッド化とスレッド通信を理解する必要があります。このチュートリアルを参照してください。