每个客户端的多线程服务器

时间:2012-05-28 21:27:40

标签: java sockets connection client serversocket

好的有一个问题,我有一台服务器,这个服务器是多线程的,它允许多个客户端连接到它。当客户端连接到服务器时,它会被抛入一个线程来执行其任务,以此类推其他客户端。

客户端所做的基本上是在屏幕上绘制一个“图形”方块,当你在屏幕上移动这个方块(带有键盘事件,箭头键)时,它会将x和y cordonate发送到要放置的服务器到一个数组对应的索引,指向在开始连接中给客户端的客户端编号。

我的问题不是将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线同时在其屏幕上绘制......看到这是线程到位的地方,但是如果不是不可能用一个插座那么非常困难

2 个答案:

答案 0 :(得分:0)

服务器中每个连接有两个线程。一个人听客户端更新;对于每个客户端更新,它接收它进行正确的处理,最后它发出一个内部状态已被更改的事件。

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

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

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

另外,不要这样做......

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

...因为从IS和OIS互换阅读可能会导致问题。

答案 1 :(得分:0)

另一种方法是在服务器上注册每个客户端。然后,每个客户端都必须打开自己的服务器端口。每当客户端向服务器发送新坐标时,服务器必须将此新坐标发送给除发送此坐标之外的每个客户端。