📢 Network IPC: Socket

pipe, FIFO, message queue, semaphore, shared memory 등은 하나의 컴퓨터, 단말 내부의 프로세스간 통신(Inter Process Communication) 방법이다.

socket는 서로 다른 컴퓨터, 단말의 프로세스 간 통신을 지원하는 방법 중 하나다. 통신의 종점을 추상화해둔 것이다. 즉, 소켓은 서로 다른 단말 간의 통신이라기보다 서로 다른 단말의 애플리케이션간 통신을 돕는 API라고 생각하면 된다.


📢 운영체제에서 Socket

프로세스가 파일 디스크립터를 이용해 파일에 접근하는 방법과 동일하게, 소켓 디스크립터를 이용해 소켓에 접근한다. 실제로 소켓 디스크립터는 파일 디스크립터와 동일하게 구현되어 있다.

때문에 파일 디스크립터 조작이 가능한 프로세스의 함수(메서드)들이 소켓 디스크립터를 동일하게 동작시킬 수 있다. (단, 소켓에는 오프셋 개념이 없기 때문에 lseek 기능은 동작하지 않는다.)

소켓 디스크립터와 파일 디스크립터는 하나의 디스크립터 테이블을 공유한다. 예를 들어 디스크립터 테이블 3, 4번에는 파일 정보가, 5번에는 소켓 정보가 존재할 수 있다.

image


📢 HTTP와 Socket (Web Socket)

image

그림 속 응용1 애플리케이션을 살펴보면, 파일 디스크립터와 소켓을 함께 가지고 있는 것을 확인할 수 있다. 클라이언트가 192.203.144.11 IP를 통해 단말을 선택하고, 3000 포트번호를 통해 응용프로그램을 선택한다.

그렇다면 어떻게 소켓이 바로 연결되어 통신이 진행될까? 또, 소켓이 여러 개라면 어떤 소켓을 사용해야할지 어떻게 구분할 수 있을까?

이해를 위해선 우선 서버 측 소켓이 어떤 순서로 통신을 준비하는지 알아야 한다.

image

서버 측 소켓은 socket()-bind()-listen()-accept() 과정을 거쳐서 클라이언트와 통신을 준비하고 있다.

socket() 과정에서는 소켓의 옵션을 지정하고 생성한다. 이 때 상대측 연결 대상에 대한 정보는 포함되지 않는다. 그저 통신을 준비할 뿐이다. (소켓은 재활용이 가능하다는 걸 유추할 수 있다!)

bind() 과정에서 소켓이 어떤 PORT 번호에 지정될지를 결정한다. 각 소켓은 시스템이 관리하는 포트 번호 중 하나를 선택해야하는데, 소켓이 어떤 PORT 번호로 들어오는 요청을 처리할 것인지 운영체제에게 바인딩을 요청하고, 만일 이미 다른 소켓이 사용 중이라면 에러를 반환 받는 과정인 것이다.

listen() 과정에서 클라이언트의 요청을 기다리는 상태에 빠져든다. listen() 과정에서는 오로지 연결 성공/실패(자의적인 소켓 close 포함)로만 이어지는데, 연결에 성공하더라도 연결 대상의 정보는 가지지 않는다. 처리를 위한 대기 큐에 연결 대상의 정보를 기록하기만 한다.

accept() 과정에 들어서야 대기 큐에 쌓여있는 연결 대상의 정보를 꺼내온다. 그리고 연결 대상의 정보를 접수해서 연결을 진행한다. 그러나 이 때! socket()-bind()-listen() 과정을 수행한 소켓과 연결하는 것이 아니라, 새로운 자식 소켓을 만들어서 연결을 진행한다.

즉, 서버측 소켓에는 socket()-bind()-listen()을 관장하는 서버 소켓 1개와 실제 연결 대상(클라이언트 소켓)과 연결accept() 되고 소통을 진행하는 소켓 N개로 이루어 지게 된다.

(이 때 N개의 소켓들도 각각의 포트번호를 부여받게 될 것이다… 정확하진 않다!)

그리고 이 소켓들의 정보는 디스크립터 테이블에 기록된다.


📢 Socket vs Web Socket

당연히 소켓이 훨씬 더 포괄적이고 일반적인 개념이다.

소켓은 애플리케이션 계층과 전송 계층 사이의 의사소통을 돕는 개념이고, 웹 소켓은 그 중에서도 브라우저, HTTP 프로토콜의 단점 보완에집중한 개념이다.

웹 소켓은 일반적으로 TCP/IP를 통해 실행되는 HTTP와 유사한 프로토콜(ws(WebSocket), wss(WebSocket Secure))을 통해 Application Server에 연결하는 브라우저에서 실행된다.

HTTP와 별개의 프로토콜을 사용하기 때문에 하나의 포트번호로 HTTP 요청과 웹 소켓 요청을 모두 수용할 수 있게 되는 것으로 보인다.

댓글남기기