2012-02-25 2 views
0

TCP 소켓과 UDP 소켓에 대한 예제를 읽은 후에 Oracle Java 페이지의 소켓에 대해 스스로 배우는 동안 Java 소켓 다중 스레드에 문제가 있습니다.클라이언트와 서버 간의 Java 소켓 교환 메시지

이 지식을 사용하여 클라이언트와 서버간에 메시지를 교환하려고합니다.

그러나 클라이언트가 멀티 스레드를 사용하여 서버에 메시지를 보내고 서버에 어떤 조건이 있는지 궁금합니다.

예 : 클라이언트가 서버에

서버를 받게됩니다 편지를 보내 위 코드의 주석에서

if(inputfromClient.equals("A")){ 
    // how to make input fromClient is null after get message (inputstream) from client? 
} 

같은 조건이있는 경우, 당신은 내 질문을 볼 수 있기 때문에 클라이언트 후

if(inputfromClient.equals("A")){ 
    if(inputfromClient.equals("B")){ 
     //some condition 
    } 
} 

내 서버 코드 같은 것입니다 : A는 입력 한 후 클라이언트가이 같은 구조에서, B처럼 다음 편지를 보낼 것입니다 전송

public class TCPServerThread extends Thread{ 

    Socket client = null; 
    BufferedReader in; 
    String statusBuffer = new String(); 
    String intputLine, outputLine; 
    public TCPServerThread(Socket socket){ 
     client = socket; 
    } 

