본문 바로가기

server

Socket과 WebSocket

이번 포스팅에서는 socket과 web socket에 대해서 알아보도록 하겠다.

각 소켓과 웹 소켓에 대해 알아보고 웹 소켓 프로그래밍 예제를 통해 웹 소켓 프로그래밍을 해보려 한다.

네트워크 위에서 프로그램이 동작하기 쉽게 하기 위해서 OSI 7 계층을 나누어서 네트워크를 관리한다.

계층별 프로토콜은 통신 규약일 뿐 프로토콜 구현을 위해 구체적인 구현이 필요하다.

소켓에서는 함수들의 body를 제공하고 별도의 구현 없이 소켓을 사용할 수 있다. 

 

Socket

소켓이란 프로그램이 네트워크에서 데이터를 주고 받을 수 있도록 네트워크 환경에 연결할 수 있게 만들어진 연결부이다.

일반적으로 TCP/IP 프로토콜을 이용한다.

응용 계층 아래 전송 계층 위에 상주하게 된다. 소켓은 엔드 포인트로 통신의 양 끝단에 존재하게 된다.

 

소켓은 프로세스 간 통신에 사용되는 소켓을 이용한 통신 프로그래밍을 socket programming이라 한다.

client Socket과 server Socket으로 구분된다.

통신 연결 요청을 받아들이는 Socket을 Server Socket

통신 연결 요청을 보내는 Socket을 Client Socket이라 한다. 동일한 구조의 소켓이지만 역할에 따라 처리되는 흐름이 조금씩 다르다.

 

소켓 유형

스트림 소켓(Stream Socket)

연결 지향형 소켓으로 TCP를 사용해 데이터가 순서대로 전송되며 신뢰성 있는 통신을 보장한다.

웹 브라우징과 이메일, 파일을 전송에 사용된다.

 

데이터그램 소켓(Datagram Socket)

비연결 지향형 소켓으로 UDP를 사용한다.

데이터 전송이 순서에 상관 없이 이루어지며 신뢰성 보장은 없다.

실시간 비디오 스트리밍이나 온라인 게임에 사용된다.

 

Client, Server의 소켓 API 실행 흐름

 

클라이언트

- 소켓 생성, 연결 요청, 데이터 송수신, 소켓 닫기

서버

- 소켓 생성, 결합, 주시, 받아들이기, 데이터 송수신, 소켓 닫기

 

클라이언트 흐름

클라이언트 소켓 생성 - 연결 요청 - 데이터의 송수신 - 소켓 닫기

 

클라이언트 소켓 생성

연결 대상에 대한 정보가 들어있지 않은 Socket을 생성한다.

이때 소켓의 종류를 선택해야 하는데 TCP 소켓을 위해선 stream 타입 UDP 소켓을 위해선 데이터그램 타입으로 지정 가능하다.

 

연결 요청(Connection)

연결하고 싶은 대상에게 연결 요청을 보내고 IP 주소와 서비스 포트 번호로 연결하고 싶은 타깃 대상을 특정한다.

요청에 대한 결과가 돌아와야 Connect의 실행이 끝난다.

서비스 포트란 port를 말하는 것이고 서비스 구분을 위한 번호로 ip주소:서비스 포트 형태로 사용한다. ex) http:80, https:443, ssh:22

 

데이터 송 수신 - send, recieve

연결 요청에 대한 결과가 반환되어야 실행이 끝난다.

송신할 때는 데이터를 보내는 것이기 때문에 데이터를 언제 얼마나 보낼것인지 알 수 있지만 수신할 땐 상대방이 언제 얼마큼의 데이터를 보낼 것인지 알 수 없다.라는 차이가 존재한다.

수신하는 API는 별도의 Thread에서 진행하게 된다.

 

소켓 닫기

더 이상 데이터의 송수신이 없을 시 소켓을 닫는다.

 

데이터를 송수신할 땐 보안이 중요하다.

어떤 데이터를 보낼 때 아무 데이터나 수신하는 것이 아닌 발신에 해당하는 수신 데이터만 받아야 한다.

 

서버 흐름

 

서버 소켓 생성

클라이언트 소켓과 같이 연결 대상에 대한 정보가 들어있지 않은 껍데기 소켓을 생성한다.

 

