TCP/IP

원정·2025년 4월 3일

네트워크

목록 보기
1/1
post-thumbnail

💰 인터넷


다양한 네트워크 종류와 다양한 컴퓨터가 연결되어 있는 전 세계적인 네트워크

인터넷을 통해 데이터를 디지털 신호로 바꾸어 전달하고, 받은 디지털 신호를 다시 데이터로 바꿔가면서 네트워크 통신이 이뤄진다.

이들이 통신하기 위해서는 TCP/IP(Transmisstion Control Protocol / Internet Protocol) 프로토콜을 이용한다.

인터넷에 연결된 네트워크 종류도 다양하고 사용하는 프로토콜 또한 다양하다.
네트워크는 어떤 프로토콜을 사용하냐에 따라 데이터를 처리하는 효율이 달라지기 때문에 사용 환경에 맞는 다양한 프로토콜이 생겨났다.

💰 TCP/IP


인터넷에서 컴퓨터들이 서로 정보를 주고 받는데 쓰이는 프로토콜의 집합

이러한 문제점을 해결하기 위해 공통적으로 쓸 수 있는 프로토콜이 필요하게 되었는데, 이것이 TCP/IP다.
TCP/IP가 마련됨으로써 네트워크에 연결된 컴퓨터 기종에 상관없이 정보 교환이 가능하게 됐다.

TCP/IP를 지원하는 네트워크에 TCP/IP를 지원하는 소프트웨어가 있는 컴퓨터가 연결됐다면 아무 문제없이 서로 다른 기종이라도 통신이 가능하다.

TCP/IP 프로토콜은 OSI 참조 모델 이전부터 이미 개발됐었다.
따라서 TCP/IP 프로토콜의 계층 구조는 OSI 참조 모델과 일치하지 않는다.
TCP/IP는 5개의 계층 구조로 되어 있고 현재 가장 널리 사용되고 있는 통신 프로토콜이다.

가장 널리 퍼지고 사용되는 프로토콜 중 하나인데도 불구하고 표준을 따르지 않는 이유는 발생 과정에 있다.

초기 네트워크는 다르게 만들어진 컴퓨터, 다른 회사 제품들 그리고 각 컴퓨터의 다른 운영체제 등 복잡한 환경에서 사용되어져야 했고, 각 컴퓨터의 모델마다 통신 방식이 만들어져야 하는 번거로운 상황이었다.

이런 상황에서 국제적인 표준안의 필요성을 느끼고 생각하게 됐지만, OSI 참조 모델은 전 세계적인 표준 기구에서 추진하는 것이었으므로 진척이 더뎠다.

표준안의 확정을 오래 기다릴 수 없는 상황에서 미국 정부가 긴박한 필요성에 의해 만들어낸 것이 바로 TCP/IP다.

그 후 TCP/IP는 계속 발전하여 퍼져나가 가장 널리 쓰이고, 그만큼 다양한 서비스를 갖고 있는 프로토콜이다.

💵 계층 구조

Application Layer

특정 서비스를 제공하기 위해 애플리케이션 끼리 정보를 주고 받을 수 있다.
브라우저와 웹 서버가 HTTP 요청, 응답을 통해 통신하는 걸 예로 들 수 있다.
FTP, HTTP, SSH, Talnet, DNS, SMTP와 같은 프로토콜이 사용된다.

  • FTP: 장치와 장치 간의 파일을 전송하는 데 사용되는 표준 통신 프로토콜
  • SSH: 보안되지 않은 네트워크에서 네트워크 서비스를 안전하게 운영하기 위한 암호화 네트워크 프로토콜
  • HTTP: World Wide Web을 위한 데이터 통신의 기초이자 웹 사이트를 이용하는 데 쓰는 프로토콜
  • SMTP: 전자 메일 전송을 위한 인터넷 표준 통신 프로토콜
  • DNS: 도메인 이름과 IP 주소를 매핑해주는 서버, 예를 들어 www.naver.com에 DNS 쿼리가 오면 [Root DNS] -> [.com DNS] -> [.naver DNS] -> [.www DNS] 과정을 거쳐 완벽한 주소를 찾아 IP 주소를 매핑한다.

