TCP/IP 4계층(Layer)
TCP/IP는 인터넷 통신을 위한 기본 프로토콜 스위트(Protocol Suite, 프로토콜 모음)입니다. 이는 데이터를 패킷으로 나누어 전송하고, 수신 측에서 이를 받아 재조립하는 과정을 담당합니다. TCP/IP는 네 개의 계층으로 구성되어 있습니다.
이러한 표준을 정립함으로 회사가 다른 장비간에 호환 문제를 해결할 수 있었습니다. 처음에는 이러한 표준을 지키지 않아서 호환이 되지 않았었어요. OSI 7 레이어와 같은 표준을 위한 모델도 있지만 실무에서는 TCP/IP 모델로 설명드리는 것이 좀 더 적합하기에 TCP/IP로 설명을 드리도록 하겠습니다.
웹 통신은 OSI 7 레이어 모델과 TCP/IP 모델 모두를 사용하여 설명할 수 있습니다. 두 모델은 네트워크 통신을 설명하는 다른 방식일 뿐, 실제 통신 프로세스는 동일합니다.
이 과정을 설명하기 위해 편지 예시를 사용해보겠습니다.
송신 측
- 애플리케이션 계층 (편지 작성)
- 긴 편지를 작성합니다. 이는 전송해야 할 큰 데이터를 나타냅니다.
- 트랜스포트 계층 (편지를 페이지로 나누기)
- TCP: 편지를 일정한 크기의 페이지로 나눕니다. UDP보다는 느립니다. 신뢰성을 보장합니다.
- UDP: 편지를 나누되, 페이지 크기가 일정하지 않을 수 있습니다. TCP보다는 빠릅니다. 신뢰성을 보장하지 않습니다.
- 인터넷 계층 (봉투에 넣어 주소 붙이기)
- 각 페이지를 봉투에 넣고, 봉투에 받는 사람 주소 (IP 주소)를 씁니다.
- 네트워크 인터페이스 계층 (편지 발송)
- 봉투를 우체국 (라우터)에 전달하여 발송합니다.
수신 측
- 네트워크 인터페이스 계층 (편지 수신)
- 봉투를 받습니다.
- 인터넷 계층 (봉투에서 페이지 꺼내기)
- 봉투를 열어 페이지를 꺼냅니다.
- 트랜스포트 계층 (페이지 재조립)
- TCP: 페이지 번호 (시퀀스 번호)를 사용하여 페이지를 원래 순서대로 재조립합니다.
- UDP: 페이지를 받은 순서대로 재조립합니다. 순서가 바뀌거나 페이지가 유실될 수 있습니다.
- 애플리케이션 계층 (편지 읽기)
- 재조립된 편지를 읽습니다. 이는 수신된 데이터를 처리하는 것을 나타냅니다.
특징 요약
- 인터넷에 관련된 다양한 프로토콜의 집합을 총칭합니다.
- 우리가 배웠던 HTTP는 TCP/IP 중 하나입니다. HTTP는 데이터의 교환을 담당하는 애플리케이션 계층에 속합니다.
- HTMP, FTP, SNMP, TCP, IP, UDP 등이 ‘TCP/IP’에 포함됩니다.
7.1 TCP/IP 4계층(Layer)
- 4계층 - 애플리케이션 계층: 사용자와 직접 상호작용 하는 계층으로 수신하거나 송신할 데이터를 생성합니다. 이 계층에서는 웹 브라우저, 이메일 클라이언트, 메신저 등의 애플리케이션이 동작하며, 사용자가 입력한 데이터나 애플리케이션이 생성한 데이터를 송신하거나, 수신한 데이터를 사용자에게 표시합니다.
HTTP, FTP 등의 프로토콜이 이 계층에 속합니다. Python의 soket 모듈을 사용하면 FTP, HTTP, SMTP 등 다양한 애플리케이션 계층 프로토콜을 직접 구현할 수 있습니다. 하지만 이런 프로토콜들은 이미 잘 구현된 라이브러리 또는 프레임워크가 많이 있으므로 (ftplib
, http.client
, smtplib
등), 이런 라이브러리나 프레임워크를 사용하는 것이 더 일반적입니다.
-
아래 코드는 HTTP를 구현한 예제입니다.
import socket def handle_request(request): headers = request.split('\n') filename = headers[0].split()[1] if filename == '/': filename = '/index.html' try: with open(filename[1:], 'r') as file: content = file.read() response = 'HTTP/1.0 200 OK\n\n' + content # 이 부분이 프로토콜 규칙을 지키는 부분입니다. # 이 규칙(HTTP)을 깨면 브라우저가 데이터를 해석하지 못합니다. except FileNotFoundError: response = 'HTTP/1.0 404 NOT FOUND\n\nFile Not Found' # 이 부분이 프로토콜 규칙을 지키는 부분입니다. return response server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('localhost', 8888)) server_socket.listen(1) print('Server is ready to receive...') while True: connection, address = server_socket.accept() request = connection.recv(1024).decode('utf-8') print(request) response = handle_request(request) connection.sendall(response.encode('utf-8')) connection.close()
import socket def handle_request(request): headers = request.split('\n') filename = headers[0].split()[1] if filename == '/': filename = '/index.html' try: with open(filename[1:], 'r') as file: content = file.read() response = 'HTTP/1.0 200 OK\n\n' + content # 이 부분이 프로토콜 규칙을 지키는 부분입니다. # 이 규칙(HTTP)을 깨면 브라우저가 데이터를 해석하지 못합니다. except FileNotFoundError: response = 'HTTP/1.0 404 NOT FOUND\n\nFile Not Found' # 이 부분이 프로토콜 규칙을 지키는 부분입니다. return response server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('localhost', 8888)) server_socket.listen(1) print('Server is ready to receive...') while True: connection, address = server_socket.accept() request = connection.recv(1024).decode('utf-8') print(request) response = handle_request(request) connection.sendall(response.encode('utf-8')) connection.close()
-
이를 통해 생성된 문자열 예시입니다.
HTTP/1.0 200 OK abcdef
HTTP/1.0 200 OK abcdef
-
3계층 - 트랜스포트 계층(전송 계층): 트랜스포트 계층은 상위 계층인 애플리케이션 계층으로부터 데이터를 받아, 하위 계층인 인터넷 계층으로 전달하는 역할을 합니다. 트랜스포트 계층의 주요 프로토콜은 TCP(Transmission Control Protocol)와 UDP(User Datagram Protocol)입니다.
- TCP (Transmission Control Protocol)
- 연결 지향적 프로토콜입니다.
- 데이터의 신뢰성, 순서, 무결성을 보장합니다.
- 데이터 전송 속도는 UDP보다 느리지만, 데이터 손실이 없어야 하는 애플리케이션(예: 이메일, 파일 전송 등)에 적합합니다.
- 3-way handshake를 통해 연결을 설정합니다.
- 흐름 제어, 혼잡 제어, 오류 제어 등의 기능을 제공합니다.
- 혼잡 제어를 하여 안전하게 데이터 흐름을 보장합니다. 야구에서 상대방이 준비된 것을 사인으로 확인하고 공을 차례차례 던지는 것과 같습니다.
- UDP (User Datagram Protocol)
-
비연결 지향적 프로토콜입니다.
-
TCP에 비해 간단하고 빠르지만, 데이터의 신뢰성을 보장하지 않습니다.
-
데이터의 순서나 무결성도 보장하지 않습니다.
-
실시간 스트리밍, 온라인 게임 등 속도가 중요하고 일부 데이터 손실이 허용되는 애플리케이션에 적합합니다.
-
혼잡 제어를 하지 않아 상대방이 받을 준비가 되었는지 확인하지 않고 보냅니다. 야구에서 상대방이 있는 것만 확인하고 사인 없이 계속해서 공을 던지는 것과 같습니다. 상대방이 공을 못받았어도 다음 공을 그냥 던집니다.
-
-
python 코드로는 아래와 같이 표현 가능합니다.
# python 프로그래밍에서는 아래와 같이 socket에 정의되어 있습니다. server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # TCP server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
# python 프로그래밍에서는 아래와 같이 socket에 정의되어 있습니다. server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # TCP server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
-
TCP 세그먼트가 잘려지는 예시입니다. 각 세그먼트의 크기를 4바이트로 가정하고, 출발지 포트는 1234, 목적지 포트는 80, 시퀀스 번호는 각 세그먼트의 첫 바이트 위치라고 가정하겠습니다.(UDP는 애플리케이션 계층에서 받은 데이터 그대로 헤더만 추가(데이터그램)가하여 전송)
-
원본
HTTP/1.0 200 OK abcdef
HTTP/1.0 200 OK abcdef
-
세그먼트 1
출발지 포트: 1234 목적지 포트: 80 시퀀스 번호: 1 확인 응답 번호: 0 데이터: "HTTP"
출발지 포트: 1234 목적지 포트: 80 시퀀스 번호: 1 확인 응답 번호: 0 데이터: "HTTP"
-
세그먼트 2
출발지 포트: 1234 목적지 포트: 80 시퀀스 번호: 5 확인 응답 번호: 0 데이터: "/1.0"
출발지 포트: 1234 목적지 포트: 80 시퀀스 번호: 5 확인 응답 번호: 0 데이터: "/1.0"
-
세그먼트 3
출발지 포트: 1234 목적지 포트: 80 시퀀스 번호: 9 확인 응답 번호: 0 데이터: " 200"
출발지 포트: 1234 목적지 포트: 80 시퀀스 번호: 9 확인 응답 번호: 0 데이터: " 200"
-
세그먼트 4
출발지 포트: 1234 목적지 포트: 80 시퀀스 번호: 13 확인 응답 번호: 0 데이터: " OK\\n"
출발지 포트: 1234 목적지 포트: 80 시퀀스 번호: 13 확인 응답 번호: 0 데이터: " OK\\n"
-
세그먼트 5
출발지 포트: 1234 목적지 포트: 80 시퀀스 번호: 17 확인 응답 번호: 0 데이터: "\\nabc"
출발지 포트: 1234 목적지 포트: 80 시퀀스 번호: 17 확인 응답 번호: 0 데이터: "\\nabc"
-
세그먼트 6
출발지 포트: 1234 목적지 포트: 80 시퀀스 번호: 21 확인 응답 번호: 0 데이터: "def"
출발지 포트: 1234 목적지 포트: 80 시퀀스 번호: 21 확인 응답 번호: 0 데이터: "def"
이 예시에서는 TCP 헤더의 주요 필드인 출발지 포트, 목적지 포트, 시퀀스 번호, 확인 응답 번호만 포함하였습니다. 실제 TCP 헤더에는 이외에도 헤더 길이, 플래그, 윈도우 크기, 체크섬 등의 필드가 포함됩니다. 각 세그먼트는 TCP 헤더와 데이터로 구성되며, 시퀀스 번호는 세그먼트의 첫 바이트 위치를 나타냅니다. 이렇게 구성된 세그먼트는 인터넷 계층으로 전달되어 IP 패킷에 encapsulation됩니다. 수신 측에서는 시퀀스 번호를 사용하여 세그먼트를 재조립하고, 최종적으로 원래의 HTTP 응답 데이터를 복원합니다.
-
- TCP (Transmission Control Protocol)
-
2계층 - 네트워크 계층(인터넷 계층): 네트워크상에서 패킷의 이동을 다룹니다. 여러 가지 길 중에서 하나의 길을 결정하는 것이 네트워크 계층의 역할입니다.
-
패킷 : 전송하는 데이터의 최소단위(IP 헤더 + TCP 세그먼트)
-
패킷이 만들어지는 예시는 아래와 같습니다.
-
IP만 알아도 어느 정도 국가와 지역을 알 수 있습니다. 내 ip 주소 확인을 검색해보세요. python에서는 pygeoip와 같은 라이브러리로 확인이 가능합니다.
-
IPv4 주소에서 사용할 수 있는 IP는 43억개로 우리가 필요한 IP 갯수에 한참 부족합니다. 이러한 고갈 문제를 해결하기 위해 NAT, IPv6 등 여러 해결책이 나옵니다.
-
IP 패킷 1:
버전: IPv4 헤더 길이: 20바이트 서비스 유형 (ToS): 0x00 전체 길이: 40바이트 식별자: 0x1234 플래그: 0x02 (Don't Fragment) 단편화 오프셋: 0 TTL: 64 프로토콜: TCP (0x06) 헤더 체크섬: (계산된 값) 출발지 IP 주소: 192.168.0.1 목적지 IP 주소: 192.168.0.2 TCP 세그먼트: 출발지 포트: 1234 목적지 포트: 80 시퀀스 번호: 1 확인 응답 번호: 0 데이터: "HTTP"
버전: IPv4 헤더 길이: 20바이트 서비스 유형 (ToS): 0x00 전체 길이: 40바이트 식별자: 0x1234 플래그: 0x02 (Don't Fragment) 단편화 오프셋: 0 TTL: 64 프로토콜: TCP (0x06) 헤더 체크섬: (계산된 값) 출발지 IP 주소: 192.168.0.1 목적지 IP 주소: 192.168.0.2 TCP 세그먼트: 출발지 포트: 1234 목적지 포트: 80 시퀀스 번호: 1 확인 응답 번호: 0 데이터: "HTTP"
-
IP 패킷 2:
버전: IPv4 헤더 길이: 20바이트 서비스 유형 (ToS): 0x00 전체 길이: 40바이트 식별자: 0x1234 플래그: 0x02 (Don't Fragment) 단편화 오프셋: 0 TTL: 64 프로토콜: TCP (0x06) 헤더 체크섬: (계산된 값) 출발지 IP 주소: 192.168.0.1 목적지 IP 주소: 192.168.0.2 TCP 세그먼트: 출발지 포트: 1234 목적지 포트: 80 시퀀스 번호: 5 확인 응답 번호: 0 데이터: "/1.0"
버전: IPv4 헤더 길이: 20바이트 서비스 유형 (ToS): 0x00 전체 길이: 40바이트 식별자: 0x1234 플래그: 0x02 (Don't Fragment) 단편화 오프셋: 0 TTL: 64 프로토콜: TCP (0x06) 헤더 체크섬: (계산된 값) 출발지 IP 주소: 192.168.0.1 목적지 IP 주소: 192.168.0.2 TCP 세그먼트: 출발지 포트: 1234 목적지 포트: 80 시퀀스 번호: 5 확인 응답 번호: 0 데이터: "/1.0"
나머지 IP 패킷도 유사한 구조로 구성됩니다.
-
-
-
1계층 - 링크 계층(데이터 링크 계층/네트워크 인터페이스 계층): 네트워크에 접속하는 하드웨어적인 면을 다룹니다. 이렇게 만들어진 데이터는 수신측으로 전송됩니다.
프리앰블: 10101010 10101010 10101010 10101010 10101010 10101010 10101010 목적지 MAC 주소: 00:11:22:33:44:55 소스 MAC 주소: AA:BB:CC:DD:EE:FF 유형: IPv4 (0x0800) 페이로드: IP 패킷: 버전: IPv4 헤더 길이: 20바이트 서비스 유형 (ToS): 0x00 전체 길이: 40바이트 식별자: 0x1234 플래그: 0x02 (Don't Fragment) 단편화 오프셋: 0 TTL: 64 프로토콜: TCP (0x06) 헤더 체크섬: (계산된 값) 출발지 IP 주소: 192.168.0.1 목적지 IP 주소: 192.168.0.2 TCP 세그먼트: 출발지 포트: 1234 목적지 포트: 80 시퀀스 번호: 1 확인 응답 번호: 0 데이터: "HTTP" FCS: (계산된 값)
프리앰블: 10101010 10101010 10101010 10101010 10101010 10101010 10101010 목적지 MAC 주소: 00:11:22:33:44:55 소스 MAC 주소: AA:BB:CC:DD:EE:FF 유형: IPv4 (0x0800) 페이로드: IP 패킷: 버전: IPv4 헤더 길이: 20바이트 서비스 유형 (ToS): 0x00 전체 길이: 40바이트 식별자: 0x1234 플래그: 0x02 (Don't Fragment) 단편화 오프셋: 0 TTL: 64 프로토콜: TCP (0x06) 헤더 체크섬: (계산된 값) 출발지 IP 주소: 192.168.0.1 목적지 IP 주소: 192.168.0.2 TCP 세그먼트: 출발지 포트: 1234 목적지 포트: 80 시퀀스 번호: 1 확인 응답 번호: 0 데이터: "HTTP" FCS: (계산된 값)
이 예시는 이더넷 프레임의 구조를 단순화하여 설명한 것으로, 실제 이더넷 프레임에는 VLAN 태그, 우선순위 정보 등 추가적인 필드가 포함될 수 있습니다.
-
참고사항
OSI 7계층(표준화 목적) TCP/IP 4계층(실용성) 응용 계층 응용 계층 표현 계층 응용 계층 세션 계층 응용 계층 전송 계층 전송 계층 네트워크 계층 인터넷 계층 데이터링크 계층 네트워크 액세스 계층 물리 계층 네트워크 액세스 계층
7.1.1 정보를 감싸는 캡슐화를 통해 계층간 정보 전달
7.1.2 Response(응답)과 Request(요청) 과정
- 이미지 아래 링크를 클릭하시면 크게 보실 수 있습니다.