바인딩

컴퓨터 사용시 많은 서비스를 사용하고 수많은 프로세스가 동시에 돌아가고 있다.

만약 서버 소켓이 받은 데이터를 다시 보내줘야 할 때 프로세스들의 포트번호가 동일하다면 혼란이 생길 수 있다. 따라서 서버 소켓이 고유한 포트 번호를 만들 수 있도록 소켓과 포트번호를 결합해 주는 작업이 필요하다.

위와 같이 소켓이 사용하는 포트 번호가 다른 소켓의 포트 번호인 10000 이라는 포트 번호를 사용하게 된다면 네트워크를 통해 10000 포트로 데이터가 수신될 때 어떤 소켓이 처리해야 하는지 결정할 수 없을 것이다. 운영체제는 소켓들이 중복된 포트 번호를 사용하지 않도록 내부적으로 포트 번호와 소켓 연결 정보를 관리한다.

하나의 프로세스에는 동일한 포트 번호를 가진 여러 개의 소켓을 결합할 수 있다. 호스트가 하나의 Port로 여러 개의 Socket을 만들어 다른 호스트들과 데이터를 주고받을 수 있다.

 

클라이언트 연결 요청 대기

서버 소켓에서 포트 번호와 바인딩 작업을 마치고 나면 클라이언트로 부터의 연결 요청을 받아들일 준비가 된다.

클라이언트가 연결 요청을 할 때까지 기다리다 연결 요청이 오면 대기 상태를 종료하고 리턴한다.

 

클라이언트 연결 수립

서버 소켓은 연결 요청을 받아들임과 동시에 새로운 소켓을 생성한다.

서버 소켓의 메인 역할은 just 클라이언트 연결 요청을 기다리는 것이다. 따라서 클라이언트 소켓으로부터 연결 요청을 받으면 새로운 소켓을 열고 클라이언트 소켓을 매핑해 넘겨준다.

 

데이터 송수신 - send, recieve

클라이언트와 동일하게 연결 요청을 보내고 요청에 대한 결과가 들어와야 한다.

 

소켓 닫기

송수신할 데이터가 없다 판단시 소켓을 닫고, 서버 소켓은 자신이 생성한 소켓들도 관리해야 한다.

 

TCP/IP 소켓과 웹 소켓의 차이

소켓과 웹 소켓은 IP와 포트를 통한 통신을 한다는 점에서 비슷하고 양방향 통신을 한다는 특징을 가지고 있다.

웹 소켓은 HTTP 레이어에서 작동하는 소켓으로 TCP/IP 소켓의 레이어가 다르다.

 

WebSocket

웹 소켓은 http에서 실시간 통신을 할 수 없는 문제를 해결하기 위해 나온 기술이다.

HTML5 표준의 일환으로 등장한 프로토콜로 웹 브라우저와 서버 간 양 방향 통신을 가능하게 하고 HTTP 프로토콜과 달리 지속적인 연결을 유지하여 실시간 데이터 전송이 가능하다. 초기 연결 설정은 HTTP를 사용하지만 연결이 성립되면 지속적인 TCP 연결을 통해 데이터를 주고받는다.

 

차이점

특징 소켓 웹 소켓
프로토콜 TCP 또는 UDP WebSocket(기본적으로 TCP를 사용)
통신 방식 비동기 또는 동기 양방향, 풀 이중 통신
연결 유지 필요 시마다 연결 설정/ 해제 연결 설정 후 지속적 유지
사용 사례 네트워크 애플리케이션(파일 전송, 메시지 전달 등) 실시간 애플리케이션(채팅, 실시간 데이터 스트리밍 등)
브라우저 지원 직접 지원하지 않음 대부분의 최신 웹 브라우저에서 지원
메시지 포맷 자유롭게 정의 가능 텍스트 또는 바이너리(프레임 기반)

 

http 특징에 대해서 확인하고 넘어가자.

비연결성

매번 연결 맺고 끊는 과정의 비용

request - response의 구조

해더의 비중이 너무 크다. 실시간성으로 많은 데이터를 주고받고자 하는 경우에 부담이 된다.