Transport Layer

송신자와 수신자를 연결하는 통신 서비스를 제공한다.
네트워크 통신을 하는 애플리케이션은 포트 번호를 사용하게 된다.
포트 번호를 사용해서 애플리케이션을 찾아 주는 역할을 한다.
TCP, UDP, RTP, RTCP와 같은 프로토콜이 사용된다.

  • TCP: 패킷 사이의 순서를 보장하고 연결지향 프로토콜을 사용해서 연결하여 신뢰성을 구축해서 수신 여부를 확인하며 가상회선 패킷 교환 방식을 사용한다.
  • UDP: 순서를 보장하지 않고 수신 여부를 확인하지 않으며 단순히 데이터만 주는 데이터그램 패킷 교환 방식을 사용한다.

Internet Layer

수신 측까지 데이터를 전달하기 위해 사용된다.
송신측, 수신측 모두 IP 주소를 갖고 있다.
IP 주소를 바탕으로 올바른 목적지로 찾아갈 수 있도록 해준다.
상대방이 제대로 받았는지에 대해 보장하지 않는 비연결 지향형적인 특징을 갖고 있다.
IP, ARP, ICMP, RARP, OSPF와 같은 프로토콜이 사용된다.

Network Access Layer

네트워크에 직접 연결된 기기 간 전송을 할 수 있도록 한다.
물리적 주소인 MAC 주소를 사용한다.
Ethernet, PPP, Token Ring과 같은 프로토콜이 사용된다.

💰 TCP/IP 흐름

www.google.com 을 웹 브라우저에 입력하면 무슨 일이 일어날까?

웹브라우저에 www.google.com 을 입력한다는 것은 구글 웹서버의 80포트로 HTTP Request 메세지를 보내는 것이다.

해당 요청을 인터넷을 통해 구글 서버로 전달하기 위해 패킷을 만들어야 한다.
패킷에는 각 계층에 필요한 정보들이 담겨야 한다.

각 계층 별로 HTTP, TCP, IP, Ethernet 프로토콜을 사용한다고 가정해보자.
패킷의 Application Layer에는 HTTP Request가 들어간다.

TCP 패킷의 헤더에서 중요하게 볼 곳은 Source Port(시작 포트 번호)와 Destination Port(목적지 포트 번호)다.
시작 포트 번호는 내 컴퓨터에서 만든 소켓의 포트 번호라서 당연히 내 컴퓨터는 알고 있다.
그리고 목적지 포트 번호 또한 80으로 알고 있다.
80은 웹 서버의 웰 노운 포트 번호다.

💵 DNS를 통한 IP 주소 받아오기

IP 헤더에서 중요한 정보는 Source IP Address(시작 IP 주소)와 Destination IP Address(목적지 IP 주소)다.
나의 시작 IP 주소는 알고 있지만, 목적지 IP 주소는 모르고 www.google.com 이라는 도메인 정보만 알고 있다.
그렇지만 DNS 프로토콜을 통해서 도메인 정보로 IP 주소를 알아 낼 수 있다.

브라우저는 OS에게 도메인에 대한 IP 주소를 알고 싶다고 요청하면 OS에서 DNS 서버로 요청을 보내게 된다.
그럼 OS가 DNS 서버를 어떻게 알고 있을까?

DNS 서버 주소는 이미 컴퓨터에 등록이 되어 있다.

DNS 또한 HTTP와 같은 애플리케이션 계층 프로토콜이고 53번 포트를 사용한다.
DNS도 HttpRequest와 비슷하게 도메인이 담긴 쿼리를 도메인 서버로 보낸다.
그러면 도메인 서버가 IP 주소를 응답해준다.

DNS는 Transport Layer에서 UDP라는 프로토콜을 사용한다.
UDP는 TCP와 다르게 헤더에 포트 번호말고 다른 게 없다.
UDP가 비연결 지향형 프로토콜이기 때문이다.

