LinkedIn

Java NIO - SocketChannel non-blocking mode에서 Read Timeout 설정

2021. 11. 2. 09:39 | 자바 개발자되기

SocketChannel Default nonBlocking is false

 

SocketChannel을 사용할 때 기본적으로 Blocking Mode로 사용된다.

 

 

일반적으로 다음과 같이 사용하는 경우 버퍼에 있는 데이터를 읽기 위한 작업 수행 시 Thread Block 발생

 

 

이 경우 Read Timeout(soTimeout)을 설정해도 먹히지 않음

Javadoc을 보면 read() 메서드에 대한 timeout은 InputStream을 사용할 때 적용 가능하다고 되어 있음

 


즉, SocketChannel의 구현체인 SocketChannelImpl의 read() 메서드를 직접 사용하는 경우 InputStream을 사용하지 않고 IOUtil.read()를 호출

SocketChannelImpl.read(ByteBuffer buf) 메서드 내부

 

 

InputStream을 사용하여 ReadTimeout 설정

getInputStream()을 통해 실제 ChannelInputStream 반환

 

 

이후 SocketInputStream.read(ByteBuffer bb)가 호출됨

 

 

이 메서드에서의 특징은

  1. 소켓 채널의 설정을 Non-Blocking으로 변경
    sc.configureBlocking(false);​
  2. 최초 읽기 시도 시 반환된 데이터가 없으면 이후 timeout 설정만큼 소켓을 poll 하여 변화를 감지
    int result = sc.poll(Net.POLLIN, to);​
  3. 만약 0보다 작은 값이 반환되었다면 Running Time을 확인하여 타임아웃이라 판단되면 SocketTimeoutException Throw
    to -= System.currentTimeMillis() - st;
    if (to <= 0)
    	throw new SocketTimeoutException();
  4. 메서드를 Return 하기 전 설정을 원복 하여 Blocking Mode로 바꿈
    finally {
    	try {
    		sc.configureBlocking(true);
    	} catch (ClosedChannelException e) { }
    }​

 


결론

  • SocketChannel Blocking Mode에서는 기본적으로 Read Timeout 기능을 제공하지 않음
  • InputStream을 사용하는 형태로 Blocking Mode에서도 Read Timeout 기능을 사용할 수 있지만 실제 내부 로직에서는 Non-Blokcing Mode로 임시 변경하여 사용하는 트릭과 같음

 

참고

https://docs.oracle.com/javase/8/docs/api/java/nio/channels/SocketChannel.html#read-java.nio.ByteBuffer-

 

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