즉, 요청을 보내면 응답이 오는 단방향적 구조로 통신하기 때문에 TCP/IP 프로토콜을 사용하는 소켓처럼 계속 connection이 유지되는 실시간 통신을 할 수 없다. 이 문제를 해결하기 위해 나온 것이 웹 소켓 프로토콜이다.

 

웹 소켓이 어떤 특징으로 인해 실시간 통신을 할 수 있는지?

연결 지향(양방향)

한 번 연결을 맺고 유지한다.

핸드 셰이크 과정에서는 헤더의 비중이 크지만 한 번 연결되면 간단한 메시지만 오고 가므로 경제적이다.

http를 대체하는 개념은 아니며 웹에서 실시간 통신을 해야 하는 상황에서 쓰이는 프로토콜 중 하나이며 http 레이어 위에서 작동한다.

 

웹 소켓 동작 방법

 

1. 핸드 쉐이킹

통신이 시작되기 전에 실체 간에 확립된 통신 채널의 변수를 동적으로 설정하는 자동화된 협상 과정

 

2.Frame 구성

최초 접속 시에만 http 프로토콜 위에서 핸드 쉐이킹을 하기 때문에 http 헤더를 사용한다. 웹 소켓을 위한 별도의 포트는 없고 기존 포트인 80, 443을 사용한다. 프레임으로 구성된 메시지라는 논리적 단위로 송수신한다. 메시지에 포함될 수 있는 교환 가능한 메시지(frame)는 텍스트와 바이너리뿐이다.

 

웹 소켓 한계

웹 소켓은 html5 이후에 나왔다. html5 이전 기술로 구현된 서비스에서 어떻게 할지에 대해 알아보자.

 

1.Socket.io, SockJS

Socket.io, SockJS가 html5 이전의 기술로 구현된 서비스에서 웹 소켓처럼 사용할 수 있도록 도와주는 기술로 실시간 통신을 돕는다.

브라우저와 웹 서버의 종류와 버전을 파악해 가장 적합한 기술을 선택해 웹 소켓처럼 보이게 기능을 만든다.

 

2.STOMP

웹 소켓은 문자열들을 주고받을 수 있게 해 줄 뿐 그 이상의 일은 하지 않는다. 주고받는 문자열의 해독은 애플리케이션에게 맡긴다.

HTTP는 형식을 정해두었기 때문에 모두가 약속을 따르기만 하면 해석할 수 있다. 하지만 WebSocket 방식은 sub-protocols를 사용해 주고 받는 메시지의 형태를 약속하는 경우가 많다. sub-protocols로 자주 쓰이는 것이 STOMP이다.

 

웹 소켓 이전에 비슷한 기술을 확인해 보자.

http통신은 클라이언트에서 서버로 단방향 통신을 위해 만들어진 기술로 Web Socket 기술이 나타나기 전에는 실시간 통신을 위해 Http통신에 약간의 트릭을 사용해 실시간인 것처럼 작동하게 하는 기술을 만들었다.

 

1. Http Polling

 

가장 기본적인 데이터 처리 방식으로 특정 주기를 가지고 서버에 http request을 하는 방식이다.

Polling 방식은 언제 통신이 발생할지 예측이 불가능하기 때문에 클라이언트가 평범한 http request를 일정한 주기로 서버에 요청해 이벤트 내용을 전달받는 방식이다.

언제 통신이 발생할지 예측이 불가능하단 점에서 틀라이언트가 지속적으로 요청을 하기 때문에 클라이언트가 많아지면 서버의 부담이 급증하게 된다. 실시간 통신이라 부르지만 실시간 정도의 빠른 응답을 기대하긴 어렵다.

 

2. Long Polling

Polling과 비슷한 기법이나 실시간으로 데이터를 처리할 수 있는 방식이다.

Long Polling은 클라이언트에서 서버로 http request를 보내고 이 상태로 계속 기다리다 서버에서 해당 클라이언트로 전달할 이벤트가 있으면 그 순간 response 메시지를 전달하며 연결이 종료된다. 해당 작업이 완료된 이후에는 클라이언트에서 곧바로 다시 http request를 보내 서버의 다음 이벤트를 기다리게 되는 작업 방식이다.

