2016-10-10 2 views
2

Myself и другой член группы несут ответственность за создание многопользовательского аспекта игры. Для этого мы придерживаемся стиля сервера. Мы можем подключить Сервер и клиентов, и мы отправляем 4 сообщения клиенту с сервера. При использовании 2 клиентов один клиент получит 4 строки, а второй получит одну строку, которая представляет собой комбинацию из всех 4 с белыми квадратами между ними, иногда с отключенными частями сообщения.Непоследовательные результаты Server-Client

Что может быть причиной для двух клиентов иметь разные результаты, один получает правильное сообщение 4, а другой - тот, который является комбинацией всех 4?

MainServer выступает в качестве хозяина игры, содержит сокет сервера и клиентские соединения. Каждый клиент подключается к классу сервера и его сервером, что переговоры с MainServer

public class MainServer { 

    public GameManager game; 
    public Server[] connections; //Array of connected players if server is running. 
    public int playerID = 1001; 
    public ArrayList<Integer> idList = new ArrayList<Integer>(); 
    int maxPlayers; 
    public MainServer(GameManager game, int maxPlayers){ 
     this.game = game; 
     this.maxPlayers = maxPlayers; 
    } 

    public synchronized void runServer(int port){ //As it stands, having the game in server mode will dedicate it to server mode totally. 
     try { 
      int nclients = 0; 
      connections = new Server[maxPlayers]; 
      //Await connections. 
      ServerSocket ss = new ServerSocket(port); 
      System.out.println("GAME NOW IN SERVER MODE"+ " Port: "+port+" URL: "+ss.getInetAddress()); 
      while (idList.size() != maxPlayers) { //WHile there are still open players slots 
       //Wait for a socket 
       //System.out.println("MainServer, before ss.accept()"); 
       Socket s = ss.accept(); 
       System.out.println("ACCEPTED CONNECTION FROM: " + s.getInetAddress()); 

       connections[nclients] = new Server(s, playerID); 
       idList.add(playerID); 
       playerID++; 
       connections[nclients].start(); 
       nclients++; 
      } 

      for (Server s : connections){ 
       System.out.println(s.playerID); 
       if(s.dout==null){System.out.println("dout is null for server "+s.playerID);} 
       s.dout.writeUTF("BEGINGAME"); 
       for (int i : idList){ 
        s.dout.writeUTF(Integer.toString(i)); 
       } 
       s.dout.writeUTF("ENDLIST"); 
      } 


     } catch(IOException e) { 
      System.err.println("I/O error: " + e.getMessage()); 
     } 

    } 


public class Server extends Thread { 
    public final Socket socket; 
    public DataInputStream din; 
    public DataOutputStream dout; 
    public int playerID; 

    public Server(Socket sock, int ID) { 
     this.socket = sock; 
     playerID = ID; 
    } 

    public void run() { 

     try { 

      din = new DataInputStream(socket.getInputStream()); 
      dout = new DataOutputStream(socket.getOutputStream()); 

      dout.writeInt(playerID); 
      dout.flush(); 

      String frmClient = "", toClient = ""; 

      while (!frmClient.equals("stop")) { 
       frmClient = din.readUTF(); 

       //System.out.println("client says: " + frmClient); 
       //toClient = frmClient + " :Reply From Server"; 
       toClient = frmClient; 

       sendToAll(toClient); 
       dout.flush(); 
      } 
      din.close(); 
      socket.close(); 

     } catch (IOException e) { 
      System.err.println("Server I/O Error: " + e.getMessage()); 
      e.printStackTrace(System.err); 
     } 
    } 

    public void sendToAll(String msg) throws IOException { 
     for (Server s : GameManager.server.connections) { 
      if (s != null && s.dout != null) { 
       s.dout.writeUTF(msg); 

      } 
     } 
    } 
} 

public class Client extends Thread { 

    public DataOutputStream output; 
    public DataInputStream input; 

    private GameManager game; 

    private String address; 
    private int port; 
    public int playerID; 
    public ArrayList<String> allIds = new ArrayList<String>(); 
    private Socket s; 
    // 
    String l=""; 
    // 

    public ArrayList<String> outBuff = new ArrayList<String>(); 
    public ArrayList<String> inBuff = new ArrayList<String>(); 

    public Client(String add, int por, GameManager game) { 
     address = add; 
     port = por; 
     this.game = game; 
    } 

    public void run() {  
     System.out.println("CLIENT"); 
     try { 
      s = new Socket(address,port); 
      DataInputStream input = new DataInputStream(s.getInputStream()); 
      DataOutputStream output = new DataOutputStream(s.getOutputStream()); 

      String toServ = ""; 
      String frmServ = ""; 

      playerID = input.readInt(); 

      while (!toServ.equals("stop")) { 

       toServ = ""; 
       if(outBuff.size()>0){ 
       toServ = outBuff.remove(0);} 

       if (toServ != null){ 
        output.writeUTF(toServ); 
        output.flush(); 
       } 

       frmServ = input.readUTF(); 


       if(frmServ.length()>0){ 
        System.out.println(frmServ+" :test");}    
       if (frmServ != null&&frmServ.length()>0){ 
        if (frmServ.equals("BEGINGAME")){ 
         //System.out.println("2"); 
         while (!frmServ.equals("ENDLIST")){ 
          frmServ = input.readUTF(); 
          if (!frmServ.equals("BEGINGAME")&&!frmServ.equals("ENDLIST")&&frmServ.length()>0){ 
           System.out.println(frmServ+" :Adding to allIds"); 
           allIds.add(frmServ);  
          }      
         } 

         game.beginGame(allIds); 

        } 
        if(!frmServ.equals("BEGINGAME")||!frmServ.equals("ENDLIST")){ 
         inBuff.add(frmServ);       
        } 
       } 

       for (int i = 0; i < inBuff.size() - 1; i++){ 
        game.applyUpdateFromServer(inBuff.remove(i)); //Possible temporary solution, may cause lag because this thread is going into main game and performing tasks 
       } 


      } 

      output.close(); 
      s.close(); 

     } catch (IOException e) { 
      System.err.println("Client I/O Error: " + e.getMessage()); 
      e.printStackTrace(System.err); 
     } 
    } 

} 
+0

Не могли бы вы правильно отформатировать этот беспорядок. – EJP

+1

И задайте реальный вопрос. Вы не задали вопрос или не указывали, что не работает. –

ответ

0

TCP не выдерживает границы сообщений. Иногда отдельные «сообщения», отправленные вашим сервером, будут поступать по одному клиенту; иногда нет. Если несколько сообщений отправляются быстро клиенту, система отправки (я имею в виду здесь операционная система, а не ваша серверная программа) связывает их в один сегмент TCP и передает их в другую систему как единое целое. Даже если этого не произойдет, принимающая система может завершить агрегирование нескольких принятых сообщений и доставку их через один приемный вызов клиенту.

Вы должны всегда налагать свои границы протокола сообщений на логический поток, предоставляемый TCP. Это обычно означает либо (а) размещение «разделителя записей» (новая строка, нулевой байт, что угодно) между записями, либо (б) помещение заголовка в начале каждой записи с указанием его длины.

Смежные вопросы