google.com에 접속해보자 (TCP 연결 과정)

요약

이 글은 TCP/IP 연결이 어떻게 진행되는지를 간단히 살펴본다.

사실 google.com에 접속해보자는… 제목만 그런거다.

그 대신, 각 OSI 7계층이 어떤 역할을 담당하는지 설명한다.

참고

용어 설명

계층 구조

계층구조는 역할 분담을 나누며, 자신의 일말을 처리하고 각 계층별 인터페이스를 지키며 독립적 동작을 가능하게 만든다.

계층 구조는 네트워크(OSI 7계층) 외에도, 다른곳에서도 찾을 수 있다

  • 예를들어 서버는, 애플리케이션-OS-하드웨어 3계층으로 나눌 수 있다

프로토콜

서로 소통하기 위해 정한 규약

TCP/IP 프로토콜 외에도, USB 프로토콜(마우스-PC 연결 등), CPU안에서 사용하는 프로토콜등 다양하다.

TCP/IP

1969년 ARPANET부터 시작된 인터넷의 역사 초기에는 
여러 대학, 연구기관에서 운용하던 수많은 독자 프로토콜이 있었으나
상호 접속을 위해 국제 규격을 만들고자 했고 결국 TCP/IP가 표준이 되었다

TCP/IP는, TCP 프로토콜IP 프로토콜의 집합이다.

다양한 Node가 존재하는 인터넷에서 신뢰성이 필요하며, TCP 프로토콜은 신뢰도 높은 전송을 담당한다.

그러나 TCP는 필수적이지 않으며, IP는 통신상대 지정시에 IP 주소를 이용하기에 필수적이다.

TCP/IP 계층 구조

이제 OSI 7계층을 TCP/IP 4계층 모델로 나누고 각각을 알아보자

애플리케이션 계층 (HTTP)

애플리케이션이 없으면 통신도 없다.

* 애플리케이션 계층 프로토콜은 직접 통신을 하는게 아니라, 모두 OS에 위임한다.

HTTP의 경우 client process가 요청을 보낼때

  1. client process는 커널에 TCP/IP로 통신하기 위해 socket() 오픈 call한다.
  2. IP주소와 TCP 포트의 정보를 가지고,  상대 서버와 가상의 경로(socket)이 열린다.
  3. 애플리케이션이 write 시스템 콜을 호출하여 데이터를 보낸다 (socket에 데이터를 기록한다)

process 관점에서 봤을때, 물리적인 회선등을 고려하지 않고 연결된 socket에 데이터를 기록하면 상대 프로그램은 socket을 통해 데이터를 읽을 수 있다.

전송 계층 (TCP)

전송 계층은, socket에 기록된 데이터 전달을 위해 TCP 프로토콜은 ‘데이터를 상대에게 확실히 전달’을 담당한다.

상대 서버로 실제 전송하는 부분은 하위 계층인 IP 계층에게 위임한다.

  1. socket에 기록된 데이터는 큐를 경유해 커널내 네트워크 처리 부분에 전달된다.
  2. 커널에서 전달된 데이터는 송신용 send socket buffer 뒷부분에 추가 된다.
    • 수신용 receive socket buffer도 존재한다
  3. 이 데이터에 TCP 헤더(데이터 시퀀스, 상대 포트 등…)를 붙여 TCP 세그먼트(하나의 단위)를 만든다
  4. IP 계층으로 보낸다

상대 서버에 도착했을때, 포트번호를 이용하여 알맞는 애플리케이션에 전달한다

참고로 netstat -nap 명령어를 확인하면 ‘Recv-Q’, ‘Send-Q’ 정보가 있는데 각 소켓의 송/수신 큐 바이트수 정보이다.


주요 기능
  • 데이터 보증과 재전송 제어
    • 수신 측에 TCP 세그먼트가 도착하면 수신 측은 송신측에 도착했다는 것을 알린다 (이때 반환하는것을 ACK)
    • ACK이 돌아오지 않으면, 언제든 재전송이 가능하도록 TCP 세그먼트를 소켓 버퍼에 남겨 둔다.
  • 데이터 순서 보증 (TCP 세그먼트내의, 시퀀스 번호)
  • 흐름제어 폭주제어
  • 연결 생성 (TCP는 연결형 프로토콜, 연결이라 불리는, 가상 경로를 생성)

