0

質問があります。サーバーがあります。このサーバーは、複数のクライアントが接続できるようにマルチスレッド化されています。クライアントがサーバーに接続すると、他のクライアントのタスクを実行するためにスレッドにスローされます。

基本的に、クライアントは「グラフィックス」の正方形を画面に描画します。この正方形を画面上で移動すると(キーボードイベント、矢印キーを使用)、xとyのコードがサーバーに送信されて配列に配置されます。最初の接続でクライアントに与えられたクライアント番号に対応するインデックス。

私の問題は、xコードとyコードをサーバーに送信しないことです。接続したクライアントの数に関係なく、すべてが機能し、xコードとyコードをサーバーに送信して保存します。もちろん、プレーヤーが新しい動きをしたときも同様です。 、配列内の前のxおよびyは、新しいxおよびyコードで上書きされます。

私の問題は、各クライアント(そのクライアントを含まない)を他のクライアント画面に描画することです...

したがって、基本的に、クライアントの画面上で正方形を移動すると、すべての画面上で移動します(もちろんサーバーに接続されています)。idにはクライアントごとにマルチスレッドサーバーがあると思っていました。つまり、idには接続ごとに2つのスレッドがあります。しかし、2つのスレッドで同時にデータをやり取りしていると、ソケットが混乱します。さらに、クライアントが移動したときだけでなく、このxコードとyコードの配列を継続的に受信して、誰かが移動した場合に全員を更新するようにします。また、新しいxとyを追加で取り込み、配列に正しい変更を加えながら、サーバーが継続的にxとyのコード配列をクライアントに送信するようにします。

基本構造を自分の持っているものに投稿します。誰かが私を正しい方向に向けることができた場合、別のサーバーソケットを作成し、クライアントで別のソケットを受け入れる必要がありますか?

そのため、接続ごとに複数のスレッドを作成する方法について混乱しています。ありがとうございました!:)

クライアント側:

//some methods are taken out 
// All imports imported here
public class ClientSquares extends JFrame implements Runnable{
    //variables here
    public void run(){
        try{
            while(true){
                 //other calls here (just for client)
                if(online == true && (x != oldX || y != oldY)){
                    //only sends its X and Y cords when the player makes a move.
                    checkAbility check = new checkAbility(x, y, clientNum, alpha);
                    check.checking();
                    //the Checking method in checkAbilities class just assigns a client           
                    //number to this client, which is stored in a int variable called  
                    //clientNum, once its assigned then it can send its x and Y cords
                }
                Thread.sleep(3);
           }
       }catch(Exception e){
        System.err.println("Error in implemented Runnable's method Run");
       }
  }

//paint method stuff here, paints the the clients square, and everyone else (according 
//to the array received from the server.

  public static void main(String [] args){
       //thread for client started here
  }
  public ClientSquares(){
    //standard jFrame here, creates standard x and y cords here

    //This is how im making my connection with the server right now.. further 
    //communication (in getting client number, and x and y cords are done in a 
    //different class)
    try{
        sock = new Socket("localhost",4000); 
        OS = new DataOutputStream(sock.getOutputStream());
        IS = new DataInputStream(sock.getInputStream());
        OIS = new ObjectInputStream(sock.getInputStream());
        roomNum = IS.readInt();
        players = new int[roomNum + 1][2];
        defaultPlayerArray();
        online = true;
    }catch(Exception e){
      System.err.println("Cannot connect to the Server, check and make sure that the" + 
                         " correct ip is entered, and also check if port 777 is open" +
                         " you will now enter offline mode.");
        online = false;
    }
   }
   class AL extends KeyAdapter{
      //Key events here
   }
}

サーバ側:

//import heres
public class ServerRunner{
    //variables here, and this class is called somewhere else to start the server, 
    //which 
    //has the server socket, and a couple more variables
    public ServerRunner(Server2 ser){
        serv2 = ser;
        players = new Socket[ServerRunner.roomNum + 1];
        xy = new int[roomNum + 1][2];
        gui = new GUI();
        string = new String[0];
    }
    //start method is called in the class above, which passes it a server2 object 
    //(itself)
    public void start(){
        try{
            serv2.dataServ = new ServerSocket(4000);
            serv2.listening = true;
            defaultArray();
            gui.main(string); //the GUI class just draws the players for the server to
                              //see
            System.out.println("Listening for Connections...");
        }catch(Exception e){
            System.err.println("The port number 777 and 778 are not open");
        }
        while(serv2.listening){
            try{
                //the data class gives the client a client number, and stores the x & y
                //cord
                new data(serv2.dataServ.accept()).start();
            }catch(Exception e){
                System.err.println("Error in Server Runner");
            }
        }
    }
    public void defaultArray(){
        for(int i = 0; i < xy.length; i++){
            xy[i][0] = -1;
        }
    }
}

この問題で私を助けてくれてありがとう!:)

編集:全部で1つのソケットを使用していますが、このソケット(スレッド)で複数のことを行う必要があります。データを混同せずにこれを行うにはどうすればよいですか?別のserverSocketを作成する必要がありますか?

クライアントは、xコードとyコードをサーバーに送信して配列に格納しますが、他のプレーヤーのxコードとyコードでいっぱいの配列を受信して​​、同時に画面に描画します...これを参照してくださいスレッドが所定の位置に配置されますが、1つのソケットで実行することは不可能ではないにしても非常に困難です

4

2 に答える 2

0

もう 1 つの方法は、すべてのクライアントをサーバーに登録することです。次に、すべてのクライアントが独自のサーバー ポートを開く必要があります。クライアントが新しい座標をサーバーに送信するたびに、サーバーはこの座標を送信したクライアント以外のすべてのクライアントにこの新しい座標を送信する必要があります。

于 2016-06-20T14:54:42.677 に答える
0

サーバーの接続ごとに 2 つのスレッドを用意します。1 つはクライアントの更新をリッスンします。受信したクライアントの更新ごとに適切な処理を行い、最後に内部状態が変更されたというイベントを発行します。

もう一方のスレッドは「内部状態変更」イベントをリッスンし、イベントを受信すると、新しい状態をクライアントに送信します。

ここで、複数のエミッター、単一のイベント、複数のレシーバーがあるため、イベント全体を慎重に実装する必要があります。

クライアントは再び 2 つのスレッドを持つ必要があります。1 つはサーバーにメッセージを送信し、もう 1 つは更新された状態を受信します。それらの同期は簡単なはずです。

また、これをしないでください...

IS = new DataInputStream(sock.getInputStream());
OIS = new ObjectInputStream(sock.getInputStream());

... IS と OIS を交互に読み取ると問題が発生する可能性があるためです。

于 2012-05-28T22:19:14.093 に答える