2012-07-20 102 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