자바 소켓 프로그래밍 알아보기

이월(0216tw)·2024년 5월 23일

이 포스트는 자바 소켓 프로그래밍의 이론적인 내용을 담고 있습니다.
테스트+코드 분석 및 실습 자료는 👉 java-socket-example 깃허브 에 정리해놓았습니다.

소켓(Socket)이란?
소켓은 네트워크 통신에 사용되는 인터페이스(규격)로 종단간 데이터 송수신을 할 수 있게 해준다. 예를 들어 Client PC 와 Server PC가 서로 데이터를 주고 받을 수 있도록 네트워크 통신을 설정해주는 것이다.

소켓을 구성하는 주소 정보
IP주소(컴퓨터 식별을 하는 논리 주소) : PORT(해당 응용프로그램을 식별)

만약 A (127.0.0.1)라는 클라이언트가 B (192.168.12.12) 라는 웹서버와 통신을 하고 싶다고 하자. 그럼 A는 B라는 대상의 웹서버를 192.168.12.12:80 으로 식별할 수 있는 것이다.
(:80 은 HTTP 프로토콜을 의미한다)

소켓은 네트워크 7계층 중 전송 계층(4계층)에서 생성되고 관리된다. 참고로 IP주소는 3계층에서 , Port 정보는 4계층에서 네트워크 대상을 식별하기 위해 주소로써 사용된다. (2계층은 MAC이라는 물리적 주소 등등..)
세션(Session)
클라이언트와 서버간의 연결 상태를 유지하는 논리적 개념

세션과 소켓의 관계
클라이언트와 서버간의 연결을 통한 세션을 생성하기 위해 소켓이 사용된다.

소켓(Socket)이 생긴 이유
(1) HTTP를 이용한 데이터 송수신의 단점
초기에는 문서 자원을 URL을 이용해 요청하고 응답할 수 있는 HTTP(하이퍼텍스트전송프로토콜) 방식으로 통신을 했다. 이를 통해 사람들은 원하는 자료를 편하게 요청할 수 있지만 아쉬운 점이 있었다.

클라이언트가 자원 요청(URL)을 해야만 서버가 응답을 주는 방식이다.

특정 자원 호출을 위해서는 반드시 새로운 URL을 요청해야 한다는 것이었다.
(만약 타이머 기능을 제공하는 사이트가 새로운 정보를 위해 1초마다 새로고침 된다면..?)

(2) AJAX의 등장 (비동기 javascript and XML)
데이터 요청을 위해 새로운 페이지로 이동하는게 아니라 웹 페이지 내용의 일부만 수정함으로써 부하를 줄일 수 있었다.
(이제 타이머 기능을 만들때 초,분,시쪽만 업데이트하면 되겠군)

하지만 여전히 클라이언트 요청이 있어야 서버가 응답을 주는 방식이다.

(3) WebSocket 개념의 등장
클라이언트와 서버간의 양방향 통신이 가능한 채널을 구성해주는 기술이 등장했다.

즉, 한번의 연결로 자유롭게 C->S , S->C 메세지 처리가 가능한 것이다.

참고로 과거 HTTP 1.0 버전은 항상 연결 요청마다 다음 프로세스를 진행해야 했다.
[연결요청 -> 데이터 요청 -> 데이터 응답] (100번 요청해야하면 100번 연결..)
이후 HTTP 1.1 버전부터는 일정 요청/일정 시간 동안 연결 유지를 통해 부하를 줄였다.

WebSocket 프로토콜은 연결은 HTTP로 하되, 데이터 송수신은 ws 프로토콜을 사용한다.

소켓을 어디에 사용하나?
가장 먼저 생각할 수 있는 양방향 통신은 "채팅" , "실시간댓글" 등이다.
또한 서버로 클라이언트가 요청을 할 때도 소켓을 통해 연결하고 스레드를 발생시켜 자원을 처리하도록 한다.

그 외에도 사용방식은 무궁무진하다.

소켓 기술 트렌드
출처 : GPT
(1) 비동기 소켓 프로그래밍
발달 이유
기존에 웹서버는 사용자의 요청이 들어올 때마다 하나의 스레드를 발생시켜 소켓을 연결하여 요청을 처리했다. 만약 10개의 스레드풀을 가지고 있는 서버에 10개의 동시요청이 들어온다면 이후의 연결 요청은 스레드 자원이 반환되어야만 진행을 할 수 있었다. 만약 10개의 요청이 모두 긴 IO 응답을 필요로 하는 요청이라면, 작업이 끝나야 쓰레드를 반환하여 사용하게 된다.

NIO 을 활용한 IO작업 Non-Blocking화
만약 IO작업이 발생했을 때 block을 하지 않고 백그라운드에서 처리할 수 있다면?
만약 10개의 스레드가 있고 20개의 client요청이 IO작업을 모두 포함한다고 하자.
기존 방식이라면 10개의 요청을 먼저 처리하고 이후에 스레드가 반환되는 대로 추가적인 client요청을 수행할 것이다.

하지만 NIO을 활용하면 10개의 IO요청이 끝나기 전에 그 다음 요청을 계속 처리할 수 있다.

Non-blocking Channel 와 Selector 활용
Selector는 여러 Non-blocking Channel의 상태를 모니터링 하고, 이벤트가 발생한 채널(select() 메서드) 에 대한 작업을 수행할 수 있게 해준다.

Non-blocking 채널은 NIO에서 사용되는 개념으로 , IO작업이 완료되지 않아도 대기하지 않고 다른 작업을 수행할 수 있는 채널을 의미한다.

IO vs NIO
NIO가 성능적인 부분에서 좋은 점이 있지만 한계점도 분명하다.

IO를 사용하면 좋은 경우
(1) IO는 스트림을 사용해 입출력 작업을 하며, 대용량 데이터를 처리해야 한다면 이처러 작은 조각으로 처리하는 것이 좋다.
(2) 클라이언트 요청 수가 적다면(스레드풀이 충분히 커버한다면) IO도 충분하기
(3) 데이터를 순차적으로 처리할 때 사용하면 좋다.

NIO를 사용하면 좋은 경우
(1) NIO는 버퍼를 이용해 데이터를 주고 받으므로 작은 용량의 데이터도 효율적으로 처리가 가능하다.
(2) 클라이언트 요청이 많은 경우 Non-blocking이 큰 도움이 된다.
(3) 만약 요청이 많고 이에 대한 IO작업 크기가 작다면 보다 효율적이다.

이후 내용도 TODO로 업데이트 할 예정입니다.

profile
개발도 하고 강의도 하고 고민을 제일 많이 합니다

0개의 댓글