관리자 글쓰기
[NIO]TCP 넌블로킹 채널?
2017. 1. 5. 12:58 - 개발 새발

넌블로킹 방식은 connect(), accept(), read(), write() 메소드에서 블로킹이 없다. 클라이언트의 연결 요청이 없으면 accept()는 즉시 null을 리턴한다. 그리고 클라이언트가 데이터를 보내지 않으면 read()는 즉시 0을 리턴하고, 매개값으로 전달한 ByteBuffer에는 어떤 데이터도 저장되지 않는다. 넌블로킹 방식에서 클라이언트가 연결 요청을 하지 않으면 무한루프를 계속 돈다.


넌블로킹은 이벤트 리스너 역할을 하는 셀렉터(Selector)를 사용한다. 넌블로킹 채널에 Selector를 등록해 놓으면 클라이언트의 연결 요청이 들어오거나 데이터가 도착할 경우, 채널은 Selector에 통보한다. Selector는 통보한 채널들을 선택해서 작업 스레드가 accept() 또는 read() 메소드를 실행해서 즉시 작업을 처리하도록 한다.


Selector는 멀티 채널의 작업을 싱글 스레드에서 처리할 수 있도록 해주는 멀티플렉서 역할을 한다. 

- 채널은 Selector에 자신을 등록할 때 작업 유형을 키(SelectionKey)로 생성하고, Selector의 관심키켓(interest-set)에 저장시킨다. 

- 클라이언트가 처리 요청을 하면 Selector는 관심키켓에 등록된 키 중에서 작업 처리 준비가 된 키를 선택된 키셋(seleted-set)에 별도로 저장한다. 

- 작업 스레드가 선택된 키셋에 있는 키를 하나씩 꺼내어 키와 연관된 채널 작업을 처리하게 된다.

- 작업 스레드가 선택된 키셋에 있는 모든 키를 처리하게 되면 선택된 키셋은 비워지고, Selector는 다시 관심키셋에서 작업 처리 준비가 된 키들을 선택해서 선택된 키셋을 채운다.


넌블로킹에서 작업 스레드를 꼭 하나만 사용할 필요는 없다. 채널 작업 처리 시 스레드풀을 사용할 수 있다. 작업스레드가 블로킹되지 않기 때문에 적은 수의 스레드로서 많은 양의 작업을 고속으로 처리할 수 있어 블로킹 방식보다는 서버의 성능이 향상될 수 있다.