2017-01-10 6 views
0

내 서버 (및 ExecutorService)를 종료 할 때 정확히 어떤 문제가 있는지 잘 모르겠습니다. ServerMain을 시작하고 Enter를 눌러 socket.close()를 사용하여 server.shutdown() 메소드를 시작하지만 SocketException을 발생시키지 않습니다. 이것이 ExecutorService와 관련이 있다면 종료 할 수 없다는 것을 나는 모른다. 이 코드입니다 :Java ExecutorService를 실행중인 서버와 함께 종료 할 수 없음

public class ServerMain { 

public static void main(String[] args) throws DirectoryServerException, IOException { 
    TCPDirectoryServer server = new TCPDirectoryServer(); 
    ExecutorService serverExecutor = Executors.newSingleThreadExecutor(); 
    try { 
     server.start(1337); 
     serverExecutor.execute(server); 
     System.out.println("Server started. Press enter to terminate."); 

     System.in.read(); 

     server.shutdown(); 
     System.out.println("Server is shut down..."); 
    } finally { 
     serverExecutor.shutdown(); 
     while (!serverExecutor.isTerminated()) { 
      try { 
       if (!serverExecutor.awaitTermination(5, TimeUnit.SECONDS)) { 
        System.err.println("Problem with shutting down the Executor"); 
        serverExecutor.shutdownNow(); 
       } 
      } catch (InterruptedException ignore) { 
      } 
     } 
    } 
} 
} 

그리고 여기에 서버 :

public class TCPDirectoryServer implements DirectoryServer { 
private int port; 
private ConcurrentHashMap<ParseDirectory, Histogram> cache; 
private List<ClientHandler> clientHandlerList; 
private ExecutorService clientExecutorService; 
private Socket socket; 

public TCPDirectoryServer() { 
    super(); 
    this.cache = new ConcurrentHashMap<ParseDirectory, Histogram>(); 
    this.clientHandlerList = new LinkedList<ClientHandler>(); 
    this.clientExecutorService = Executors.newCachedThreadPool(); 
} 

@Override 
public void start(int port) throws DirectoryServerException { 
    this.port = port; 
} 

@Override 
public void disconnect(ClientHandler clientHandler) { 
    clientHandlerList.remove(clientHandler); 

} 

@Override 
public void shutdown() throws DirectoryServerException { 
    try { 
     socket.close(); 
    } catch (IOException e) { 
     throw new DirectoryServerException(e); 
    } 
} 

@Override 
public void run() { 
    try (ServerSocket serverSocket = new ServerSocket(port)) { 
     while (true) { 
      socket = serverSocket.accept(); 
      clientHandlerList.add(connect(socket)); 
     } 
    } catch (SocketException e) { 
     System.err.println("AAAA"); 
     System.out.println("Server is shutting down"); 

    } catch (IOException e) { 
     System.out.println("Something failed " + e.getMessage()); 
    } 
} 

답변

2

이 부분 : 당신이 shutdown를 호출 할 때

while (true) { 
     socket = serverSocket.accept(); 
     clientHandlerList.add(connect(socket)); 
    } 

이 ... 때문에, SocketException이를 포기하지 않습니다 마지막으로 연결된 클라이언트 소켓을 닫고 있습니다. ServerSocket은 아직 열리고 들어오는 요청을 기다리고 있습니다.

0

serverExecutor.shutdown()을 호출해도 서버가 종료되기 전에 모든 프로세스가 완료 될 때까지 대기하게됩니다. 정상적으로 종료되었습니다. "while (true)"루프를 빠져 나가기를 기다리는 중일 것입니다. serverExecutor.shutdownNow()를 호출 해보십시오. 귀하의 프로그램을 종료하십시오. 당신의 TCPDirectoryServer 클래스 메이크업에서

0

는 멤버 변수를 ServerSocket를하고 종료 방법은 소켓이 null의 경우 NPE에 대한 조심 클라이언트 소켓 (들)을 닫을 때 또한

public void shutdown() { 
    ...... 
    this.serverSocket.close(); 
    ........ 
} 

다음 (아무도 같이한다 귀하의 서버에 연결됨). 이렇게하면 서버가 종료되지 않습니다.