2012-03-12 156 views
1

我正在用java編寫一個網絡服務器,並且我遇到了一個小問題。 讓代碼來說話:Java循環退出條件

import java.io.IOException; 
import java.net.ServerSocket; 
/** 
* Another flavor of the server module. 
* According to GOD (also known as Joshua Bloch) this is the proper 
* implementation of a singleton (Note: serialization). 
* 
* @author estol 
*/ 
public enum EnumSingletonServer implements ServerInterface, Runnable 
{ 
    SERVER; 
    private ServerSocket serverSocket = null; 
    private boolean Listening   = true; 

    @Override 
    public void bind() { 
     this.bind(DEFAULTPORT); 
    } 

    @Override 
    public void bind(int Port) { 
     try { 
      this.serverSocket = new ServerSocket(Port); 
     } catch (IOException ioe) { 
      System.err.printf("Cannot bind to port %d\nAdditional information:\n%s\nExiting\n", Port, ioe.getMessage()); 
      System.exit(1); 
     } 
    } 

    /** 
    * Not that elegant, but does not work with flipping the switch, because 
    * the loop (in public void run()) is only running when there is an incoming connection(?). 
    * 
    * 
    * FIXME 
    */ 
    @Override 
    public void shutdown() { 
     // this.Listening = !this.Listening; // FIXME 
     System.exit(0); 

    } 
    /** 
    * Accepting connections on the port, we are bound to. 
    * The main loop of the server is a bit broken. Does not exit, 
    * if we flip the value of this.Listening, but exit on the next incoming 
    * connection. This is a problem. 
    * 
    * FIXME 
    */ 
    @Override 
    public void run() { 
     try { 
      System.out.printf("Listening on %d\n", this.serverSocket.getLocalPort()); 
      Thread.currentThread().setName("ServerThread"); 
      // FIXME 
      do { 
       new Thread(new ServerWorkerThreads(this.serverSocket.accept(), 3)).start(); 
      } while (this.Listening); 

      this.serverSocket.close(); 
      System.exit(0); 
     } catch (IOException ioe) { 
      System.err.printf("Cannot accept on, or close port %d\nAdditional information:\n%s\nExiting\n", this.serverSocket.getLocalPort(), ioe.getMessage()); 
      System.exit(1); 
     } 
    } 
} 

現在,在評論中說,如果我否定在下/翻蓋/改變變量this.Listening的值,循環不停止,但退出連接。

我在一開始並沒有在枚舉器中實現服務器,而是使用了一個類,它在被序列化後未能成爲單例,但是按照我預期的那樣執行。我嘗試了一段時間(條件)完成,還做了while(condition)循環。

所有幫助將不勝感激。

+2

您是否嘗試過偵聽「volatile」以確保所有線程都可以看到更改? – assylias 2012-03-12 10:59:32

+1

serversocket塊中的accept()方法,所以在等待新連接時不會執行循環;它只會在收到新連接後檢查是否繼續。我不太清楚如何得到你想要的行爲,雖然.. – Steven 2012-03-12 11:00:12

+0

解決了易變。謝謝assylias! – 2012-03-12 11:01:52

回答

1

在您的關機方法只關閉套接字,而不是設置變量:

this.serverSocket.close() 

這將引發SocketException在接受環路和環路將停止。

+0

其實這也會起作用,但如果我想處理這個異常,並退出,我會回到起點。 (System.exit(0)vs try {this.serverSocket.close();} catch(Exception e){System.out.printf(「Exiting Gracefully!\ n」); System.exit(0)})做更完全一樣的事情的更長的方式。 – 2012-03-12 11:16:33

+2

+1 @estol,如果你正在使用這個庫運行單元測試,你可能更喜歡測試來完成和給與狀態,並繼續運行測試。只是讓這個進程死掉並不是那麼有用。注意:您更有可能在生產中終止進程,因此shutdown()可能僅在測試中有用。 – 2012-03-12 13:52:56