2012-03-12 131 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