2009-10-02 4 views
6

ServerSocket.accept()에서 차단 된 스레드의 차단을 해제하는 방법?

및 다음과 같은 종료 방법 :

public void shutdown() { 
    EneaLog.printLog("Server shutdown NOW!"); 
    stopped = true; 
} 

server.accept()에서 대기중인 스레드의 차단을 해제 할 수 있어야합니다. 서버가 종료되기 전에 연결을 기다리십시오.

서버가 다운되고 있다는 것을 등록 된 클라이언트에게 알려야하기 때문에 shutdown()에서 server.close()를 할 수 없습니다.

어떤 아이디어?

답변

4

인터럽트로 "종료"할 수 있도록 코드를 디자인하려고합니다. 주로, 이는 Java 동시성 패키지의 Executor 프레임 워크가 interrupt을 사용하여 실행중인 작업을 취소하기 때문입니다. 또한 "종료"작업은 종료되는 작업의 내부를 알 필요가 없습니다.

그러나, 인터럽트를 무시하는 ServerSocket 생성자로 생성 한 서버 created from a ServerSocketChannel.입니다 하지 않는 accept에 대한 호출이 인터럽트에 응답하지 않습니다, 나는이를 다시 구성하는 방법을 발견하지 않았습니다.

서버를 만드는 코드를 변경할 수없는 경우 서버 소켓에서 close을 호출하는 다른 스레드를 준비하십시오. 또한 서버 소켓을 만드는 데 사용 된 방법에 관계없이 accept에 차단 된 스레드에서 예외가 발생합니다.

이렇게하면 SSL을 사용할 때 큰 어려움이 있습니다. JSSE 소켓은 InterruptibleChannel에서 생성되지 않으며 스레드의 간단한 인터럽트에 응답하지 않습니다.


클라이언트에게 알리지 않고 서버를 닫을 수 없다는 메시지가 나타났습니다. 소켓을 성공적으로 중단하면 종료됩니다.

accept (으)로 전화를 걸면 서버 소켓이 수락 상태로 차단 된 경우 클라이언트가 연결되지 않으므로 문제가되지 않습니다. 현재 연결을 나타내는 Socket 인스턴스의 경우에만 문제가되어야합니다.

알림 요구 사항을 충족하지 못하는 경우 NIO의 ServerSocketChannel을 비 차단 모드로 사용하기위한 재 작업이 필요할 수 있습니다.

+0

음 좋은 대답 .. 어쩌면 내가 문제에 접근 방식을 변경합니다. 클라이언트 측에서 try-catch로 서버 종료를 관리합니다. –

0

Thread.interrupt()을 사용해 보셨습니까? 스레드가 인터럽트 채널상에서의 I/O 동작 막히면

다음 채널 가 닫히고 스레드의 인터럽트 상태 설정되고, 스레드 에서 ClosedByInterruptException 수신처.

스레드는 스레드의 인터럽트 상태가 설정 될 선택기 차단하며, 아마도 비 - 제로 값과, 선택 동작으로부터 즉시 를 반환하는 경우 만, 셀렉터 웨이크 것처럼 메소드가 호출되었습니다.

+0

나는이 시도했다. interrupt(); 종료()하지만 작동하지 않습니다 ... –

+0

당신이 방해하고자하는 스레드 (즉, 차단 된)에서 호출해야합니다 –

2

다른 스레드에서 소켓을 닫을 수 있어야합니다.

2

인터럽트 (인터럽트 지점에 따라 다르지만 취소 지점에 따라 취소됨) 또는 닫기 (취소는 파일 설명자를 닫지 않아도 됨)를 수행하지 않습니다. 수락을 계속하지 않도록 알리려면 수락과 통신해야합니다 (종료 알림이있는 sendto를 시도하십시오). 적어도 이것은 Linux의 경우입니다. 다른 플랫폼에서 어떤 모습인지 모릅니다.

+0

마침내이 문제를 어떻게 해결합니까? 많은 사람들이 close가 작동한다고하지만, Linux에서 실행되는 제 경우에는 작동하지 않습니다. – Djvu

1

나는 같은 문제에 직면 해있다. 내 작업 솔루션은 ServerSocket 객체를 닫는 것으로 구성됩니다 (serverSocket.close()). 이 작업을 수행하면 accept() 메서드가 원하는 작업 인 SocketException을 throw합니다.

빈센트

관련 문제