간단한 nio 기반 자바 서버가 있다고 가정 해 보겠습니다. 예 : (간략화 된 코드) :자바에서 비동기 채널 닫기 NIO
while (!self.isInterrupted()) {
if (selector.select() <= 0) {
continue;
}
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove();
SelectableChannel channel = key.channel();
if (key.isValid() && key.isAcceptable()) {
SocketChannel client = ((ServerSocketChannel) channel).accept();
if (client != null) {
client.configureBlocking(false);
client.register(selector, SelectionKey.OP_READ);
}
} else if (key.isValid() && key.isReadable()) {
channel.read(buffer);
channel.close();
}
}
}
따라서 간단한 단일 스레드 비 차단 서버입니다.
문제는 다음 코드에 있습니다.
channel.read(buffer);
channel.close();
같은 스레드 (연결을 허용하고 데이터를 읽는 스레드)에서 채널을 닫으면 모두 정상적으로 작동합니다. 하지만 다른 스레드에서 연결이 닫히면 문제가 발생합니다. 예를 들어
((SocketChannel) channel).read(buffer);
executor.execute(new Runnable() {
public void run() {
channel.close();
}
});
이 시나리오에서 서버의 상태 TIME_WAIT에 소켓이 있고 클라이언트에 ESTABLISHED가 설정되었습니다. 따라서 연결이 정상적으로 닫히지 않습니다. 어떤 아이디어가 잘못된거야? 나는 무엇을 놓쳤는가?
호스트 OS는 무엇입니까? 이것은 패키지 사양이 모두 스레드 안전 구조임을 주장하기 때문에 구현 기능/버그 일 수 있습니다. – alphazero
Mac OS X 10.5.6 하의 호스트 시스템. 오늘 저는 Windows 7 하에서 반복 테스트를하고 있습니다. 네가 옳은 것 같아. –
채널을 닫기 전에 channel.socket()을 닫으면 어떻게됩니까? – Nuoji