2016-10-10 18 views
2

自分自身と他のグループメンバーは、ゲームのマルチプレイヤーの側面を作成する責任があります。これを行うために、我々はServer Clientスタイルに従っています。私たちはサーバーとクライアントを接続することができ、サーバーから4つのメッセージをクライアントに送信します。 2つのクライアントを使用する場合、1つのクライアントは4つの文字列を受信しますが、2つ目の文字列は4つすべての組み合わせを白い四角で組み合わせた1つの文字列を受信します。サーバ - クライアントの一貫性のない結果

2つのクライアントが異なる4つのメッセージを受信し、正しいメッセージを受信した受信者と、受信した4つのメッセージの受信者が異なる可能性があります。

メインサーバーはゲームのホストとして機能し、サーバーソケットとクライアント接続を含みます。 各クライアントはサーバ・クラスに接続され、その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は、メッセージの境界を維持しません。サーバーによって送信された個々の「メッセージ」は、クライアントによって一度に1つずつ受信されることがあります。時にはそうではない。クライアントに複数のメッセージが連続して送信される場合、送信システム(ここではサーバープログラムではないオペレーティングシステムを意味します)は、それらを単一のTCPセグメントにバンドルし、それらを単一のユニットとして他のシステムに配信します。たとえそれが起こらなくても、受信システムはいくつかの受信メッセージを集約し、それらをクライアントへの単一の受信呼び出しを介して配信する可能性があります。

TCPが提供する論理ストリームの上に、常に独自のメッセージプロトコル境界を課す必要があります。これは、一般に、(a)レコード間に「レコード区切り」(改行、ゼロバイトなど)を入れること、または(b)各レコードの先頭にその長さを示すヘッダーを置くことを意味します。

関連する問題