일반 Polling과 비교했을 때 Polling보다는 서버의 부담이 줄어든다는 장점이 있지만 클라이언트에게 동시에 많은 양의 메시지가 올 경우 Polling과 별 차이가 없게 되며, 다수의 클라이언트에게 동시에 이벤트가 발생될 경우에는 곧바로 다수의 클라이언트가 서버로 접속을 시도하게 되고 서버의 부담이 급증하게 된다.

 

3.Streaming

일반적인 TCP Connection과 비슷하고 클라이언트와 서버 간 열결된 연결 통로로 데이터를 보내는 방식이다.

Streaming은 Long Polling과 마찬가지로 처음에는 클라이언트에서 서버로 http request를 보낸다.

서버에서 클라이언트로 이벤트를 전달할 때 해당 요청을 끊지 않고 필요한 메시지만 보내기를 반복하는 방식이다. 서버에서 메시지를 보내고 다시 http request 연결을 하지 않아도 돼서 Long Polling에 비해 부담이 덜하다.

 

이 세 가지 방법 모두 Http를 통해 통신하기 때문에 요청과 응답 시 둘 다 Header가 불필요하게 크다는 단점이 있다.

Long Polling과 Streaming 방식의 경우 서버에서 클라이언트로 메시지를 보낼 수 있지만 클라이언트에서 서버로 메시지를 보내는 것은 조금 어럽다는 문제가 있으므로 클라이언트와 서버 간 어려움 없이 양방향 통신이 가능하게 하기 위해 HTML5 표준의 일부로 Web Socket이 만들어지게 되었다.

 

여기서 잠깐 HTTP가 TCP 위에서 동작하는 원리와 예시를 확인하고 포스팅을 이만 줄이고 다음 포스팅에는 소켓 프로그래밍을 해보도록 하겠다.

 

원리

1. 신뢰성 있는 데이터 전송

http는 데이터를 신뢰성 있게 전송하기 위해 TCP의 기능을 활용한다. TCP는 데이터의 손실, 중복, 순서 보장을 제공하고 HTTP 요청과 응답이 정확하게 전달되도록 한다.

 

2. 연결 설정과 해제

http는 각 요청마다 TCP 연결을 설정하고 응답이 완료되면 연결을 해제하는 방식으로 동작한다. 이 http의 비연결성 특성과 연결 지향적 특성을 결합한 것이다.

 

3. TCP의 흐름 제어와 혼잡 제어

TCP는 네트워크 상태에 따라 데이터 전송 속도를 조절하므로 http는 이러한 기능을 통해 데이터 전송을 보장받는다.

 

예시

1. http 요청 과정

클라이언트가 http 요청을 보낼 때 먼저 TCP 연결을 설정한다.

클라이언트는 TCP 3-way handshake를 통해 서버와 연결을 설정한다.

연결이 설정되면 http 요청을 TCP 세그먼트로 나눠 전송한다.

 

2.http 응답 과정

서버는 요청을 받고 응답을 준비한 후 TCP 연결을 통해 응답을 전송한다.

클라이언트가 응답을 받으면 TCP 연결을 해제한다.

 

3. 지속 연결

HTTP/1.1부터는 기본적으로 지속 연결을 지원하여 여러 HTTP 요청을 동일한 TCP 연결을 통해 처리할 수 있다. 이는 성능 향상과 지연 시간 감소를 위해 도입됐다.

 

HTTP는 응용 계층에서 웹 브라우저와 웹 서버 간의 요청과 응답을 처리하며 TCP는 전송 계층에서 신뢰성 있는 데이터 전송을 담당한다. HTTP는 비연결성이지만 신뢰성 있는 데이터 전송을 위해 TCP의 연결 지향적 특성을 사용하여 동작한다. 이로써 HTTP가 TCP 위에서 동작할 수 있는 것이다.

 

다음 포스팅에서 자바를 통해 소켓 프로그래밍 예제를 해보도록 하자.

'server' 카테고리의 다른 글

STOMP를 활용한 실시간 채팅 프로그래밍  (0) 2024.06.29
WebSocket Programming 채팅 예제  (0) 2024.06.28
Socket Programming 예제  (0) 2024.06.28
Nginx 사용해보기  (0) 2024.06.23
Nginx에 대해서  (0) 2024.06.22