2012-07-20 2 views
0


Java에서 클라이언트 - 서버 게임 ("SET"이라고 함)을 개발했습니다.

디버깅 프로세스 중에 매우 어색한 문제가 발생했습니다.
동일한 컴퓨터에서 클라이언트와 서버를 모두 실행하면 (클라이언트가 로컬 호스트에 연결) 게임이 환상적으로 작동합니다 (또한 서버와 많은 고객).

그러나 클라이언트와 서버를 2 대의 개별 컴퓨터에서 실행하면 클라이언트와 서버가 모두 InputStream readLine 메서드에 멈추게됩니다.

필자는 writeBytes 메소드를 사용하여 데이터를 쓰고 있지만 필자는 항상 \ n 데이터 라인을 완성한다고 언급 할 것이다. (언급했듯이, 시스템은 1 머신에서 완벽하게 작동한다!)

시스템 아키텍처는 다음과 같다. 다음과 같이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의 실행 방법 :

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()); 
      } 
     } 
    } 

, 클라이언트 서버 프로젝트가 한 시스템에서 완벽하게 작동하는 이유가 될 수 있는지,하지만 것 2 대의 개별 컴퓨터에 매달려 있습니까?
P. 클라이언트와 서버를 별도의 컴퓨터에 단계별로 디버깅 할 때도 완벽하게 작동합니다. 사전에

감사합니다,

+0

코드에 여전히 localhost 문이 있습니다.이 코드는 복사 붙여 넣기 문제입니까? –

답변

1

그 다음 방화벽에 대한 검사가 현재 비활성화 인 경우 경우 대부분 로컬 호스트의 문제가 아니라 그리고 서버가 모든 인터페이스에서 수신 여부를 확인하기 위해 NETSTAT 실행 둘째, 다시 확인하는 경우 뿐만 아니라 루프백.

리눅스에서 당신은 시도 할 수 있습니다 :

netstat -nat | grep 6789 

그것은 아마도 윈도우 파워 쉘에서 작동합니다. 서버가 외부 IP에서 실행 중이거나 수신 중이며 클라이언트가 여전히 연결할 수 없으며 방화벽이 wireshark를 설치 해제하고 네트워크에서 어떤 일이 일어나는지 살펴보십시오.

+0

오, 죄송합니다. 오늘은 내가 만든 변경 사항입니다. 올바른 IP로 실행했습니다. 당신은 이것이 문제가 아니라고 생각할 수 있습니다. – banshimo