2011-09-14 3 views
1

Java 프로그램의 단일 인스턴스를 열 수있는 클래스를 만듭니다. ServerSocket을 여는 데몬 스레드를 사용합니다. TCP 포트가 이미 취해진 경우 인스턴스 생성시 예외가 발생합니다.예기치 않은 소켓이 때때로 닫히거나 열리지 않습니다.

코드는 일반적으로 Linux 및 Windows에서 작동합니다. 여기

내가 코드를 사용하고 있습니다 :

public class SingleInstaceHandler extends Thread { 

    private static final Logger log = Logger.getLogger(IEPLC_Tool.class); 
    private boolean finished = false; 

    @SuppressWarnings("unused") 
    private ServerSocket serverSocket; 

    /* 
    * Constructor 
    * Generate the server socket. 
    * If the TCP door was busy throws IOException. 
    */ 
    public SingleInstaceHandler() throws IOException { 
     @SuppressWarnings("unused") 
     ServerSocket serverSocket = new ServerSocket(44331); 
     this.setDaemon(true); 
     this.start(); 
     log.info("Server socket initialized"); //if commented out it works 
    } 

    public void run() { 
     synchronized (this) { 
      while (!finished) { 
       try { 
        log.debug("Server socket goes to sleep"); 
        this.wait(); 
        log.debug("Server socket waken up"); 
       } catch (InterruptedException e) { 
        log.debug("ERROR while sending SocketThread2 in wait status"); 
        e.printStackTrace(); 
        System.exit(-1); 
       } 
       log.info("Server socket end"); 
      } 
     } 
    } 

    public synchronized void shutdown() { 
     log.debug("SingleInstaceHandler shutdown() caled"); 
     finished = true; 
     notifyAll(); 
    } 
} 

때때로 대신 포트가 바쁜 유지되지 ... 어떤 생각을?


UPPENDED 기타 시험 AFTER :

다른 많은 테스트를 실행. 포트가 다른 SW 인스턴스와 같은 것으로 가져간 경우 new ServerSocket(44331);이 예외를 throw하지만 때때로 어떤 이유로 포트를 가져 오지 않아도이 리소스를 가져올 수없는 경우도 있습니다. 이 경우 아무런 예외도 발생하지 않고 응용 프로그램에서 원하는만큼 인스턴스를 열 수 있습니다. 어쩌면 내가 포트를 잠글 스레드를 강제로 다른 작업을 수행해야합니다 ...

어떤 생각?

감사합니다,

인트

+0

가 어떻게 소켓이 닫혀 있는지 진단 할

인트? 왜 사용하지 않는 serverSocket 필드가 클래스에 있습니까? –

+0

이 코드는 나에게 의미가 없습니다. ServerSocket을 인스턴스 변수에 저장하지 않으려면 다시 액세스 할 수 없습니까? – home

+0

나는 netstat -vatn | 명령을 사용한다. grep "44331".난 내 응용 프로그램의 단일 인스턴스를 보장하기 위해 그것을 사용하는 경우 – Stefano

답변

0

는 내 질문에 대답을 게시에 바보 조금 기분이 할 ... 음 .. 내 코드는 알아낼 나를 오래 걸려서 버그가 있습니다 : 대신

ServerSocket serverSocket = new ServerSocket(44331); 

:

this.serverSocket = new ServerSocket(44331); 

내가 전에 그것을 통지하지 않았다가 ... basicaly 버그 내가 생성자 내에서 로컬 소켓을 선언 한 것이 었습니다. 생성자 프로 시저가 종료되었을 때 소켓은 해제되었거나 Garbadge 수집기에 의존하지 않았습니다. 행동은 아주 무작위 적이었다. 재미있는 부분은 로버 호출자가 전화를 걸지 않았거나 호출하지 않았기 때문에 Garbadge 수집기를 시작하기 위해 enougth되었다는 것입니다. 실수를 알아 차리는 데 꽤 오래 걸렸습니다. 대기 후

this.serverSocket.close() :

은 또한 그것은을 넣어하는 것이 좋습니다.

어쨌든 도움을 줄 것입니다!

건배,

0

당신이 GC를받을 수 ServerSocket가에 대한 참조를 유지하지 않는 것처럼. Oracle JDK를 사용하는 경우 소켓은 GCed 될 때 닫힙니다 (java.net.PlainSocketImpl).

문제가 테 생성자에서 내가 할 것입니다 :