3-way handshaking

가상 경로 생성을 위해, server process는 OS에게 80 port에 통신 요청이 오면 자신에게 전달해 달라하며 기다리는데, 이를 LISTEN하고 있다 한다

위와 같이 상대가 LISTEN하고 있을때, 그 유명한 3-way handshaking을 거쳐 client와 server사이의 소켓이 연결된다.

  1. 클라이언트가 통신 상대인 서버측 OS에게 가상 경로 오픈을 의뢰하며 SYN 패킷 전송
  2. 서버측 소켓은 LISTENING상태이기에 ACK +SYN 패킷 응답.
  3. 클라이언트도 다시 ACK 패킷으로 응답하며 서버의 새로운 소켓이 생성되며 연결(ESTABLISHED)된다

더 자세한 내용은 링크 참고


모든 요청은 실제 물리적 회선을 거쳐 이루어지며, TCP 통신을 시작할때 상대와 연결을 열어 달라고 요청을 할 뿐이다.

데이터 전송은 IP 계층이 담당하기에, 실제 물리적인 문제가 생기거나, 상대 서버가 꺼져도 가상 경로인 TCP 연결은 끊기지 않는다.

  • 이럴때 정상적으로 통신되지는 않지만 TCP 연결은 유지된다. (비정상종료)
  • 다만 KeepAlive 설정등을 통해, 일정 시간(대부분 3600초) 동안 통신이 없으면 연결이 닫힌다.

* 서버는 미리 지정한 포트 번호가 있지만, 클라이언트측 포트는 자동적으로 OS가 할당한다.

물런, 클라이언트가 소켓 connect() 하기전에 bind()를 통해 지역포트를 직접 할당 가능하다

네트워크 계층 (IP 프로토콜)

지정한 서버까지 전달받은 데이터를 전달하는것을 담당한다.

  1. TCP 세그먼트에 IP 헤더(서버 IP 주소 포함)를 붙여, IP 패킷을 생성
  2. IP 헤더를 덧붙인 후, 데이터 링크 계층으로 보낸다

주요 기능
  • IP 주소를 이용해 최종 목적지 전송
  • 라우팅
    • 대상 서버는 다른 네트워크 상에 있을 수 있다.
    • 이럴 경우, 최종 목적지까지 도달할때까지 목적지를 알고 있는 여러 라우터를 거친다.

데이터 링크 계층 (이더넷 프로토콜)

링크 계층 프로토콜을 간단히 말하자면 ‘동일 네트워크내의 네트워크 장비까지 전달받은 데이터를 운반’이다.

* 데이터 링크 계층의 프로토콜은 이더넷이 대표적이며, 무선 랜 프로토콜등이 있다

  1. IP패킷에 이더넷 헤더,푸터를 붙여 이더넷 프레임을 만든다 (패킷은 완성)
    • 헤더, 푸터에는 링크 계층 주소인, MAC주소 포함
  2. OS가 버스를 통해 NIC(Network Interface Card)에게 전달
  3. NIC는 이를 다시 네트워크에 전송

* 만약 다른 네트워크에 있다면, 기본 게이트웨이에 패킷을 보내게 된다

* 기본 게이트웨이는 외부 네트워크에 접속되어 있어 다른 네트워크로 패킷을 보낼 수 있다

그 후

이렇게 전송한 프레임은, 여러 장치를 거쳐 목적지에 도달하게 된다.

수신 측 NIC에 도착하면 위 과정이 반대로 진행된다

  1. NIC가 패킷을 호스트 메모리에 전송
  2. 이더넷 레이어에서, 확인 후 이더넷 헤더 푸터 제거
  3. IP 레이어에서, 확인 후 IP 헤더 제거
  4. TCP 레이어에서, 확인 후 소켓의 수신 큐 저장 (다른 세그먼트를 기다릴 수 있다)
  5. 애플리케이션 읽기 요청이 있으면 수신 큐 내용 전달

이렇게 TCP/IP를 각 계층을 통해 socket이라는 추상화된 객체에 기록한 데이터가 상대 서버의 socket을 통해 나오게 된다.

물런 우리가 소프트웨어를 개발할때는 socket 객체조차 눈치채지 못하고 개발하고 있을 수도 있다.

C 계열의 언어가 아니라면?


Written by@Juna
I love Node.js