0

好的,有一个问题,我有一个服务器,这个服务器是多线程的,它允许多个客户端连接到它。当一个客户端连接到服务器时,它会被扔到一个线程中来完成它的任务,等等其他客户端。

基本上,客户端所做的是在屏幕上绘制一个“图形”方块,当您在屏幕上移动这个方块时(使用键盘事件、箭头键),它会将 x 和 y 坐标发送到服务器以放入一个数组中在开始连接时给予客户端的客户端编号的对应索引。

我的问题不是将 x 和 y 线发送到服务器,无论我连接了多少个客户端,它们都可以工作并将 x 和 y 线发送到服务器进行存储,当然还有当玩家做出新动作时,数组中先前的 x 和 y 被新的 x 和 y 线覆盖。

我的问题是将每个客户端(不包括其客户端)绘制到其他客户端屏幕...

所以基本上如果我要在我的客户端屏幕上移动我的方块,它会在每个人的屏幕上移动(当然是连接到服务器)。我在想 id 为每个客户端都有一个多线程服务器,这意味着 id 每个连接有两个线程。但是,如果我在两个线程中同时来回发送东西,套接字就会混淆。另外,我希望客户不断收到这个 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;
        }
    }
}

谢谢你帮我解决这个问题!:)

编辑:总的来说,我有一个正在使用的套接字,但我需要用这个套接字(线程)做多件事,我如何在不混淆数据的情况下做这件事,我应该再做一个 serverSocket 吗?

客户端会将其 x 和 y 线发送到服务器以存储在一个数组中,但也将接收一个充满其他玩家 x 和 y 线的数组以同时在其屏幕上绘制......看这是螺纹到位的地方,但如果不是不可能的话,用一个插座就很难做到

4

2 回答 2

0

服务器中每个连接有两个线程。一个监听客户端更新;对于接收到的每个客户端更新,它都会进行适当的处​​理,最后它会发出一个内部状态已更改的事件。

另一个线程监听“内部状态修改”事件,当它接收到一个时,将新状态发送给客户端。

现在,您需要仔细实现整个事件,因为您有多个发射器、一个事件和多个接收器。

客户端将不得不再次拥有两个线程,一个向服务器发送消息,一个接收更新的状态;同步它们应该很容易。

还有,不要这样...

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

...因为从 IS 和 OIS 交替读取可能会导致问题。

于 2012-05-28T22:19:14.093 回答
0

Another approach would be to register every client at the server. Then, every client has to open its own server port. Whenever a client sends new coordinates to the server, the server has to send this new coordinates to every client other than the one which sends this coordinates.

于 2016-06-20T14:54:42.677 回答