SocketChannel Default nonBlocking is false
SocketChannel을 사용할 때 기본적으로 Blocking Mode로 사용된다.
일반적으로 다음과 같이 사용하는 경우 버퍼에 있는 데이터를 읽기 위한 작업 수행 시 Thread Block 발생
이 경우 Read Timeout(soTimeout)을 설정해도 먹히지 않음
Javadoc을 보면 read() 메서드에 대한 timeout은 InputStream을 사용할 때 적용 가능하다고 되어 있음
즉, SocketChannel의 구현체인 SocketChannelImpl의 read() 메서드를 직접 사용하는 경우 InputStream을 사용하지 않고 IOUtil.read()를 호출
InputStream을 사용하여 ReadTimeout 설정
getInputStream()을 통해 실제 ChannelInputStream 반환
이후 SocketInputStream.read(ByteBuffer bb)가 호출됨
이 메서드에서의 특징은
- 소켓 채널의 설정을 Non-Blocking으로 변경
sc.configureBlocking(false);
- 최초 읽기 시도 시 반환된 데이터가 없으면 이후 timeout 설정만큼 소켓을 poll 하여 변화를 감지
int result = sc.poll(Net.POLLIN, to);
- 만약 0보다 작은 값이 반환되었다면 Running Time을 확인하여 타임아웃이라 판단되면 SocketTimeoutException Throw
to -= System.currentTimeMillis() - st; if (to <= 0) throw new SocketTimeoutException();
- 메서드를 Return 하기 전 설정을 원복 하여 Blocking Mode로 바꿈
finally { try { sc.configureBlocking(true); } catch (ClosedChannelException e) { } }
결론
- SocketChannel Blocking Mode에서는 기본적으로 Read Timeout 기능을 제공하지 않음
- InputStream을 사용하는 형태로 Blocking Mode에서도 Read Timeout 기능을 사용할 수 있지만 실제 내부 로직에서는 Non-Blokcing Mode로 임시 변경하여 사용하는 트릭과 같음
참고
SocketChannel (Java Platform SE 8 )
Reads a sequence of bytes from this channel into the given buffer. An attempt is made to read up to r bytes from the channel, where r is the number of bytes remaining in the buffer, that is, dst.remaining(), at the moment this method is invoked. Suppose th
docs.oracle.com
https://bugs.java.com/bugdatabase/view_bug.do?bug_id=4614802
Bug ID: JDK-4614802 setSoTimeout does not work with nio SocketChannel
bugs.java.com
https://technfun.wordpress.com/2009/01/29/networking-in-java-non-blocking-nio-blocking-nio-and-io/
Networking in Java: non-blocking NIO, blocking NIO and IO
Standard run-time library in Java provides two interfaces for networking. One, which exists in Java since the beginning, is called “basic IO”, because it is based on generic framework o…
technfun.wordpress.com
'자바 개발자되기' 카테고리의 다른 글
Inner Class에 대한 유효성 검사(javax.validation) (0) | 2022.07.02 |
---|---|
Spring JPA findById() 사용 시 주의점 (1) | 2021.07.28 |
@MockBean Spring Context Recreated (0) | 2021.05.24 |
구체적인 Exception Catch를 해야하는 이유 (0) | 2021.04.22 |
Open Session In View와 트랜잭션, 그리고 영속성 컨텍스트 (0) | 2021.03.24 |