解释
我正在重新审视我过去自学Java的项目。
在这个项目中,我希望能够阻止服务器接受新客户端,然后在退出JVM之前执行一些“清理”操作。
在该项目中,我使用以下样式进行客户端接受/处理循环:
//Exit loop by changing running to false and waiting up to 2 seconds
ServerSocket serverSocket = new ServerSocket(123);
serverSocket.setSoTimeout(2000);
Socket client;
while (running){ // 'running' is a private static boolean
try{
client = serverSocket.accept();
createComms(client); //Handles Connection in New Thread
} catch (IOException ex){
//Do Nothing
}
}
在这种方法中,如果没有客户端连接,则每2秒抛出一次SocketTimeoutException,除非有必要,否则我不喜欢依赖异常进行正常操作。
我一直在尝试使用以下样式来尝试最小化依赖异常进行正常操作:
//Exit loop by calling serverSocket.close()
ServerSocket serverSocket = new ServerSocket(123);
Socket client;
try{
while ((client = serverSocket.accept()) != null){
createComms(client); //Handles Connection in New Thread
}
} catch (IOException ex){
//Do Nothing
}
在这种情况下,我的意图是只有在调用serverSocket.close()或出现问题时才会抛出异常。
问题
这两种方法有什么显着差异,还是它们都是可行的解决方案?
我完全是自学成才,所以我不知道我是否无缘无故地重新发明了这个轮子,或者我是不是已经找到了好的东西。
我已经潜伏了一段时间,这是我第一次找不到我需要的东西。
请随意提出完全不同的方法= 3
答案 0 :(得分:1)
第二种方法的问题是如果while循环中发生异常,服务器将会死亡。
第一种方法更好,但您可能希望使用Log4j添加日志记录异常。
while (running){
try{
client = serverSocket.accept();
createComms(client);
} catch (IOException ex){
// Log errors
LOG.warn(ex,ex);
}
}
答案 1 :(得分:0)
非阻塞IO是您正在寻找的。如果返回SocketChannel
(Socket
的非阻塞替代方法),则返回null
,如果当前没有要接受的连接,则不会阻止。
这将允许您删除超时,因为没有任何阻止。
您还可以注册一个Selector
,它会在有接受连接或有数据需要时通知您。我有一个here的小例子,以及一个不使用选择器的非阻塞ServerSocket
编辑:如果我的链接出现问题,这里是非阻塞IO的示例,没有选择器,接受连接:
class Server {
public static void main(String[] args) throws Exception {
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);
while(true) {
SocketChannel sc = ssc.accept();
if(sc != null) {
//handle channel
}
}
}
}
答案 2 :(得分:-1)