    public void run(){ 
     try { 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException ex) { 
       Logger.getLogger(TCPServerThread.class.getName()).log(Level.SEVERE, null, ex); 
      } 
      PrintWriter out = new PrintWriter(client.getOutputStream(),true); 
      in = new BufferedReader(new InputStreamReader(client.getInputStream())); 
      gameHandle g = new gameHandle(); 
      boolean condition = true; 

       while((intputLine=in.readLine()) != null){ 
        outputLine = g.processInput(intputLine); 
        out.println(outputLine); 
        System.out.println(outputLine); 

       } 



        out.close(); 
        in.close(); 
        client.close(); 


     } catch (IOException ex) { 
      Logger.getLogger(TCPServerThread.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 


} 

내 클라이언트 코드 :

public class ClientTCP { 

    public static void main(String[] args) { 
     try { 
      Socket socket; 
      PrintWriter out = null; 
      BufferedReader in = null; 
      try { 
       socket = new Socket("localhost", 4444); 
       out = new PrintWriter(socket.getOutputStream(), true); 
       in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      } catch (UnknownHostException ex) { 
       Logger.getLogger(ClientTCP.class.getName()).log(Level.SEVERE, null, ex); 
      } catch (IOException ex) { 
       Logger.getLogger(ClientTCP.class.getName()).log(Level.SEVERE, null, ex); 
      } 

      BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); 
      String fromServer; 
      String fromUser; 
      fromUser = stdIn.readLine(); 
      while(fromUser!= null){ 

       out.println(fromUser); 
       //System.out.println(in.readLine()); 
      } 
     } catch (IOException ex) { 
      Logger.getLogger(ClientTCP.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 


} 

가 대단히 감사합니다.

편집

내가 언급으로

클라이언트가 서버에

클라이언트 메시지를 보내기 전에 이해하는 것이 확인 : onePMode

클라이언트 : 인터넷

....

와 서버는 클라이언트로부터 메시지를받을과

if(inputLine.equals("onePMode")){ 
// it will continue to compare inputline is satisfy with sub condition 
    if(inputLine.equals("internet"){ 
    //do something 
    } 

} 

이 가능한 솔루션 가장 간단한 수 있습니다 입력을

/* 
* To change this template, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package srpserver; 

import java.net.Socket; 
import java.util.Random; 

/** 
* 
* @author *** 
*/ 
public class gameHandle { 

    private String modePlay = ""; 
    private String wait = "wait"; 
    private String status = wait; 
    private String keyword = ""; 
    private Socket client; 
    private String letter = ""; 
    private String onePMode ="onePMode"; 
    private String getWord = "getWord"; 
    private String twoPMode = "twoPMode"; 
    private String waitForPlayer = "waitforPlayer"; 
    private String ready = "ready"; 
    private String question = "question"; 

    public gameHandle(){} 

    public gameHandle(Socket socket,String Mode, String keyword, String letter){ 
     client = socket; 
     this.keyword = keyword; 
     this.letter = letter; 
     modePlay = Mode; 
    } 
    //array with word will be rando, 
    String[] words = {"laptop", "network", "device", "game", "mobile", 
    "word", "november", "december", "signal", "internet","localhost","boot", "socket", 
    "client", "server", " port", "exception", "java", "dotnet","singleton", "ejb","hibernate", 
    "computer", "microsoft", "lan"}; 

    //this method get random word from array  
    public String getWord(){ 
     Random r = new Random(); 
     String randomString = words[r.nextInt(words.length)]; 
     return randomString; 
    } 



    public String processInput(String inputString){ 
     String outPut = ""; 
      if(status.equals("wait")){ 
       if(inputString.equals(onePMode)){ 
        status = question; 
        outPut = "hello"; 
        // outPut = question; 
       } 
      }else if(status.equals(question)){ 
       if(inputString.equals(getWord)){ 
        /*keyword = getWord(); 
        outPut = getWord(); 
        System.out.println(keyword); 
        status = question;*/ 
        outPut = "getworrdddrdd"; 
        System.out.println("get worddddddddd"); 

       }else if(keyword.contains(inputString)){ 
        System.out.println("containt"); 
       } 
      } 
     return outPut; 
    } 





    public static void main(String[] args) { 
     gameHandle a = new gameHandle(); 
     System.out.println(a.getWord()); 

    } 
} 
+0

정확히 주석의 의미는 무엇입니까이를 사용하는 방법 ? 당신이 정교 할 수 있니? 클라이언트 측에서는 루프로 작성하고 있지만 서버 측에서는 한 줄만 읽었습니다. 여기 뭔가 잘못 되었나요? – JProgrammer

+0

@JProgrammer 예 클라이언트에 루프를 사용하여 서버에 연속적으로 메시지를 보내십시오. 하지만 서버에서이 조건이 true이면 클라이언트가 메시지를 onePMode 보낼 때와 같은 조건이 필요합니다. 서버가 위의 조건에서 다음 조건을 수행합니다. – MYE

+0

ok.질문에 대해 더 자세히 설명 할 수 있습니까? (코드 주석에 언급 된 내용) – JProgrammer

답변

0

이 처리하는

GameHandle을 편집 비교 너의 문제에.

public class TCPServerThread extends Thread{ 

    Socket client = null; 
    BufferedReader in; 

    String statusBuffer = new String(); 

    public TCPServerThread(Socket socket){ 
     client = socket; 
    } 

    public void run() { 
    try { 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException ex) { 
      ex.printStackTrace(); 
     } 

     PrintWriter out = new PrintWriter(client.getOutputStream(), true); 
     in = new BufferedReader(new InputStreamReader(
       client.getInputStream())); 
     String intputLine, outputLine; 

     intputLine = in.readLine(); 

     while (intputLine != null) { 
      if(intputLine.equals("close")){ 
       break; 
      } 
      processResponse(intputLine); 
      intputLine = in.readLine();    
     } 

     out.close(); 
     in.close(); 
     client.close(); 

    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 
} 

public void processResponse(String response) { 

    // reset the statusBuffer so that we can process new commands from 
    // client 
    if (response.equals("reset")) { 
     statusBuffer = new String(); 
     System.out.println("reset"); 
    } else { 
     statusBuffer = statusBuffer + "#" + response; 
    } 

    if (statusBuffer.equals("#onePMode")) { 
     System.out.println("#onePMode"); 
    } else if (statusBuffer.equals("#onePMode#internet")) { 
     System.out.println("#onePMode#internet"); 
    } else if (statusBuffer.equals("#onePMode#play")) { 
     System.out.println("#onePMode#play"); 
    } 

} 

} 

귀하의 클라이언트 코드에서도 실수가 하나 있습니다. 수정 된 코드는 다음과 같습니다.

public class ClientTCP { 

    public static void main(String[] args) { 
     try { 
      Socket socket = null; 
      PrintWriter out = null; 
      BufferedReader in = null; 
      try { 
       socket = new Socket("localhost", 1000); 
       out = new PrintWriter(socket.getOutputStream(), true); 
       in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      } catch (Exception ex) { 
       ex.printStackTrace(); 
      } 

      BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); 

      String fromServer; 

      String fromUser = stdIn.readLine(); 
      while(fromUser!= null){ 
       out.println(fromUser); 

       if(fromUser.equals("close")){ 
        break; 
       } 

       fromUser = stdIn.readLine(); 

      } 
      out.close(); 
      in.close(); 
      socket.close(); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

} 

내 마지막으로 프로그램을 실행했는데 성공적으로 실행되었습니다. 이제는 아무런 문제가 없어야합니다.

+0

첫 번째로 대단히 감사합니다.하지만 클라이언트가 메시지 onePMode와 내부 조건을 보낸다면 두 개의 문자도 BufferedReader에서 얻습니다. – MYE

+0

당신의 답장을 이해하려고 노력하고 있지만 정확히 무엇을 말하고 싶은지를 알 수는 없었습니다. (예 : onePMode ")) {if (startsBuffer.equals ("Play "). statusBuffer는 클라이언트로부터받은 inputLine을 추가하기 때문에 "onePmode # play"값을 보유 할 것입니다. 시작부터 시작하자. 클라이언트가 'onePmode'를 서버로 보냅니다. statusBuffer의 값은 'onePmode'가 될 것입니다. 클라이언트가 'Play'를 보내면 statusBuffer의 값은 'onePmode # play'가됩니다. 따라서 if ("onePMode # twoPMode")가 this를 조건부로 수행해야합니다 cond와 일치하면 inside와 같습니다. ition. – JProgrammer

+0

예 이것이 내 뜻이며 내 편집 된 내용을 볼 수 있습니다 – MYE

0

원하는 것은 이전 상태를 기반으로 결정하는 것입니다. 객체 지향 상태 머신 만 있으면됩니다. 클라이언트가 초기 상태에서 'A'을 입력하면 서버는 'B' 또는 'C'을 다음 입력으로 예상해야합니다. 서버가 'A' 상태에있는 동안 클라이언트가 'B'을 입력하면 서버는 다음 입력으로 'D'또는 'E'를 예상해야합니다. 원하는 경우 State Design Pattern을 사용해야합니다.

  • 보유하고있는 모든 상태는 개체로 나타내야합니다.

  • 먼저 상태에 대해 Interface을 만들고 상태를 파생시켜야합니다.

  • 그런 다음 상태를 캡슐화하기위한 래퍼 클래스를 만들어야합니다. 이 래퍼 클래스는 상태 시스템 역할을합니다. "현재"상태 개체에 대한 참조를 유지 관리해야합니다.

클라이언트가 문자를 입력하면 래퍼 인스턴스로 전달됩니다. 그런 다음 랩퍼가이를 현재 상태 오브젝트로 전달합니다. 그러면 현재 State 개체가 해당 데이터를 처리하고 컴퓨터의 다음 상태를 결정합니다. 다음 상태 (Object)를 만들고 래퍼 클래스의 "현재"상태 참조를 업데이트합니다. 다음 클라이언트 입력은 새로 생성 된 State 오브젝트에 의해 처리됩니다. 여기

은 예입니다

주 인터페이스

public interface State { 

    void perform(GameHandler context, String data); 
} 

래퍼 클래스

public class GameHandler { 

    State current_state; // holds the current state of the state machine 

    // Initial state should be passed to the constructor 
    public GameHandler(State current_state) { 
     this.current_state = current_state; 
    } 

    // Sets the next state of the state machine 
    // Called by State objects 
    public void setNextState(State mystate) { 
     this.current_state = mystate; 
    } 

    // Outside world will communicate with state machine using this method 
    public void processRequest(String data){ 
     current_state.perform(this,data); 
    } 
} 

국가 구현

public class State_A implements State { 

    @Override 
    public void perform(GameHandler context, String data) { 
     /* Process input data. 
     * Based on your processing, decide the next state 
     * Then set that sate (assuming it as State_B) 
     */ 
     context.setNextState(new State_B()); 
    } 
} 

public class State_B implements State { 

    @Override 
    public void perform(GameHandler context, String data) { 
     /* process input data. 
     * based on your processing, decide the next state 
     * then set that sate (assuming it as State_C) 
     */ 
     context.setNextState(new State_C()); 

    } 
} 

... 서버

// Assuming State_A as the initial state 
GameHandler g = new GameHandler(new State_A()); 
boolean condition = true; 

     while((intputLine=in.readLine()) != null) 
     { 
     g.processRequest(intputLine); 
     } 

...

관련 문제