이제 DNS를 통해 성공적으로 도메인 이름에 대한 IP 주소를 받아왔다.

💵 ARP를 통해 IP 주소로 MAC 주소 받아오기

마지막으로 Ethernet 프로토콜에 대한 헤더를 만들어야 하는데, MAC 주소를 알지 못한다.

IP 주소를 알아보기 위해서는 구글 서버에 대한 정보가 필요했다.
Ethernet 프레임에는 출발지 MAC 주소와 목적지 MAC 주소가 들어가야 한다.
그러면 목적지 MAC 주소에 구글 웹서버의 MAC 주소를 넣어야 할까?

아니다.
MAC 주소는 구글의 MAC 주소 대신 물리적으로 연결된 우리집 공유기의 MAC 주소가 필요하다.
MAC 주소는 최종 목적지가 아닌 첫 번째로 만날 장치의 MAC 주소가 필요하다.

이 공유기를 통해 다른 네트워크와 연결이 가능하니 게이트웨이라 부르기도 한다.
우리는 이미 게이트웨이에 대한 정보를 알고 있다.

Netstat 명령어(netstat -rn)를 통해 확인할 수 있다.

그럼 어떻게 IP 주소로 MAC 주소를 알 수 있을까?

이때 사용하는 것이 ARP 프로토콜이다.
ARP 프로토콜은 IP 주소를 MAC 주소로 바꿔주는 주소 해석 프로토콜이다.

💵 3 Way Handshaking

이제 MAC 주소까지 알아냈으니 패킷이 네트워크 세계로 나갈 준비가 됐다.
하지만 요청을 보내기 전에 한 가지 더 봐야할 게 있다.

바로 TCP가 연결지향형 프로토콜이라는 점이다.
그래서 TCP 프로토콜은 데이터를 전송하기 전에 송신측과 수신측이 서로 연결되는 작업이 필요하다.
이러한 작업을 3 Way Handshaking이라고 부른다.

  • SYN: SYNchronization의 약자, 연결 요청 플래그.
  • ACK: ACKnowledgement의 약자, 응답 플래그.
  • ISN: Initial Sequence Numbers의 약자, 초기 네트워크 연결을 할 때 할당된 32비트 고유 시퀀스 번호.

3 Way Handshaking을 수행하기 위해서는 TCP 헤더에 표시한 플레그들이 사용된다.
이러한 플래그들을 컨트롤 비트라고 부른다.

  1. 클라이언트는 클라이언트의 ISN을 담아 서버에게 SYN 패킷을 보낸다.
  2. 서버는 SYN 요청을 받고, 클라이언트에게 요청을 수락한다는 ACK과 서버의 ISN을 보내며 승인 번호로 클라이언트의 ISN + 1을 보낸다.
  3. 클라이언트는 서버의 ISN + 1 한 값인 승인 번호를 담아 서버에게 다시 ACK을 보낸다.
  4. 이제부터 연결이 이뤄지고 데이터가 오간다.

이제 연결이 성립되었으니, 데이터가 보내질 차례다.

💵 NAT (Network Address Translation)

한 가지 더 부가적인 설명을 하면 내가 사용하는 컴퓨터는 Private IP를 사용하고 있다.
Private IP는 외부의 네트워크 환경에서 IP 주소를 찾지 못한다.
그래서 공유기를 통해 나갈 때 Public IP 주소를 변환하여 나가는 작업이 필요하다.
이러한 작업을 NAT(Network Address Translation)이라고 한다.

💵 라우팅

공유기를 거치고 구글 서버에 도착하기 위해 여러 라우터를 거쳐야 한다.
라우터는 네트워크와 네트워크를 연결해주는 역할을 한다.
라우터가 목적지 경로를 찾아 나가는 과정을 라우팅이라 한다.

💵 데이터 도착 후 과정

브로드 캐스팅(broadcasting): 네트워크에 있는 모든 장치에게 메세지를 전송하는 행위.

