2011-04-14 6 views
1

ServerSocket 및 소켓을보다 잘 제어 할 수 있도록 매우 기본적인 API를 구현하고 있지만 스레드 지식 부족으로 해결할 수없는 매우 이상한 문제가 있습니다. 내가 설명 할께.ServerSocket accept() 루프 스레드를 중지하는 중

제 수업에서는 SocketStreamReceiver 보조 소켓을 사용하여 ServerSocket#accept()으로 새 소켓을 수신합니다. 클라이언트가 시작하여 (스레드를 만들고 accept()으로 수신을 시작하는) start() 및 stop() 메소드를 사용하고, SocketStreamReceiver를 중지 (ServerSocket을 닫고 스레드를 파기) 할 수 있습니다.

stop() 메서드는 어떻게 구현합니까? stop()은 start()에 의해 시작된 동일한 보조 스레드에서 doSomething() 내부에서 호출 될 수 있습니다. 원하는대로 변경할 수 있습니다. 원할 경우, 바로 이전 (실행 중)에 스레드 안에 ServerSocket을 만들 수 있습니다.

public class SocketStreamReceiver{ 
    ... 
    private Thread thread; 
    private ServerSocket server; 
    private boolean running; 
    ... 

    public void start() throws IOException{ 
     if (thread != null) return; 

     server = new ServerSocket (port); 
     thread = new Thread (new Runnable(){ 
      @Override 
      public void run(){ 
       try{ 
        while (running){ 
         Socket socket = server.accept(); 
         doSomething (socket); 
        } 
       }catch (SocketException e){ 
        ... 
       }catch (IOException e){ 
        ... 
       } 
      } 
     }, "SocketStreamReceiver"); 
     thread.start(); 
    } 

    public void stop() throws IOException{ 
     if (thread == null) return; 

     //code... 

     thread = null; 
    } 
} 

감사합니다.

편집 - 솔루션 :

public class SocketStreamReceiver{ 
    private Thread thread; 
    private ServerSocket server; 
    private volatile boolean running; 
    ... 

    public synchronized void start() throws IOException{ 
     if (thread != null) throw new IllegalStateException ("The receiver is already started."); 

     server = new ServerSocket (port); 
     thread = new Thread (new Runnable(){ 
      @Override 
      public void run(){ 
       try{ 
        running = true; 
        while (running){ 
         doSomething (server.accept()); 
         ... 
        } 
       }catch (SocketException e){ 
        ... 
       }catch (IOException e){ 
        ... 
       } 
      } 
     }, "SocketStreamReceiver"); 
     thread.start(); 
    } 

    public synchronized void stop(){ 
     if (thread == null) return; 

     running = false; 
     try{ 
      if (server != null){ 
       server.close(); 
      } 
     }catch (IOException e){} 

     thread = null; 
    } 
} 

답변

2

난 그냥 당신도 실행 플래그를 필요로 표시되지 않습니다

public void stop() { 
    running = false; 
    try{ 
     if (server != null) server.close(); 
    } catch (IOException ignored){ 
    } 
} 

할 것입니다. 그러나 예외가 예상되는지 여부를 결정하는 코드를 서버에서 수락합니다. 즉, == false를 실행하면 모든 예외가 무시됩니다.

나는 running을 휘발성으로 만들 것입니다.

다른 스레드에서 실행할 수 있으면 start()/stop()을 동기화합니다.

+1

server.close()가 호출되고 server.accept()를 수행 한 후에는 어떻게됩니까? ServerSocket이 스레드를 차단합니까? –

+2

accept()는 SocketException을 던집니다. 어쨌든 잡아야합니다. –

+1

왜 예외를 잡아서 던집니까? – MByD

관련 문제