원본 본문으로 이동하기

자바 소켓의 종류 [블록킹 / 논블로킹 / 비동기 논블로킹]

박용서 - 참고 할 문서(같이보기) : https://gs.saro.me/#m=elec&jn=534 https://gs.saro.me/#m=elec&jn=537 비동기 논블로킹의 예제파일은 https://gs.saro.me/#m=elec&jn=534 에서 받으시기 바랍니다. 자바에서의 소켓 구현방법 1. 일반적인 소켓 : 블록킹 + 쓰래드 일반적으로 소켓을 배울 때 처음 접하는 방식으로 블록킹 방식이라고 합니다. 블록킹 + 쓰래드 라고 쓴 이유는 1:1 접속이 아닌 이상 서버는 엑셉이 있을 때 마다 새로운 쓰래드를 생성해야합니다. (아래 두가지의 방식도 쓰래드를 적절히 분배하여 사용하지만 블록킹 방식의 경우는 필수이기 때문에 강조하였습니다.) 구현이 매우 쉽다는 장점이 있지만... 접속자가 1000명쯤 된다면 read 상태에서 블록킹이 걸려 있더라도 cpu는 시분할 처리를 하면서 1000개의 read 상태의 쓰래드를 아무 의미없이 돌게(CPU 컨텍스트 스위칭) 됩니다. 즉 사람이 많아질 경우 극악의 방식이 됩니다. 다만 개발 시간이 단축되는 장점이 있기 때문에 소수의 사람이 접속하는 시스템을 만들 때 도움이 됩니다. (하지만 보통... 이미 만들어진 라이브러리를 쓰는 경우가 많죠.. 소켓 라이브러리를 추천하는 글은 아니기 때문에 앞으로 생략하겠습니다.) 2. 논블로킹 방식 java.nio.channels 에 있는 SocketChannel 등을 이용하여 만드는 방식입니다. nio 는 non-blocking IO의 약자로 엑셉이나 리드등이 블록킹 되지않고 그냥 지나가는 방식입니다. 때문에 여러 접속자가 있어도 하나의 쓰래드로 일괄적으로 read가 가능합니다. 다만 while 문을 통과하는 read나 accept으로 인해 접속자가 없더라도 CPU 점유율이 매우 많이 올라가게 되고 이를 제어하기 위해 sleep 등을 쓰게 된다면 그만큼 효율성이 떨어지게 됩니다. 난이도도 어려우며 접속자가 별로 없을 경우 오히려 효율이 떨어질 수 있습니다. 3. 비동기 논블로킹 방식 java.nio.channels 에 있는 AsynchronousSocketChannel 등을 이용하여 만드는 방식입니다. CompletionHandler을 이용하여 콜백을 받을 수 있습니다. 즉 논블로킹처럼 while 으로 받는 형식이 아니기 때문에(그렇게 받을 수도 있긴 하지만, 그럴경우 위 논블록킹 방식도 가능합니다.) CPU점유율을 직접 저어해야 하는 단점이 줄어듭니다. 다만 이 방식은 운영체제의 시스템콜을 부르는 방식이기 때문에 코딩을 잘못 할 경우 블루스크린등.. 심각한 오류가 날 확률이 있습니다. (필자도.. 경험했습니다.) 다른 C/C++의 경우는 프로그래밍을 잘못 할 경우 시스템까지 영향을 끼칠 수 있지만, 아무렇게 짜도 시스템까지 문제 생기는 일이 드문 자바에서는 조금 불안정해 보일 수 있습니다. 아마 윈도우의 경우는 IOCP를 이용하여 구현된 객체가 아닐까 조심스럽게 추측해봅니다. 또한 필자는 이것을 공부하면서 자료를 많이 찾을 수 없었는데 JDK 1.7 버전 부터 지원하기 때문에 안드로이드에서는 아직 사용하기 힘듭니다. (안드로이드에서 JDK 1.7을 사용할 수는 있으나... Android 4.4 KitKat 부터 완전히 지원되기 때문에.. 아직 사용할 수 없다고 봐야합니다.) 추가 : 기본값으로 사용할 경우 운영체제 기본값 쓰래드를 생성하게 됩니다. 때문에 단일 쓰래드를 테스트 하고싶으신분은. AsynchronousChannelGroup asynchronousChannelGroup = AsynchronousChannelGroup.withFixedThreadPool(1, Executors.defaultThreadFactory()); asynchronousServerSocketChannel = AsynchronousServerSocketChannel.open(asynchronousChannelGroup); 위와 같이 오픈하셔야합니다. System.out.println("TID : " + Thread.currentThread().getId()); 위와 같이 현재 쓰래드번호를 테스트 해보시기 바랍니다. - 자바