2011-02-10 3 views
3

그래서 두 개의 스레드 (서버 스레드와 클라이언트 스레드)가 있습니다. 서버에 쓸 수는 있지만 클라이언트가 읽을 수는 없습니다. 다음은 클라이언트 연결을 처리하기 위해 서버에 의해 생성 된 클라이언트, 서버 및 스레드입니다.반 사회적인 스레드

클라이언트 - 소켓에 연결하고 서버와 핑퐁을 시도하십시오. 클라이언트는 서버가 먼저 대화 할 것을 기대합니다!

public class ClientMain {  
    public static void main(String[] args) throws UnknownHostException, IOException { 
     Socket socket = new Socket("localhost", 14285); 

     BufferedReader in = null; 
     PrintWriter out = null; 
     try { 
      in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      out = new PrintWriter(socket.getOutputStream()); 
     } catch(IOException e) { 
      Log.write("Error in client thread "); 
      Log.write(e); 
     } 
     while(true) { 
     System.out.println("About to read!! :-D"); 
      String fromServer = in.readLine(); 
      System.out.println("From server: " + fromServer); 
      out.println("PONG"); 
     } 
    } 
} 

서버 - 이것은 서버의 시작 방법입니다. serverSocket을보고 스레드를 생성하고 필요에 따라 클라이언트 스레드를 생성합니다. 네, 그런 식으로 클래스를 정의하는 것은 나쁜 습관이라는 것을 깨닫게됩니다 ... 읽기가 어려울 경우 사과드립니다.

public void start() { 
    this.running = true; 
    // probably could have done this better, but it gets the job done 
    class Start implements Runnable { 
     Server server; 
     Start(Server server) { this.server = server; } 
     public void run() { 
      while(server.running) { 
       try { 
        Socket socket = server.serverSocket.accept(); 
        Log.write("Accepted socket"); 
        new ClientThread(server,socket).start(); 
       } catch (IOException e) { e.printStackTrace(); } 
      } 
     } 

    } 
    Thread start = new Thread(new Start(this)); 
    start.start(); 
} 

여기는 클라이언트 스레드입니다. 소켓에서 스트림을 가져 와서 더 이상 데이터가 없을 때까지 데이터를 작성한 다음 클라이언트에서 일부 데이터를 가져옵니다.

 public void run() { 
      Log.write("Running clientthread"); 
      BufferedReader in = null; 
      PrintWriter out = null; 
      try { 
       in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
       out = new PrintWriter(socket.getOutputStream()); 

      } catch(IOException e) { 
       running = false; 
       Log.write("Error in client thread " + getName()); 
       Log.write(e); 
      } 
      while(running) { 

       try { 
        String message = messageQueue.poll(); 
        while(message != null) { 
         out.println(message); 
         Log.write("wrote message: " + message); 
         message = messageQueue.poll(); 
        } 
        String input = in.readLine(); 
        System.out.println("From client: " + input); 
        server.handle(username,input,this); 
       } 
       catch(IOException e) { 
        Log.write("Error in client thread " + getName() + " username=" + username); 
        Log.write(e); 
        break; 
       } 
      } 
     } 

지금 여기에 내가 서버 측의 출력지고있어 무엇 :

Accepted socket 
Running clientthread 
wrote message: PING 

이이 연결을 가져오고 메시지를 쓰고 나에게 나타냅니다. (명확성을 위해, 클라이언트 스레드가 인스턴스화 될 때 PING이 messageQueue에 채워지므로 클라이언트에게 대화를 시작하기 위해 항상 말을해야합니다.) 수줍어 스레드에 대한 쇄빙선과 같은 것입니까?) 또한 나에게 나타냅니다. 아무 것도 인쇄하지 않기 때문에 클라이언트에서 아무것도 얻지 못한다는 것입니다. in.readLine()

또한 클라이언트의 유일한 출력은 읽으려고한다는 알림입니다. 그렇다면 서버가 작성한 내용을 어떻게 놓칠 수 있습니까?

모든 아이디어를 높이 평가합니다!

감사합니다.

+0

@jgauffin - 태그를 주셔서 감사합니다. – corsiKa

답변

3

내가 추측하고, 추가하려고 :

out.flush(); 
out.close(); 
+1

Doh! 이 일을하는 것이 너무 늦었습니다. 글쎄, 나는 연결을 닫고 싶지 않기 때문에'close()'하지 않았다. 그러나 나는 그것을 내뿜고 싶다. 플러시하기 전에 버퍼가 오버플로되지 않도록 또는 내가 너무 자주 플러시하는지 확인하기 위해 일부 논리를 추가해야합니다. 그러나 그것이 필요한 것입니다. 고맙습니다! – corsiKa

+0

당신의 환영합니다! 내 첫 번째 답변에 감사드립니다! –

+0

PrintWriters에 autoflush를 추가했는데 원활하게 작동합니다. 적어도 프로토 타입 개발로 나아갈 수 있습니다. 나중에 성능/대역폭 문제가 발생하면 해결할 수 있습니다. 다시 한번 감사드립니다. – corsiKa

1

당신이 메시지를 보낼하려는 out.flush(); 매번를 추가합니다. 작업을 마치기 전에는 스트림을 닫지 마십시오. 스트림 완료시 out.close();을 추가하십시오.

관련 문제