본문 바로가기
Web/Backend

저는 소켓이 처음이라니까요?

by 조엘 2021. 5. 10.

안녕하세요! 조엘입니다!

 

"처음이라니까요" 시리즈 다섯 번째 주자 바로 소켓입니다. 👏👏

사실 소켓은 처음 접해보는 주제는 아니에요. 

네트워크 시간에 배웠지만, 수업에서 제공해주는 코드를 따라 치기에 급급했던 기억이 나네요. 😅

 

소켓이 무엇이고, 어찌 동작하는지, 그리고 웹에서는 어떻게 소켓을 사용하는지 알아봐요! 💪

 

 

*** 소켓이란? ***

위키피디아에서 정의한 소켓은 다음과 같아요. 

 

네트워크 소켓(network socket)은 컴퓨터 네트워크를 경유하는 프로세스 간 통신의 종착점이다. 오늘날 컴퓨터 간 통신의 대부분은 인터넷 프로토콜을 기반으로 하고 있으므로, 대부분의 네트워크 소켓은 인터넷 소켓이다. 네트워크 통신을 위한 프로그램들은 소켓을 생성하고, 이 소켓을 통해서 서로 데이터를 교환한다. 소켓은 RFC 147에 기술사항이 정의되어 있다.

 

인터넷 소켓은 다음과 같은 요소들로 구성되어 있다.

인터넷 소켓은 크게 두 개의 타입으로 분류할 수 있다.

  • UDP 프로토콜을 사용하는 경우
  • TCP 프로토콜을 사용하는 경우

어려운 용어들이 많이 보이네요! 이를 조금 더 쉽게 풀어쓰자면 다음과 같이 정리할 수 있어요. 

 

1. 네트워크 소켓을 통해 서로 다른 프로세스들이 네트워크를 거쳐 통신을 할 수 있다. 

2. 네트워크 소켓은 대부분 인터넷 프로토콜을 기반으로 하니, 대부분 인터넷 소켓이다. 

3. 인터넷 소켓은 인터넷 프로토콜 / 로컬 IP주소 / 로컬 포트 / 원격 IP주소 / 원격 포트로 식별된다. 

4. 인터넷 소켓은 크게 UDP 프로토콜 / TCP 프로토콜을 사용한다. 

 

새로운 용어인 IP(인터넷 프로토콜)와 UDP/TCP 프로토콜을 아주 간략하게 정리하고 넘어갈게요!

해당 내용에 더 관심있으신 분들은 참조에 있는 글들을 참고하시는 것을 추천드려요. 

 

 

*** IP / UDP & TCP ***

[TCP/IP 4계층에서 Internet Layer 소속]

IP : 인터넷으로 연결된 호스트들간에 데이터 교환을 지원하기 위해 만들어진 프로토콜

Internet Layer : 데이터를 정의하고 데이터의 경로를 배정하는 일을 담당

 

[TCP/IP 4계층에서 Transport Layer 소속]

UDP : 단순히 데이터를 받거나 던져주기만 하는 프로토콜

TCP : 서버와 클라이언트 간에 데이터를 "신뢰성 있게" 전달하기 위해 만들어진 프로토콜

Transport Layer : 도착을 원하는 시스템까지 데이터를 전송하기 위한 일을 하는 계층

 

 

*** 소켓의 동작원리 ***

소켓 통신에서는 2명의 주인공, ClientServer가 필요해요. 

Client와 Server는 자신의 IP Address와 소켓 연결에 할당할 Port Number를 End Point로 삼아요. 

IP Address와 Port Number를 통해 소켓 연결을 기다리고, 수립하고, 통신하게 되어요. 

 

Server는 어떤 포트에서 연결 요청을 받을지 미리 시스템에 등록하여 Client의 요청을 처리하도록 준비해요. 

Client는 해당 Server의 IP Address와 Port Number에 네트워크 연결 수립 요청을 보내요. 

조금 더 자세히 Client와 Server의 소켓 연결을 수립 과정을 살펴볼게요. 💪💪

Client - Server의 소켓 연결 과정

 

[Client 연결 과정]

>> socket() - connect() - write()&read() - close()

socket()

- 소켓 통신을 위해 TCP/UDP 타입을 지정하여 클라이언트 소켓 생성하기

connect()

- IP Address와 Port Number로 식별되는 대상 서버에 연결 요청 보내기

write()&read()

- 연결된 소켓을 통해 데이터를 보낼 때에는 write(), 데이터를 받을 때에는 read()를 사용

- read()를 통해 데이터를 받을 때에는 데이터를 얼마만큼, 언제 받을지 예상할 수 없어 별도의 스레드에서 실행

close()

- 연결된 소켓과의 연결 종료

 

 

[Server 연결 과정]

>> socket() - bind() - listen() - accpet() - read()&write() - close()

socket()

- 소켓 통신을 위해 TCP/UDP 타입을 지정하여 서버 소켓 생성하기