라우팅을 거쳐 구글 서버가 연결된 라우터까지 데이터가 도착을 하면 패킷의 IP 헤더에 기록된 구글 서버 IP 주소를 통해 MAC 주소를 얻어와야 한다.
이때 이전에 설명했던 ARP 프로토콜을 사용한다.
이때 ARP는 라우터가 연결된 네트워크에 브로드캐스팅된다.
목적지 구글 서버가 자신의 IP로 온 ARP 요청을 받고 MAC 주소를 응답해준다.
이제 목적지 구글 서버의 MAC 주소를 알았으니, 데이터가 물리적으로 전달될 수 있다.

ARP로 IP주소를 통해 MAC 주소를 얻고 드디어 목적지 구글 서버에 데이터가 도착했다.
Internet IP의 IP 주소와 Network Address Layer의 MAC 주소를 사용해서 올바른 목적지에 도착했으니 Transport Layer의 목적지 포트 번호에는 80번이 적혀있다.
이걸 보고 80번 포트를 사용하고 있는 애플리케이션에게 데이터를 전달해줘야 하는 걸 알 수 있다.

Application Layer 까지 오면 웹 서버가 사용될 HTTP Request 데이터를 얻을 수 있게 된다.
이제 서버에서 정상적으로 HTTP Request를 받고 응답을 돌려보낸다.
"/"에 매핑된 GET 요청을 처리해서 적절한 HTML을 응답해준다.

실제 크롬 개발자 도구를 통해 확인해보면 HTML을 받은 걸 확인할 수 있다.

💵 4 Way Handshaking

FIN: FINish의 약자, 연결 종료 요청 플래그.

HTTP의 요청과 응답 과정이 끝나면 연결을 종료해야 한다.
여기서도 TCP 컨트롤 비트가 사용된다.
이 단계에서는 ACK, FIN 플래그가 사용된다.

  1. 클라이언트가 서버로 연결을 종료하겠다는 FIN 플래그를 전송한다.
  2. 서버는 클라이언트에게 ACK 메세지를 보내고, 자신의 통신이 끝날 때까지 기다린다.
  3. 서버가 통신이 끝나면 클라이언트로 FIN을 보낸다.
  4. 클라이언트는 확인했다는 의미로 서버에게 ACK을 보내면 연결이 종료된다.

총 4단계에 거쳐 진행되고 이걸 4 Way Handshaking 이라고 부른다.

💵 TIME_WAIT

그런데 서버가 FIN을 보내기 전에 보냈던 데이터가 늦게 도착할 경우, 문제가 발생할 수 있다.
서버로 부터 FIN을 수신했다고 클라이언트가 바로 연결된 소켓을 닫아버리면 FIN을 보내기 전에 보낸 패킷은 영영 클라이언트가 받을 수 없게 된다.

그래서 클라이언트는 서버로 부터 FIN 요청을 받더라도 일정시간 동안 소켓을 닫지 않고 혹시나 아직 도착하지 않은 잉여 패킷을 기다린다.
이렇게 4 Way Handshaking 과정이 완료되어도 소켓을 닫지 않고 잉여 패킷을 기다리는 상태를 TIME_WAIT이라고 한다.

💰 신뢰할 수 있는 TCP


TCP는 연결 지향의 신뢰성 있는 프로토콜이다.

요즘 우리는 엄청 큰 데이터를 주고 받기 때문에 한 번에 다 보내긴 어렵다.
그래서 데이터를 잘게 쪼개서 많은 패킷으로 나눠서 보내게 된다.

복잡한 인터넷 환경에서 과연 패킷들이 유실 되지 않고 순서대로 도착할 수 있을까?

이걸 가능하게 해주는 게 프로토콜인 TCP다.
TCP는 흐름 제어, 오류 제어, 혼잡 제어를 통해 신뢰성을 보장한다.

💵 흐름 제어

데이터를 너무 빨리 보내면, 받는 쪽에서 다 처리하지 못할 수도 있다.
TCP는 송신자와 수신자의 속도를 맞추기 위해 흐름 제어를 사용한다.

