2012-07-08 2 views
1

다중 스레드 서버 프로그램에 대한 연결을 열어 두려고합니다. 단추를 눌렀을 때 연결된 모든 클라이언트에 테스트 메시지를 보내고 싶습니다.A 소켓과의 지속적인 연결 유지

public void run() { 
    try { 
     Scanner in = new Scanner(socket.getInputStream()); 
     PrintWriter out = new PrintWriter(socket.getOutputStream()); 
     readUpdate(out, in); 
     while(true){sendUpdate(out);} 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

많은 CPU를 사용합니다.

이것은 내 sendUpdate 메소드입니다.

private void sendUpdate(final PrintWriter out) { 
    new Thread(new Runnable() { 

     public void run() { 
      if(Server.send) { 
       try { 
        if (Server.command != "idle") { 
         System.out.println("Sending"); 
         out.println("[email protected]" + Server.command); 
         out.flush(); 
         Server.send = false; 
         Thread.sleep(100); 
        } 
       } catch (Exception ex) { 
       } 
      } 
     } 
    }).start(); 
} 

누군가가 연결을 유지하고 데이터를 보낼 준비가되면 도와 주시면 감사하겠습니다.

+1

'while (true) {sendUpdate (out);} 이렇게하면 많은 스레드를 생성 할 수 있습니다. 'setUpdate()'메쏘드 안에 새로운 쓰레드. –

+0

소켓은 사용자 또는 클라이언트가 닫을 때까지 열린 상태로 유지됩니다. 루프를 스레드의'run' 메소드로 옮긴다. –

+0

나는 그것을 도왔다. 그러나 도움이된다. 그러나 나의 cpu 사용은 접속 된 클라이언트 당 약 80 %로 간다, 나는 단 4 연결 만 할 수있다. – user1497561

답변

1

서버가 메시지를 초기화 할 수 있고 클라이언트도 시작할 수 있으면 별도의 스레드 읽기 및 쓰기가 필요할 수 있습니다. 하나의 스레드는 요청 - 응답 스타일 통신에 적합하며 다음 클라이언트 요청을 차단하고 서버 측 처리를 수행하고 클라이언트에 응답 한 다음 다시 차단할 수 있습니다.

그러나 두 개의 개별 조건 (클라이언트에서 메시지를 받고 서버의 단추를 클릭하는 경우)을 차단해야하는 경우 두 개의 개별 스레드가 있어야합니다. 그렇지 않으면 조건 중 하나라도 맞는지 확인하기 위해 스레드를 반복적으로 깨워야 할 필요가 있습니다.

그래서 두 개의 스레드를 만들고 Scanner (논리는 readUpdate입니다) 및 다른 하나는 PrintWriter으로 지정하십시오.

public class WriteHandler implements Runnable { 
    private final PrintWriter out; 
    private final BlockingQueue<String> messageQueue = new LinkedBlockingQueue<String>(); 

    //initialize the above in a constructor; 

    public void run() { 
     while(true) { 
      String nextMessageToWrite = messageQueue.poll(); 
      out.println(nextMessageToWrite); 
     } 
    } 

    public void send(String message) { 
     messageQueue.add(message); 
    } 
} 

이 수표 슬립 루프보다 훨씬 더 나은 동시성 메커니즘 인 blocking queue를 사용 :이처럼 출력 핸들러가 볼 수있는 것입니다. 그런 다음 버튼을 클릭하면 다음과 같이 할 수 있습니다.

public void actionPerformed() { 
    for (WriteHandler handler : handlers) { 
     handler.send("PING!"); 
    } 
} 
관련 문제