TCP/IP 4 계층으로 알아보는 네트워크의 동작
네트워크 인터페이스 계층(Network Interface Layer)
네트워크 인터페이스 계층은 허브, 스위치 등을 사용하여 동일한 네트워크에서 데이터를 관리하고 전달하는 역할을 한다. 이때 네트워크에 연결된 각각의 기기를 식별하기 위해 MAC 주소를 사용한다. 데이터를 전송하려는 기기의 MAC 주소를 알지 못하는 경우 컴퓨터는 ARP 프로토콜을 사용해 IP 주소를 가지고 MAC 주소를 획득한다.
ARP 프로토콜은 크게 세 단계로 나뉜다. 우선 데이터를 전송하려는 컴퓨터 A는 같은 허브나 스위치에 묶여있는 모든 기기에게 특정 IP 주소를 아는지 물어보는데(ARP request), 그러면 연결된 기기는 자신의 IP를 요청 받은 IP와 비교하게 된다. 만약 일치하는 기기 B가 존재할 경우 해당 기기는 자신의 MAC 주소를 응답한다(ARP response). 이후 컴퓨터 A는 B의 IP와 MAC을 ARP 테이블에 저장한다. 이후로 B와 통신할 일이 생기면 ARP request를 다시 하는 것이 아닌 ARP 테이블에 저장된 MAC 주소를 참고하게 된다.
특정 기기에만 데이터를 전송하는 것이 불가능한 허브와 달리, 스위치는 MAC 테이블을 사용하여 연결된 기기의 MAC 주소를 관리한다. 이를 통해 컴퓨터 A가 B에게 보내는 request가 다른 컴퓨터에게 전달되지 않도록 하는데 이를 MAC 주소 필터링이라고 부른다.
인터넷 계층(Internet Layer)
인터넷 계층은 라우터를 사용해 서로 다른 네트워크에서 데이터를 전송할 수 있도록 하는 역할을 한다. 이때부터는 본격적으로 WAN의 영역에 들어서게 되는데, 다른 기기와 통신하기 위해 MAC 주소 대신 IP 주소를 사용한다. IP 주소는 네트워크 ID와 호스트 ID로 구분되는데, 클래스 A, B, C에 따라 네트워크 ID와 호스트 ID의 범위가 달라진다.
AWS를 예로 들어보자면 내 VPC는 10.3.0.0/16 이라는 주소를 가지고 있다. 이때 16은 서브넷 마스크로서 전체 32비트 중 앞의 16개가 네트워크 ID이며, 나머지 16개가 호스트 ID라는 의미이다. 서브넷은 전체 주소 중에서 호스트 ID를 다시 서브넷 ID와 호스트 ID로 분리하게 되는데, 내 서브넷은 10.3.1.0/24와 10.3.2.0/24 두 개가 있다. VPC의 호스트 ID 16 비트 중에서 8비트를 다시 서브넷 ID로 사용한 것이다.
호스트 ID는 8비트인 만큼 해당 서브넷에 256 개의 IP를 할당할 수 있을 것처럼 보인다. 하지만 실제로는 254개만 할당할 수 있다. 호스트 ID의 가장 앞 주소는 서브넷 네트워크 주소이며, 가장 마지막 주소는 브로드캐스트 용도로 예약되어있기 때문이다.
+ 다른 네트워크에 데이터를 전송하기 위해 IP 주소를 사용하지만, 실제로는 MAC 주소 역시도 필요하다. 내 컴퓨터에서 라우터의 MAC 주소를 알아야 하며, 라우터는 데이터를 전달할 또 다른 라우터의 MAC 주소를 알아야 한다. 이렇게 MAC 주소가 적혀있는 헤더를 갈아끼우면서 나아간다.
전송 계층(Transport Layer)
전송 계층은 데이터를 목적지까지 문제 없이 전달하는 것을 목표로 한다. 여기에는 데이터를 전달하는 목적에 따라 TCP 프로토콜(연결형 통신, 데이터를 손실 없이 전달하는 것이 목표)과 UDP 프로토콜(비연결형 통신, 데이터를 최대한 빠르게 보내는 것이 목표)로 나뉜다. UDP는 주로 실시간 방송 등 여러 대의 기기에 한 번에 동일한 데이터를 전달하는 데 사용된다.
TCP 프로토콜은 3 way handshake를 사용해 통신을 시작한다. 이는 데이터를 주고 받는 두 기기가 실제로 데이터를 주고받을 준비가 되어있는지를 확인하는 과정이다.
1) 송신자는 수신자에게 SYN과 Window_Size를 전송한다. SYN은 3 way handskake를 위한 랜덤한 숫자이고, Window_Size는 송신자가 한 번에 보낼 수 있는 데이터 크기이다. 2) 이를 받은 수신자는 SYN, ACK, Window_Size를 보낸다. 이때 수신자가 보내는 Window_Size는 수신자가 한 번에 받을 수 있는 데이터 크기를 나타내며, SYN은 송신자가 보낸 것이 아니라 새로운 값이다. ACK는 송신자의 SYN에 1을 더한 값으로, 통신이 제대로 이루어졌음을 확인하기 위해 돌려보내는 값이다. 3) 송신자는 이를 받고 수신자의 SYN에 1을 더해서 ACK를 보낸다.
이러한 과정을 통해 두 기기는 서로가 통신을 할 준비가 되어있음을 확인할 뿐 아니라, 서로 보내거나 받을 수 있는 최대 데이터 크기를 확인함으로써 커다란 데이터를 가능한 적은 수의 세그먼트로 쪼개고, 한 번에 가능한 많은 데이터를 문제 없이 전송할 수 있다.
응용 계층
일반적으로 서비스를 요청하는 쪽을 클라이언트, 제공하는 측을 서버라고 한다. 응용 계층에서는 클라이언트와 서버가 서로 다른 포트와 프로토콜을 사용해 서비스를 주고받는다. 주로 사용되는 프로토콜의 경우 포트 번호가 정해져있는 경우가 많으며 HTTP(80), HTTPS(443), FTP(20, 21), POP3(110) 등이 사용된다.
종합적인 네트워크 요청
크롬 검색창에 google.com을 입력하고 엔터를 누르면, 내 컴퓨터는 로컬 라우터의 MAC 주소와 알고있는 DNS 서버의 IP를 사용해 DNS 질의를 시작한다. 로컬 라우터는 DNS 서버의 MAC 주소를 알지 못할 확률이 높지만, 라우팅 테이블을 사용해 DNS 서버의 MAC 주소를 알고 있는 라우터가 누구인지 알아내고, 이것이 연속적으로 진행되며 최종적으로는 DNS 서버와 연결된 라우터까지 도달할 것이다.
라우터와 DNS 서버 역시 MAC 주소로 통신하고, DNS 서버는 또 다시 DNS 질의를 위해 여기저기 다른 DNS 서버에게 google.com의 IP 주소를 알고 있는 DNS 서버를 찾아다닐 것이다. 그리고 마침내 google.com의 IP 주소를 알아낸 DNS 서버는 이 정보를 다시 내 컴퓨터로 보내준다.
이제 내 컴퓨터는 google 서버의 IP 주소로 3 way handshake를 위해 SYN와 Window_Size 가 포함된 요청을 보낸다. 구글 쪽에서 이 요청을 잘 받았으면 새로운 SYN과 함께 ACK, Window_Size를 보내줄 것이다. 내 컴퓨터는 ACK를 보내고, 문제가 없다면 내 컴퓨터와 구글 서버는 통신을 할 준비가 끝난다.
내가 요청한 페이지는 google.com/index.html이므로, 구글 서버는 해당 페이지를 찾아서 내게 보내준다. 이때 사용하는 프로토콜은 HTTPS이며, 포트 번호는 443이다. 구글 서버는 미리 알고 있는 Window_Size를 사용해 데이터를 적당한 크기로 자르고, 순차적으로 전송한다. 내 컴퓨터는 세그먼트 하나를 받을 때마다 잘 받았다고 응답을 보내며, 구글도 이 응답을 받아야 다음 세그먼트를 전송한다.
모든 세그먼트가 도착하면, 짜잔, 이제 내 컴퓨터는 google.com/index.html에 존재하는 html 파일이 어떻게 생겨먹었는지 알게 되었다. 이후로는 웹브라우저의 랜더링이 시작되는 것이다.
블로그의 정보
Ayden's journal
Beard Weard Ayden