TCP/IP 프로토콜
공부 배경
얼마 전, 좋은 기회를 통해 백엔드 개발자로 실무에서 일하고 있는 선배님을 만나뵙게 되었다. 여러 질문을 하던 중, 어떤걸 공부하면 좋을지 또 알아야할지를 여쭈어 보았다. 여러개가 있었지만 그 중 백엔드 개발자라면 인터넷 프로토콜에 대해 공부해볼 필요가 있다고 하셨고, 그래서 이를 바로 실천해보았다.
인터넷
전세계에 걸쳐 파일 전송 등의 데이터 통신 서비스를 받을 수 있는 컴퓨터 네트워크 시스템.
데이터를 디지털 신호로 바꾸어 전달하고 받은 데이터 신호를 다시 데이터로 바꿔 네트워크 통신.
네트워크 통신을 위해 미리 정해놓은 공통된 메뉴얼을 프로토콜이라고 한다.
TCP/IP란?
인터넷에서 컴퓨터들이 서로 정보를 주고 받는데 쓰이는 프로토콜의 집합.
Application Layer: 특정 서비스를 위해 애플리케이션끼리 정보를 주고 받을 수 있음.
ex) FTP, HTTP, SSH, Telnet, DNS , SMTP
Transport Layer: 송신된 데이터를 수신측 애플리케이션에 확실하게 전달.
네트워크 통신을 하는 애플리케이션은 포트번호를 사용하게 되는데 Transport Layer는 포트번호를 사용해서 애플리케이션을 찾아준다.
ex) TCP, UDP, RTP, RTCP
Internet Layer: 수신측까지 데이터를 전달하기 위해 사용
송신측 수신측 모두 IP주소를 가지고 있음.
ex) IP, ARP, ICMP, RARP, OSPF
Network Access Layer: 네트워크에 직접 연결된 기기간 전송을 할 수 있도록 한다.
여기서는 물리적 주소인 MAC 주소를 사용한다.
ex) Ethernet, PPP, Token Ring
www.google.com을 웹브라우저에 입력하면?
해당 요청을 인터넷을 통해 구글 서버로 보내기 위해서는 패킷을 만들어야 한다. 패킷에는 각 계층에 필요한 정보들이 담겨야 한다.
Client
Application Layer
Transport Layer
TCP 패킷의 헤더 정보에는 여러가지가 있지만 SP(Source Port)
와 DP(Destination Port)
를 주로 보겠다. SP와 DP는 시작포트와 목적지 포트번호를 말한다.
SP(시작 포트 번호)는 컴퓨터에서 만든 소켓의 포트번호이므로, 당연히 내 컴퓨터는 이를 알고 있다.
DP(목적지 포트번호) 또한 80
으로 우리는 알고있다. 80은 웹서버의 웰 노운(Well known) 번호이다.
Internet Layer
여기서도 중요한 정보는 SA(Source Address)
시작 IP주소와 DA(Destination Address)
목적지 IP주소이다.
나의 시작 IP주소(SA)는 알고 있지만, 목적지 IP주소는 모른다. 알고있는 것은 ‘www.google.com’이라는 도메인(domain) 주소만 알고있다. 하지만 우리는 DNS 프로토콜을 통해 이 도메인 주소로 목적지 IP 주소
를 알아낼 수 있다.
DNS 프로토콜
- DNS 서버의 주소는 이미 컴퓨터에 등록이 되어있다.
- HTTP와 같은 Application Layer프로토콜이다.
- 53번 포트를 사용한다.
DNS도 Http Request와 비슷하게 도메인이 담긴 쿼리를 도메인 서버로 보낸다. 그럼 도메인 서버가 IP주소를 응답해 준다.
DNS는 Transport Layer에서 UDP라는 프로토콜을 사용한다.
UDP
UDP는 비연결지향형 프로토콜이다. TCP와 다르게 헤더정보가 간단하다. 포트번호만 있다.
연결 지향형인 TCP 와 비연결 지향형인 UDP에 대해 추후에 설명하겠다.연결 지향형 TCP vs 비연결 지향형 UDP
Network Access Layer
Ethernet 프로토콜에 대한 헤더 정보를 만들어야 하는데 우리는 아직 MAC주소를 모른다.
Google 웹 서버의 MAC주소가 필요할까?
이전까지는 우리가 목표인 구글서버에 대한 정보가 필요했는데, 그러면 MAC주소도 우리의 목적지인 구글 웹서버의 MAC주소가 필요할까?
여기서 MAC주소는 구글의 MAC주소 대신 물리적으로 연결된 우리집 공유기의 MAC주소가 필요하다. 이 공유기를 통해 다른 네트워크와 연결이 가능한데, 이를 게이트 웨이라고 부른다.(netstat -rn 명령어를 통해 게이트웨이의 IP주소를 확인할 수 있다.) 우리는 ARP 프로토콜을 통해 게이트웨이의 IP주소로 MAC주소
를 얻을 수 있다.
이로써 클라이언트가 데이터를 요청하는데 필요한 패킷이 모두 준비되었다.
요청을 보내기 이전에…
TCP
TCP 프로토콜은 연결 지향형 프로토콜이다. 데이터를 전송하기 전에 송신측과 수신측이 서로 연결되는 작업이 필요하다. 이때 TCP 헤더에 표시된 플래그가 사용되고, 이러한 작업을 3 Way HandShaking
이라고 한다.
- Client측에서 접속을 요청하는
SYN
플래그가 설정된 패킷을 보낸다. - 그러면 Sever측에서 요청을 수락하는
ACK
와SYN
플래그를 보낸다. - 마지막으로 Client측이 이를 확인하는 ACK플래그를 보내면 연결이 이뤄지고 데이터가 오갈수 있게 된다.
Http의 요청과 응답과정이 끝나면 연결을 종료하는데에도 TCP플래그가 사용되고, 이 단계에는 ACK
와 FIN
플래그가 사용된다. 연결을 종료하는 작업을 4 Way HandShaking
이라고 한다.
- Client가 Server로 연결을 종료하겠다는
FIN
플래그를 전송한다. - Server는 Client에게
ACK
플래그를 보내고, 자신의 통신이 끝날때 까지 기다린다. - Server가 통신이 끝나면 Client에게로
FIN
플래그를 보낸다. - Clent는 다시 확인했다는 의미로
ACK
플래그를 보낸다.
여기서 한가지 문제가 발생할 수 있는데, 서버가 FIN
플래그를 보내기 전에 보냈던 데이터가 FIN
플래그보다 늦게 도착하는 경우이다. Client가 서버로 부터 FIN
을 수신했다고 바로 연결된 소켓을 닫아버리면 FIN
을 보내기전에 보낸 패킷은 영영 Client가 받을 수 없게 된다.
그래서 Client는 Server로 부터 FIN
요청을 받더라도, 일정 시간동안 소켓을 닫지않고 혹시나 아직 도착하지 않은 잉여 패킷을 기다리는데, 이를 TIME-WAIT
상태라고 한다.
NAT(Network Address Translation)
추가적으로, 내가 사용하는 컴퓨터는 Private IP를 사용한다. 이 Private IP는 외부의 네트워크 환경에서 IP주소를 찾아가지 못한다. 그래서 공유기에서 내보낼때 Private IP주소를 Public IP주소로 변환해서 내보내는 작업이 필요한데 이를 NAT라고 한다.
ARP 프로토콜
우리집 공유기를 거치고 나서 구글 서버에 도착하기 위해 네트워크와 네트워크를 연결해주는 여러 라우터(Router)를 거치게 된다.(라우터가 목적지 경로를 찾아가는 과정을 라우팅(Routing)이라고 한다.)
이러한 라우팅을 거쳐 구글 서버가 연결된 라우터까지 데이터가 도착하면 패킷의 IP헤더에 등록된 구글 서버 IP주소를 통해 MAC 주소를 얻어와야 한다. 이때 사용하는 것이 ARP 프로토콜이다. ARP는 라우터가 연결된 네트워크에 브로드캐스팅된다. 목적지 구글 서버가 자신의 IP로 온 ARP의 요청을 받고 MAC주소를 응답해준다.
Google(Server)
ARP로 IP 주소를 MAC주소를 얻고, 드디어 목적지 구글서버에 데이터가 도착했다. Internet Layer의 IP주소
와, Network Access Layer의 MAC 주소
를 사용해서 올바른 목적지에 도착했으니, Transport Layer에서는 80 포트 번호
를 보고, 이 포트 번호를 사용한고 있는 애플리케이션에게 데이터를 전달해준다. 그럼 Application Layer에서는 웹 서버가 사용될 Http Request
데이터를 얻을 수 있게 된다. 이제 그럼 Server에서 정상적으로 Http Request를 받고 응답을 돌려보낸다. “/”에 매핑된 GET
요청을 처리해서 적절한 HTML을 응답해 줄 것이다.