bind()

- 인자로 서버 소켓과 Port Number (혹은 IP Address + Port Number)를 전달하여, 해당 서버 소켓이 지정된 Port Number를 시스템 내에서 사용할 것을 운영체제에 요청

  - 만일 이미 시스템 내에서 사용 중인 Port Number라면 에러를 반환

listen()

- Port Number가 바인딩 된 서버 소켓에 클라이언트의 요청이 있는지 확인하며 대기

- 성공적으로 요청을 수신하면 SUCCESS를 반환함

accept()

- 연결 요청을 받아들여 최종적으로 소켓 간 연결을 수립

- 최종적으로 클라이언트 소켓과 연결이 만들어지는 소켓은 앞서 요청을 받는 데 사용한 서버 소켓이 아닌, accept() API 내부에서 새로 만들어지는 소켓과 연결 수립

  - 서버 소켓은 클라이언트의 연결 요청 수신하는 일을 담당하고, 요청을 잘 받으면 서버 소켓이 할 일은 끝

  - 새로 만들어지는 소켓은 위에서 언급한 "인터넷 프로토콜 / 로컬 IP주소 / 로컬 포트 / 원격 IP주소 / 원격 포트"의 정보로 식별

    - 여기서 로컬 포트로는 기존의 서버 소켓에서 쓰던 포트를 사용

- 서버 소켓은 다른 연결 요청을 처리하기 위해 다시 listen() 하거나 close() 함

write()&read()

- 연결된 소켓을 통해 데이터를 보낼 때에는 write(), 데이터를 받을 때에는 read()를 사용

- read()를 통해 데이터를 받을 때에는 데이터를 얼마만큼, 언제 받을지 예상할 수 없어 별도의 스레드에서 실행

close()

- 연결된 소켓과의 연결 종료

 

 

*** 직접 살펴보는 소켓 연결 과정 ***

ssh 원격 연결을 통한 소켓 연결 수립

아마존 EC2 인스턴스와 원격 연결을 하는 과정을 와이어샤크로 패킷 캡처를 해봤어요. 💦💦

여기서 제 IP Address는 192.169.6.219, 아마존 EC2 인스턴스의 IP Address는 15.164.212.226에요. 

TCP 연결이 수립되면서 192.169.6.219:62882 에서 15.164.212.226:22 로의 연결을 요청한 것을 볼 수 있어요. 

 

아마존 EC2 인스턴스에는 22번 포트로 바인딩되어, 클라이언트의 요청을 듣고 있는 서버 소켓이 있을 것이에요. 

클라이언트인 저의 요청을 accept()한 후,

<<192.169.6.219:62882 -- 15.164.212.226:22>> 의 정보를 들고 있는 새로운 소켓을 생성할 것이에요. 

 

연결이 수립된 이후, 아마존 EC2 인스턴스는 22번 포트에서 서버 소켓이 새로운 요청을 받을 수 있도록 클라이언트의 요청을 듣고 있을 거예요. 

 

22번 포트에 여러 개의 연결이 수립된 것을 볼 수 있다

+) 리눅스에서는 소켓을 하나의 파일로 간주해요.

따라서 리눅스 서버에서는 서버에서 열 수 있는 파일의 갯수 만큼 네트워크 소켓 접속을 할 수 있어요. 

 

 

*** 웹에서 소켓은? ***

HTTP 프로토콜은 요청한대로 응답을 보내주기만 하는 단순한 프로토콜이라 실시간 통신을 구현하기 부적절해요. 

웹 서비스에서도 실시간 통신의 필요성이 대두되면서 웹 소켓 프로토콜이 탄생했어요. 

웹 소켓은 연결이 수립되면 클라이언트와 서버가 자유롭게 데이터를 보낼 수 있어요. 

 

ws와 보안이 강화된 wss가 바로 웹 소켓 프로토콜이에요. 

ws는 http와 같이 80 포트를, wss는 https와 같이 443 포트를 사용해요.

 

웹 소켓 핸드쉐이크를 통해 HTTP 프로토콜을 웹 소켓 프로토콜로 변환할 수 있어요. 

다음과 같은 요청과 응답이 오가면 웹 소켓 프로토콜을 사용하게 됩니다. 

 

// 클라이언트 요청 
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

// 서버 응답 
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

 

아직 웹 소켓 프로토콜을 적용해본 적이 없어 이에 대한 내용은 경험을 쌓고 이후 포스팅에서 설명해보도록 할게요!!

 

읽어주셔서 감사합니다~ 🎁🎁

 

 

참고

- recipes4dev.tistory.com/153

- woowacourse.github.io/javable/post/2020-09-20-websocket/

- www.youtube.com/watch?v=Fh1GAi63CfA

- www.joinc.co.kr/w/Site/Network_Programing/Documents/IntroTCPIP

 

 

반응형

댓글