2012-07-20 105 views
0


我在java中開發了一個客戶端 - 服務器遊戲(稱爲「SET」)。

在調試過程中,我遇到了一個非常尷尬的問題:
如果我在同一臺機器上運行客戶端和服務器(客戶端連接到本地主機),遊戲的工作非常奇妙(如果我運行服務器和很多客戶)。

但是,如果我在兩臺獨立的機器上運行客戶端和服務器,那麼客戶端和服務器都會掛在Inputstream readLine方法中。

我會提到我使用writeBytes方法來寫入數據,但我總是用\ n完成一個數據行(如上所述,系統在一臺機器上完美工作!)

系統的體系結構是如下:JAVA客戶端 - 服務器軟件,多臺機器

public SetServer(){ 
     this.deck = initCardsList(); 
     Collections.shuffle(this.deck); 

     shownCards = new Card[12]; 
     for(int i = 0; i<12; i++){ 
      Card c = this.deck.removeFirst(); 
      shownCards[i]=c; 
     } 
     while(!isSetOnTable()){ 
      Card c = this.deck.removeFirst(); 
      this.deck.addLast(shownCards[0]); 
      shownCards[0]=c; 
     } 

     playersQueue = new LinkedList<String>(); 

     clients = new LinkedList<ServerOperation>(); 
     try{ 
      ServerSocket welcomeSocket = new ServerSocket(6789); 
      while(true) 
      { 
       if(currNumOfPlayers<5){ 
        System.out.println("Waiting for connection..."); 
        Socket connectionSocket = welcomeSocket.accept(); 
        String line = (new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()))).readLine(); 
        currNumOfPlayers++; 
        playersQueue.addLast(line); 

        ServerOperation client = new ServerOperation(connectionSocket,this, line); 
        clients.add(client); 
        Thread t = new Thread(client); 
        t.start(); //<--- This thread listens to client's request 
        notifyPlayersAdded(line,new DataOutputStream(connectionSocket.getOutputStream())); //<-----This method sends 3 lines of data 
       } 

      } 
     } 
     catch(Exception e){ 
       System.out.println(e.getMessage()); 
      } 
    } 

的ServerOperation的run方法:

public void run(){ 
     if(socket==null){ 
      return; 
     } 
     else{ 
      try{ 

     //  this.out.writeBytes("NewConnection:" + this.parent.STATUS+"\n"); 
      // this.parent.notifyCards(); 
       while(true){ 
        String line = this.br.readLine(); 
        String command = line.split(":")[0]; 
        if(command.equals("SetRequest")){      
         String[] cards = line.substring(line.indexOf(':')+1).split(" "); 
         Card c1,c2,c3; 
         c1 = new Card(
           CardShape.values()[(int)(cards[0].charAt(3)-'0')], 
           CardNumber.values()[(int)(cards[0].charAt(2)-'0')], 
           CardFill.values()[(int)(cards[0].charAt(1)-'0')], 
           CardColor.values()[(int)(cards[0].charAt(0)-'0')]); 
         c2 = new Card(
           CardShape.values()[(int)(cards[1].charAt(3)-'0')], 
           CardNumber.values()[(int)(cards[1].charAt(2)-'0')], 
           CardFill.values()[(int)(cards[1].charAt(1)-'0')], 
           CardColor.values()[(int)(cards[1].charAt(0)-'0')]); 
         c3 = new Card(
           CardShape.values()[(int)(cards[2].charAt(3)-'0')], 
           CardNumber.values()[(int)(cards[2].charAt(2)-'0')], 
           CardFill.values()[(int)(cards[2].charAt(1)-'0')], 
           CardColor.values()[(int)(cards[2].charAt(0)-'0')]); 
         this.parent.checkIfSetAndNotify(c1,c2,c3,this.playerId); 
        } 


       } 
      } 

      catch(Exception e){ 
       System.out.println(e.getMessage()); 
      } 
     } 

客戶端的代碼:

public SetClient() 
    { 
     String sentence; 
     this.myCards = new LinkedList<Card>(); 
     try{ 
      String modifiedSentence; 
      BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in)); 
      clientSocket = new Socket("10.0.0.3", 6789); 
      DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream()); 
      BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 
      outToServer.flush(); 
      String name = sayHelloAndGetUserName(); 
      outToServer.writeBytes(name); 
      outToServer.flush(); 

      sentence = inFromServer.readLine(); 
      sayWelcome(sentence); 
      ClientOperation clnOper = new ClientOperation(clientSocket,this); 
      Thread t = new Thread(clnOper); 
      t.start(); //<---this thread listens to the server for messages (suppose 
//to catch the first 3 lines. In practice, catches only the first one. 

      while(!GameOver) 
      { 
       try{ 
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //<-----listens to the user's input 
        String line = br.readLine(); 
        String[] choices = line.split(" "); 
        int c1 = Integer.parseInt(choices[0]); 
        int c2 = Integer.parseInt(choices[1]); 
        int c3 = Integer.parseInt(choices[2]); 
        sendSetMessage(outToServer,c1,c2,c3); 
       } 
       catch(Exception ex){ 
        System.out.println("Error listening to system.in..."); 
       } 
      } 

     } 
     catch(Exception e){ 
      System.out.println(e.getMessage()); 
     } 
    } 

ClientOperation代碼:

public void run() 
    { 
     if(socket==null){ 
      return; 
     } 
     else{ 
      try{ 
       this.br = new BufferedReader(new InputStreamReader(socket.getInputStream())); 

       while(true){ 
        String line = this.br.readLine(); 
        String command = line.split(":")[0]; 
        String value = line.split(":")[1]; 
        if (command.equalsIgnoreCase("Deck")) 
        { 
         ConvertStringToCards(value); 
         this.parent.PopulateCards(shownCards); 
        } 

        else if (command.equalsIgnoreCase("Points")) 
        { 
         System.out.println("Points: " + value); 
        } 

        else if(command.equalsIgnoreCase("NewPlayer")){ 
         System.out.println(value + " has joined the game !\n"); 
        } 

        else if(command.equalsIgnoreCase("Hint")){ 
         this.parent.printHint(ConvertStringToHint(value)); 
        } 
       } 
      } 
      catch(Exception e){ 
       System.out.println(e.getMessage()); 
      } 
     } 
    } 

在一般情況下,這可能是一個客戶端服務器項目將很好地工作1名機上的原因,但會掛在2個獨立的機器?
P.S.當我在單獨的機器上逐步調試客戶機和服務器時,它也可以很好地工作。

由於提前,

+0

代碼中仍然存在localhost語句,這是複製粘貼問題嗎? – 2012-07-20 08:02:53

回答

1

如果不是本地主機的問題,那麼最有可能的,如果檢查的防火牆,如果它存在禁用和再次檢查,其次是運行netstat來檢查服務器是否在所有接口上監聽不僅在環回上。

在Linux上,你可以嘗試:

netstat -nat | grep 6789 

它很可能也是在Windows電源外殼工作。如果服務器正在運行/偵聽您的外部IP,並且客戶端仍然無法連接,並且防火牆被禁用,請安裝wireshark並查看網絡上正在發生的事情。

+0

對不起,這是我今天才做出的改變。我用正確的IP運行它。你可以認爲這不是問題。 – banshimo 2012-07-20 08:15:34