수신 TCP 프로세스가 송신 TCP 프로세스에게 흐름 제어 메커니즘을 요구한다.
연결이 설정되면, 각 방향으로의 전송을 위한 윈도우 크기가 결정된다.
여기서, 윈도우 크기란 확인을 받기 전까지 송신측이 전송할 수 있는 바이트의 수를 나타낸다.
송신측에 돌아온 확인에는 새로운 윈도우 크기가 포함되어 있으며, 그것은 다음 확인 전까지 전송될 수 있는 바이트의 수를 나타낸다.

쉽게 얘기하면, 윈도우 크기라는 걸 이용해 한 번에 보낼 수 있는 데이터의 양을 정한다.
그리고 수신자는 "이만큼만 보내줘"라고 알려주고, 송신자는 그 범위 안에서만 데이터를 보낸다.
이렇게 하면, 수신자가 감당할 수 있을 만큼만 데이터를 보내게 된다.

💵 오류 제어

인터넷에서는 데이터가 사라지거나, 중복되거나, 순서가 뒤바뀌거나, 깨질 수도 있다.
TCP는 이런 문제를 해결하기 위해 다음과 같은 방법을 사용한다.

  • 각 데이터 조각(세그먼트)마다 순서 번호를 붙여서, 수신자가 순서를 확인할 수 있게 한다.
  • 잘못된 데이터는 재전송 타이머를 사용해 송신자가 세그먼트를 보내면서 타이머를 시작시키고, 해당 세그먼트에 대한 확인이 오기 전에 끝나면 송신자는 세그먼트를 재전송한다.
  • 각 송신 세그먼트에 체크섬 값을 계산하여 포함시켜, 잘못된 세그먼트에 대해 확인을 보내지 않는다.

수신자가 제대로 받지 못하면, 송신자는 다시 보내게 된다.
이렇게 해서 데이터가 빠짐없이, 정확하게 도착하도록 보장한다.

💵 혼잡 제어

혼잡(congestion)은 인터넷의 전부 또는 일부에 과부하가 걸리고, 요구된 트래픽 양만큼 충분한 통신 자원이 없을 때 발생된다.

TCP는 이런 상황을 막기 위해 인터넷에 너무 많은 데이터를 한 번에 보내지 않도록 조절하고, 혼잡이 생겼을 때는 보내는 양을 줄여서 상황을 개선한다.

즉, 인터넷 상태에 따라 데이터를 얼마나 빨리, 얼마나 많이 보낼지 조절한다.

💰 참조

profile
https://wonjung-jang.github.io/ 로 이동했습니다!

8개의 댓글

comment-user-thumbnail
2025년 4월 4일

어렴풋이 알고 있던 내용을 정리해 주셔서 편하게 읽었습니다.

1개의 답글
comment-user-thumbnail
2025년 4월 6일

뭔가 내용과 무관하긴 하지만... 이런 내가 사용하는 환경에 녹아있는 아키텍쳐나, 계층 구조에서 얻는 인사이트가 많은거같아요... OSI 7계층이나, TCP/IP 계층 구조나, 브라우저 아키텍쳐 같은 것들 보면 어떻게 이렇게 설계할 수 있었을까? 하는 생각이 드는거 같아요:) 글도 너무 잘 정리되어서 잘 읽었습니다!

1개의 답글
comment-user-thumbnail
2025년 4월 28일

이해를 했다가도 돌아서면 어려운 네트워크 개념을 정리해주셔서 잘읽었습니다.
공부할 때는 개념만 줄줄 외우다가 현업에서 이런 용어들을 사용하면 어려워서 저두 최근에 책 구매했어요.
읽게 되면 공유해보겠습니다 ㅎㅎ

1개의 답글
comment-user-thumbnail
2025년 4월 30일

네트워크 중 TCP/IP가 가장 중요한 것 같은데 오랜만에 글 보면서 다시 복기할 수 있어서 좋았습니다 ㅎㅎ 좋은 글 감사합니다!

1개의 답글