시작하기 전에..
이 책에서 정의한 TCP/IP 모델중 전송계층을 공부한다! 이제 응용계층만 남았다~~!
전송계층은 참고로 면접때 자주 등장하는 TCP와 UDP의 차이점. 그리고 TCP 특징이 중요하다
독서 & 스터디
패드로 시작해서... 집에서는 컴퓨터로 보고, 이동시에는 폰으로 보다가 결국 노트북으로 이번 챕터도 정독했다
그리고 또 한빛미디어의 도메인 주도 개발 - 최범균 책에 꽂혀서 보고 있다 2년전에 나온 책인데 이것도 정말 좋은 내용을 담고있다
백엔드로 개발하시는 분들은 한번쯤 읽어보면 좋겠다. 대신 DDD, 아키텍처, 멀티모듈 이런거에 너무 파묻히지만 않으면 베스트다
네트워크 계층의 IP 한계 -> 전송 계층 필요
네트워크 계층의 IP 한계
- 신뢰할 수 없는 통신
- 비연결성 통신
전송 계층 역할
- 신뢰할 수 있는 통신
- 연결형 통신
- 포트번호를 통해 응용 계층의 애플리케이션 프로세스 식별
신뢰할 수 없는 통신과 비연결형 통신
네트워크 계층의 핵심 프로토콜 IP
- 특징
- IP 단편화
- IP 주소지정
- 한계
- 비신뢰성 프로토콜(unreliable protocol)
- 비연결형 프로토콜(connectionless protocol)
신뢰할 수 없는 통신
- 패킷이 수신지까지 제대로 전송되었다는 보장을 하지 않음
- 통신 과정(최선형 전달: best effort delivery) - '최선을 다하지만, 전송 결과에 대해서는 어떠한 보장도 하지 않겠다'
- 패킷의 데이터가 손상/중복 전송을 확인하지 않음
- 재전송 하지 않음
- 순서대로 패킷 도착 보장하지 않음
비연결형 통신
- 송/수신 호스트간 사전 연결 수립 작업을 거치지 않음
- 단순히 수신지를 향해 패킷을 보냄
IP(Internet Protocol)은 왜 어떠한 보장도 없이 신뢰할 수 없는 비연결형 통신을 할까?
- '성능'때문. 모든 패킷이 제대로 전송되었는지 일일이 확인하고
호스트 간 연결을 수립하는 작업은 일반적으로 패킷의 '빠른' 송수신과는 배치되는 작업
- 더 많은 시간/대역폭/부하가 요구 -> 성능상 악영향
- 인터넷상의 패킷의 종류와 개수는 매우 다양
1. 금융 서비스: 신뢰성 있는 전송을 보장해야 함
2. 동영상 서비스/실시간 영상 통화: 한두 개의 패킷 손실은 감수하더라도 빠른 전송 우선
conc) 신뢰성 있는 전송이 모든 경우에 필요한 것은 아님!
IP의 한계를 보완하는 전송 계층
1. 전송 계층: 연결형 통신 가능
- 연결형 프로토콜인 TCP(연결 수립/종료 과정 존재)
2. 전송 계층: 신뢰성 있는 통신 가능
- TCP는 패킷이 수신지까지 올바른 순서대로 전달되는 것을 보장하기 위해 재전송을 통한 오류 제어, 흐름 제어, 혼잡 제어를 제공
3. 높은 성능을 위해 신뢰할 수 없는 통신, 비연결형 통신을 지원하는 프로토콜이 필요하다면?
- UDP 사용
응용 계층과의 연결 다리, 포트
포트의 정의
- port: 패킷이 실행중인 특정 애플리케이션까지 전달되기 위해 특정 어플리케이션을 식별할 수 있는 정보
포트의 분류
- 전송 계층에서는 포트 번호(port number)를 통해 특정 애플리케이션을 식별
- 패킷 내 수신지 포트와 송신지 포트를 통해 송/수신지 호스트의 애플리케이션을 식별
- 사용가능한 포트의 수 2^16 = 65536개(0~65535)
- 대분류
포트 종류 | 포트 번호 범위 |
잘 알려진(웰노운)/시스템 포트(well known port/system port) | 0~1023 |
등록된 포트(registered port) | 1024~49151 |
동적/사설/임시 포트(dynamic port/private port/ephemeral port) | 49152~65535 |
- well known port(잘 알려진 포트)
Well known port | Description |
20, 21 | FTP |
22 | SSH |
23 | Telnet |
53 | DNS |
67, 68 | DHCP |
80 | HTTP |
443 | HTTPS |
- registered port(등록된 포트)
Registered port | Description |
1194 | OpenVPN |
1433 | Microsoft SQL Server 데이터베이스 |
3306 | MySQL 데이터베이스 |
6379 | Redis |
8080 | HTTP 대체 |
인터넷 할당 번호 관리 기관(IANA: Internet Assigned Numbers Authority)
- well known port, registered port를 관리하는 국제 단체
- https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml
- 포트 번호 예시는 권고일 뿐, 강제 사항은 아님
서버와 클라이언트 포트 사용 차이
- 서버
- 서버 프로그램은 일반적으로 well known port/registred port로 동작하는 경우가 많다
- 즉, 서버로서 동작하는 프로그램의 포트 번호는 사전에 암묵적으로 정해진 경우가 많다
- 클라이언트
- 클라이언트 프로그램은 동적포트 번호(49152~65535) 중에서 임의의 번호가 할당되는 경우가 많다(ex: 웹 브라우저)
- 웹 브라우저를 통해 특정 웹 사이트에 접속하는 상황을 생각해보자
- [ 웹 브라우저 <-> 서버 프로그램 ] 서로 패킷을 주고 받는 것과 같음
- 이때 웹 브라우저 프로그램에는 동적 포트 내의 임의의 포트 번호가 자동으로 할당
IP주소 + Port번호로 특정 호스트에서 실행중인 특정 애플리케이션 프로세스 식별
192.168.0.15:8000
- IP주소(192.168.0.15): 호스트 식별
- 포트번호(8000): 애플리케이션 프로세스 식별
컴퓨터에서 실행되는 프로세스의 포트 번호 확인 실습
- 여기부분은 책 부분하고 다르게 진행했다
- 나는 파이어폭스로 https://www.google.com에 접속하는 상황을 만들었다
- 책에서는 linux, macOS면 netstat 명령어를 입력하라고 했는데.. 이상하게 netstat에서는 포트번호가 나오지 않았다
- 그래서 ps 명령어와 lsof, nslookup 명령어 3개와 조합으로 찾아봤다
ps aux | head -n 1 \
&& ps aux | grep /Applications/Firefox.app/Contents/MacOS/firefox | head -n 1
- 설명
1. && 로 일단 2개 명령어를 이어서 실행한다(앞에꺼가 성공하면 뒤에꺼 실행)
2. ps aux로 모든유저(a), 사용자친화적출력(u), 백그라운드프로세스포함(x)를 출력
2-1. 메뉴만 출력하기 위해 head -n 1
3. 다음줄로 명령어를 이어서 작성하기 위해(1줄로 처리되기 위해서) \ 백스페이스
4. 다시 같은 명령어를 실행하는데 firefox가 위치해있는 애플리케이션의 프로세스의 정보중 맨 위에꺼만 출력한다
lsof -Pan -p 59795 -i
- 설명
1. lsof 명령어 사용. -Pan옵션으로 포트번호와 호스트명이 나오도록 한다
2. 이전 명령어에서 얻은 pid를 포트인자(-p)로 넘긴다
3. -i 옵션으로 네트워크 파일을 필터링한다
nslookup 34.107.243.93
- 설명
1. 우리는 https://www.google.com으로 접속했다. https의 포트번호는 well-known 포트: 443
2. 그럼 2번째 결과에서 나온 결과에서 443 포트의 ip가 현재 요청서버 ip
3. nslookup 명령어로 ip에서 dns 정보를 역으로 조회한다
어쨌든 결과적으로 클라이언트인 firefox는 55795 포트를 사용 중이다. 즉 동적 포트 범위중에서 유휴(가능)한 포트를 할당 받았다
패킷을 요청하는 서버는 443 포트(잘 알려진 포트-https)로 요청을 한다는 사실을 볼 수 있다
위와 같이 명령어를 잘 조합하면 원하는 결과를 필터링하면서 쉽게 얻어낼 수 있다!ㅎㅎ
맨 처음 명령에서 메뉴를 출력하기 위해 굳이 ps aux 를 사용하지 않고, ps u를 사용했어도 됐다
포트 기반 NAT
NAT
- IP 주소를 변환하는 기술
- 주로 (내부망)사설 IP 주소 <-> 공인 IP주소(외부망)를 변환하는데 사용
NAT 변환 테이블
- 네트워크 외부와 네트워크 내부에서 사용하는 IP가 매핑되어있는 테이블
- 한계점)단순히 1:1로 매핑을 하면 네트워크 내부에서 사용중인 사설 IP 주소 수만큼 공인 IP 주소가 필요
네트워크 외부 | 네트워크 내부 |
1.2.3.4 | 192.168.0.5 |
1.2.3.5 | 192.168.0.6 |
... | ... |
NAPT
- 포트 기반의 NAT를 NAPT(Network Address Port Translation)이라 함
- APT(Address Port Translation)이라고도 부름
- IP 주소 쌍과 더불어 포트 번호도 함께 기록하고, 변환함
- 같은 1.2.3.4라는 공인 IP 주소로 변환되더라도 포트 번호에 따라 내부 IP를 구분지을 수 있음
- 포트를 사용함으로써 다수의 사설 IP 주소를, 그보다 더 적은 수의 공인 IP 주소로 변환 가능
- (N: 1) - (네트워크 내부 IP 주소 개수 : 네트워크 외부 IP 주소 개수)
네트워크 외부 | 네트워크 내부 |
1.2.3.4:6200 | 192.168.0.5:1025 |
1.2.3.4:6201 | 192.168.0.5:1026 |
... | ... |
[포트 포워딩]
- 포트 포워딩(port forwading): 네트워크 내 특정 호스트에 IP 주소와 포트 번호를 미리 할당하고, 해당 IP 주소:포트번호로써 해당 호스트에게 패킷을 전달하는 기능
- ex) 네트워크 내부의 여러 호스트(각각 다른 사설 IP주소 사용)가 같은 공인 IP 주소를 공유하는 상황
처음 패킷을 보내는 네트워크 외부 호스트 입장에서는 어떤 IP주소(및 포트)를 수신지 주소로 삼을지 결정하기 어려움 - 특정 IP 주소와 포트 번호 쌍을 특정 호스트에게 할당 한 뒤, 외부에서 통신을 시작할 호스트에게 해당 접속 정보(IP 주소:포트 번호 쌍)을 알림
- 주로 네트워크 외부에서 네트워크 내부로 통신을 시작할 때, 네트워크 내부의 서버를 외부에서 접속할 수 있도록 접속 정보를 공개하기 위해 자주 사용
[ICMP]
- IP의 신뢰할 수 없는 전송/비연결형 전송 특성을 보완하기 위한 네트워크 계층의 프로토콜(전송 계층 x)
- ICMP(Internet Control Message Protocol)
- IP 패킷의 전송 과정에 대한 피드백 메시지(ICMP 메시지)를 얻기 위해 사용하는 프로토콜
- ICMP 메시지 종류
- 전송 과정에서 발생한 문제 상황에 대한 오류 보고
- 네트워크에 대한 진단 정보(네트워크상의 정보 제공)
- ICMP 메시지 형태
- 타입(type) - 메시지 유형(번호로 명시)
- 코드(code) - 구체적 메시지 내용(번호로 명시)
- ICMP 메시지 Type
타입 이름(타입 번호) | 코드 번호 | 코드 설명 |
수신지 도달 불가 (3) : 특정 패킷이 수신지까지 도달할 수 없음 |
0 | 네트워크 도달 불가 |
1 | 호스트 도달 불가 | |
2 | 프로토콜 도달 불가(수신지에서 특정 프로토콜을 사용할 수 없음) | |
3 | 포트 도달 불가 | |
4 | 단편화가 필요하지만 DF가 1로 설정되어 단편화 할 수 없음 | |
시간 초과 (11) | 0 | TTL 만료 |
ex) 라우터에게 전달된 패킷의 TTL 필드가 0이 되면 해당 라우터는 송신지 호스트에게 [시간 초과 타입 - TTL 만료 코드] ICMP 패킷 전송
- ICMP 메시지 Code
타입 이름(타입 번호) | 코드 번호 | 코드 설명 |
에코 요청(8) | 0 | 에코 요청 |
에코 응답(0) | 0 | 에코 요청에 대한 응답 |
라우터 광고(9) | 0 | 라우터 광고; 라우터가 호스트에게 자신을 알림 |
ex) traceroute, tracert: 네트워크상의 간단한 문제 진단 및 테스트를 위해 사용됨(ICMP 메시지 기반으로 동작)
ex) ping: 네트워크의 상태를 진단하는 기본 명령어(ICMP의 에코 요청, 에코 응답 메시지를 기반으로 구현)
- 유의점: ICMP는 IP의 신뢰성을 보장해주지 않는다(단순히 '도우미'역할을 할뿐. 신뢰성을 위해서는 전송 계층의 프로토콜 필요)
TCP와 UDP
TCP(Transmission Control Protocol)
- 신뢰할 수 있는 통신
- 연결형 프로토콜
- 3-way handshake / 4-way handshake
- 재전송
- 오류/흐름/혼잡 제어
UDP(User Datagram Protocol)
- 신뢰할 수 없는 통신
- 비연결형 프로토콜
TCP 통신 단계와 세그먼트 구조
TCP 통신 3단계
- 연결을 수립하고, 종료가 되기 전까지 데이터가 송수신 되는 과정에서 오류/흐름/혼잡 제어 등의 기능을 제공
MSS
- MSS(Maximum Segment Size)
- TCP로 전송할 수 있는 최대 페이로드 크기
- MSS 크기를 계산할 때 TCP 헤더 크기는 제외 <-> MTU는 헤더의 크기까지 포함
TCP 세그먼트 구조
- 송신지 포트(source port) / 수신지 포트(destination port)
- 송신지 또는 수신지 애플리케이션을 식별하는 포트 번호가 명시되는 필드
- 순서번호(sequence number)
- 순서 번호가 명시되는 필드
- 순서번호: 송수신되는 세그먼트의 올바른 순서를 보장하기 위해 세그먼트 데이터의 첫 바이트에 부여되는 번호
- 확인 응답 번호(acknowledgement number)
- 상대 호스트가 보낸 세그먼트에 대한 응답
- 다음으로 수신하기를 기대하는 순서 번호가 명시
- 제어 비트(control bits)
- 플래그 비트(flag bits)라고도 부름
- 현재 세그먼트에 대한 부가정보를 나타냄
- 윈도우(window)
- 수신 윈도우의 크기가 명시
- 수신 윈도우: 한 번에 수신하고자 하는 데이터의 양
제어 비트
- 기본적으로 8비트로 구성(CWR, ECE, URG, ACK, PSH, RST, SYN, FIN)
- 좀 더 자세한 설명은 http://www.ktword.co.kr/test/view/view.php?no=2437 여기 나와있다
- TCP의 기본 동작을 설명할때 가장 자주 언급되는 세 개의 제어 비트
- ACK: 세그먼트의 승인을 나타내기 위한 비트
- SYN: 연결을 수립하기 위한 비트
- FIN: 연결을 종료하기 위한 비트
- 'ACK 비트가 1로 설정된 세그먼트' == 'ACK 세그먼트'라고 편의상 표현
순서 번호와 확인 응답 번호
- TCP의 신뢰성을 보장하기 위해 사용되는 중요한 필드
- 순서 번호: 시퀀스 넘버 / 확인 응답 번호: ACK 넘버 라고 표현하기도 함
- 초기 순서 번호(ISN: Initial Sequence Number): 처음 통신을 위해 연결을 수립한 때(SYN 플래그가 1로 설정될 때)는 순서번호는 무작위 값이 됨
- 이후 데이터를 송신하는 동안 순서 번호는 ISN + 떨어진 바이트 수로 누적(송신한 바이트를 더해감)
- 확인 응답 번호: 순서 번호에 대한 응답. 일반적으로 '수신한 순서 번호 + 1'로 설정
- 확인 응답 번호 값을 보내기 위해서는 제어 비트에서 ACK 플래그를 1로 설정해야 함
TCP 연결 수립과 종료
연결 수립: 3-way handshake(쓰리 웨이 핸드쉐이크)
송수신 방향 | 세그먼트 | 세그먼트에 포함된 주요 정보 | 비유 |
A -> B | SYN | - 호스트 A의 ISN(초기 순서 번호) - 1로 설정된 SYN 비트 |
"연결 시작합시다." |
B -> A | SYN + ACK | - 호스트 B의 ISN(초기 순서 번호) - 호스트 A가 전송한 세그먼트에 대한 ACK 번호(확인 응답 번호) - 1로 설정된 SYN 비트 - 1로 설정된 ACK 비트 |
"네. 확인했습니다." "연결 시작합시다!" |
A -> B | ACK | - 호스트 A의 다음 순서 번호 - 호스트 B가 전송한 세그먼트에 대한 ACK 번호 - 1로 설정된 ACK 비트 |
"네. 확인했습니다." |
- Active Open(액티브 오픈)
- 처음 연결을 시작하는 호스트의 연결 수립 과정
- 연결을 처음 요청하는 측의 동작
- 주로 클라이언트에서 수행
- 위의 그림에서는 호스트 A의 동작
- Passive Open(패시브 오픈)
- 연결 요청을 받고 나서 요청에 따라 연결을 수립해 주는 과정
- 주로 서버에서 수행
- 위의 그림에서는 호스트 B의 동작
연결 종료: 4-way handshake(포 웨이 핸드쉐이크)
- 3-way handshake를 통해 연결을 수립한 뒤 데이터 송수신이 끝났다면, 연결을 종료해야 한다
송수신 방향 | 세그먼트 | 세그먼트에 포함된 주요 정보 | 비유 |
A -> B | FIN | - 1로 설정된 FIN 비트 | "연결 끊을게요." |
B -> A | ACK | - 호스트 A가 전송한 세그먼트에 대한 ACK 번호(확인 응답 번호) - 1로 설정된 ACK 비트 |
"네. 확인했습니다." |
B -> A | FIN | - 1로 설정된 FIN 비트 | "이제 연결 끊어요." |
A -> B | ACK | - 호스트 B가 전송한 세그먼트에 대한 ACK 번호 - 1로 설정된 ACK 비트 |
"네. 확인했습니다." |
- Active Close(액티브 클로즈)
- 먼저 연결을 종료하려는 호스트에 의해 수행
- 위의 그림에서는 호스트 A의 동작
- Passive Close(패시브 클로즈)
- 종료 요청을 받아들이는 호스트에 의해 수행
- 위의 그림에서는 호스트 B의 동작
TCP 상태
- 상태(state): 현재 어떤 통신 과정에 있는지를 나타내는 정보
- 상태를 유지하고 활용한다는 점에서 TCP는 스테이트풀(stateful) 프로토콜이라고도 불림
- 상태는 크게 3가지로 분류
- 연결이 수립되지 않은 상태
- 연결 수립 과정에서 주로 볼 수 있는 상태
- 연결 종료 과정에서 주로 볼 수 있는 상태
상태분류 | 주요 상태 |
1 | CLOSED, LISTEN |
2 | SYN-SENT, SYN-RECEIVED, ESTABLISHED |
3 | FIN-WAIT-1, CLOSE-WAIT, FIN-WAIT-2, LAST-ACK, TIME-WAIT, CLOSING |
연결이 수립되지 않은 상태
- CLOSED
- 아무런 연결이 없는 상태
- LISTEN
- 일종의 연결 대기 상태
- 일반적으로 서버로서 동작하는 패시브 오픈 호스트는 LISTEN 상태를 유지
- SYN 세그먼트를 기다리는 상태
- 액티브 오픈 호스트(Client)가 LISTEN 상태인 패시브 오픈 호스트(Server)에게 SYN 세그먼트를 전송하면 3-way handshake 시작
연결 수립 상태
- SYN-SENT
- Active Open host가 SYN 세그먼트를 보낸 뒤 그에 대한 응답인 SYN + ACK 세그먼트를 기다리는 상태
- 연결 요청을 보낸 뒤 대기하는 상태
- SYN-RECEIVED
- Passive Open host가 SYN + ACK 세그먼트를 보낸 뒤 그에 대한 ACK 세그먼트를 기다리는 상태
- ESTABLISHED
- 연결이 확립되었음을 나타내는 상태
- 데이터를 송수신할 수 있는 상태
- 3-way handshake 과정에서 두 호스트가 마지막 ACK 세그먼트를 주고받으면 ESTABLISHED 상태가 됨
연결 종료 상태
- FIN-WAIT-1
- 일반적인 TCP 연결 종료 과정의 첫 단계, 상태
- FIN 세그먼트와 함께 연결 종료 요청을 보낸 Active Close host는 FIN-WAIT-1 상태가 됨
- CLOSE-WAIT
- 종료 요청인 FIN 세그먼트를 받은 Passive Close host가 그에 대한 응답으로 ACK 세그먼트를 보낸 후 대기하는 상태
- FIN-WAIT-2
- FIN-WAIT-1 상태에서 ACK 세그먼트를 받게 되면 FIN-WAIT-2 상태로 변함
- 상대 호스트의 FIN 세그먼트를 기다리는 상태
- LAST-ACK
- CLOSE-WAIT 상태에서 FIN 세그먼트를 전송한 뒤 이에 대한 ACK 세그먼트를 기다리는 상태
- TIME-WAIT
- Active Close host가 FIN 세그먼트를 수신한 뒤, 이에 대한 ACK 세그먼트를 전송한 뒤 접어드는 상태
- Passive Close host가 마지막 ACK 세그먼트를 수신하면 CLOSED 상태로 전이하는 반면, TIME-WAIT 상태에 접어든 Active Close host는 일정 시간을 기다린 뒤 CLOSED 상태로 전이
- 일정 시간을 기다리는 이유: 상대 호스트가 받았어야 할 ACK 세그먼트가 올바르게 전송되지 않았을 수 있기 때문
- CLOSING
- 동시에 연결을 종료하려 할 때 전이되는 상태
- 서로가 FIN 세그먼트를 보내고 받은 뒤 각자 그에 대한 ACK 세그먼트를 보냈지만, 아직 자신의 FIN 세그먼트에 대한 ACK 세그먼트를 받지 못했을 때 접어드는 상태
- 양쪽 모두가 연결 종료를 요청하고, 서로의 종료 응답을 기다리는 경우 CLOSING 상태로 접어듦
- ACK 세그먼트를 수신한다면 각자 TIME-WAIT 상태로 접어든 뒤 종료하게 됨
TCP 상태 확인해보기
netstat
맨 앞에 Proto라는 쪽에 보면 tcp4, tcp6인 경우 (state)로 연결 상태를 볼 수 있다
아마 tcp4는 IPv4이고, tcp6는 IPv6 관련인 것 같다
밑에 나올 udp는 udp4가 있고, udp46이 있는데.... 이게 뭐지? 싶어서 chatgpt4o한테 물어봤다
비연결성이기에 UDP는 프로토콜 버전을 명확하게 구분하지 않는다고 한다. 둘다 지원하는 UDP 연결을 의미한단다
UDP & 데이터그램 구조
UDP
- 비연결형 통신을 수행하는 비신뢰성 프로토콜
- TCP처럼 연결 수립/해제, 오류/흐름/혼잡 제어 등을 수행하지 않음
- TCP처럼 상태를 유지하지도 활용하지도 않음
- 스테이트리스(stateless) 프로토콜의 일종
UDP 데이터그램 구조
- 송신지 포트/수신지 포트
- 송수신지의 포트 번호가 담겨있음
- 길이
- 헤더를 포함한 UDP 데이터그램의 바이트가 담김
- 체크섬
- 데이터그램 전송 과정에서 오류가 발생했는지 검사하기 위한 필드
- 수신지는 이 필드의 값을 토대로 데이터그램의 정보가 훼손되었는지를 판단
- 문제가 있다고 판단한 데이터그램은 폐기
- '수신지까지 잘 도착했는지'를 나타내는 신뢰성/비신뢰성과는 관련이 없음!!
UDP 사용처
- TCP에 비해 적은 오버헤드로 패킷을 빠르게 처리
- 실시간 스트리밍 서비스
- 인터넷 전화
- 실시간성이 강조되는 상황에서 TCP보다 더 많이 사용
TCP vs UDP
- TCP: 수신지에 비교적 천천히 하나씩 확실하게 전달
- UDP: 수신지에 빠르게 마구 던지면서 전달(패킷이 손실되거나 패킷의 순서가 바뀔 수 있음)
TCP의 오류/흐름/혼잡 제어
TCP의 신뢰성을 보장하기 위한 기능
- 오류 제어 - 재전송 기법
- 흐름 제어 - 슬라이딩 윈도우
- 혼잡 제어 - 혼잡 제어 알고리즘
오류 제어: 재전송 기법
오류 검출(Error Control)
- TCP 세그먼트에 오류 검출을 위한 checksum 필드로는 신뢰성을 보장하기는 부족
- 체크섬은 세그먼트의 훼손 여부만 나타냄
- 체크섬 값이 잘못되었다면 호스트는 해당 패킷을 읽지 않고 폐기함
- 결국 체크섬을 이용한다고 해도 송신 호스트가 세크먼트 전송 과정에 문제가 있다는 것을 인지할 수 없음
TCP가 신뢰성을 보장하려면?
- 우선 송신 호스트가 송신한 세그먼트에 문제가 발생했음을 인지할 수 있어야 함
- 오류를 감지하게 되면(세그먼트가 잘못 전송되었음을 알게 되면) 해당 세그먼트를 재전송할 수 있어야 함
TCP가 오류를 검출하고 세그먼트를 재전송하는 상황
- 중복된 ACK 세그먼트를 수신했을 때
- 타임아웃이 발생했을 때
- TCP 세그먼트를 송신하는 호스트는 모두 재전송 타이머(retransmission timer) 값을 유지함
- 호스트가 세그먼트를 전송할 때마다 재전송 타이머를 시작
- 이 타이머의 카운트다운이 끝난 상황을 타임아웃이라고 함
RTT
- 메시지를 전송한 뒤 그에 대한 답변을 받는 데 까지 걸리는 시간
- RTT(Round Trip Time)
- ping 명령어로 조회 가능
ARQ: 재전송 기법
- ARQ(Automatic Repeat Request - 자동 재전송 요구)
- 수신 호스트의 답변(ACK)과 타임아웃 발생을 토대로 문제를 진단하고, 문제가 생긴 메시지를 재전송함으로써 신뢰성을 확보하는 방식
- Stop-and-Wait / Go-Back-N / Selective Repeat 3가지 방식 존재
Stop-and-Wait ARQ
- 가장 단순한 방식
- 제대로 전달했음을 확인하기 전까지는 새로운 메시지를 보내지 않는 방식
- 오늘날 인터넷 환경의 TCP에서는 특별한 경우가 아닌 이상 이 방식을 잘 사용하지 않음
- 장점
- 단순하지만, 높은 신뢰성을 보장
- 단점
- 송신 호스트(A) 입장에서 확인 응답을 받기 전까지는 다음 전송을 할 수 있어도 하지 못함
- 수신 호스트(B) 입장에서도 훨씬 더 많은 데이터를 전송받을 수 있음에도 불구하고 한 번에 하나씩만 확인 응답 해야함
- 네트워크 이용 효율이 낮아질 수 있음
- 성능의 저하로 이어질 수 있음
Go-Back-N ARQ
- Stop-and-Wait ARQ의 문제를 해결하기 위해 나온 방식
- 각 세그먼트에 대한 ACK 세그먼트가 도착하기 전이라고 하더라도 여러 세그먼트를 보낼 수 있어야 함
- 연속해서 메시지를 전송할 수 있는 기술인 파이프라이닝(pipelining) 사용
- 오늘날 TCP는 파이프라이닝이 사용되는 Go-Back-N ARQ 또는 Selective ARQ를 기반으로 동작
- 파이프라이닝 방식을 활용해 여러 세그먼트를 전송하고, 도중에 잘못 전송된 세그먼트가 발생할 경우 해당 세그먼트부터 전부 다시 전송하는 방식
- Go-Back-N ARQ에서 순서 번호 n번에 대한 ACK 세그먼트는 'n번만의' 확인 응답이 아니라 'n번까지의' 확인 응답
- 이런 점에서 G-Back-N ARQ의 ACK 세그먼트를 누적 확인 응답(CACK: Cumulative Acknowledgement)라고 함
빠른 재전송(fast retransmit)
- 재전송 타이머가 만료되기 전이라도 세 번의 동일한 ACK 세그먼트가 수신되었다면 해당 세그먼트를 곧바로 재전송하는 기능
- 시간 낭비를 줄이며 빠르게 손실된 세그먼트를 재전송함으로써 성능을 높이는 기술
Selective Repeat ARQ
- Stop-and-Wait ARQ의 문제를 해결하기 위해 나온 방식
- 각 세그먼트에 대한 ACK 세그먼트가 도착하기 전이라고 하더라도 여러 세그먼트를 보낼 수 있어야 함
- 연속해서 메시지를 전송할 수 있는 기술인 파이프라이닝(pipelining) 사용
- 오늘날 TCP는 파이프라이닝이 사용되는 Go-Back-N ARQ 또는 Selective ARQ를 기반으로 동작
- 이름 그대로 선택적으로 재전송하는 방법
- Go-Back-N ARQ 송신과정은 한 세그먼트에만 문제가 발생해도 그 후의 모든 세그먼트를 다시 재전송해야 하는 단점 존재
- Selective Repeat ARQ는 수신 호스트 측에서 제대로 전송받은 각각의 패킷들에 대해 ACK 세그먼트를 보내는 방식
- 이런 점에서 Selective Repeat ARQ의 ACK 세그먼트는 개별 확인 응답(SACK: Selective Acknowledgement)
- 송신 호스트는 올바르게 수신받지 못한 ACK 세그먼트가 있는지 검사하고, 만일 응답받지 못한 세그먼트가 존재하면 해당 세그먼트를 재전송
- 오늘날 대부분의 호스트는 TCP 통신에서 Selective Repeat ARQ를 지원
- 두 호스트가 연결을 수립할 때 서로의 Selective Repeat ARQ 지원 여부를 확인
(TCP 세그먼트 헤더의 옵션 필드에 속한 SACK 허용 필드를 통해 파악) - 만약 Selective Repeat ARQ를 사용하지 않을 경우 Go-Back-N ARQ 방식으로 동작
- 두 호스트가 연결을 수립할 때 서로의 Selective Repeat ARQ 지원 여부를 확인
흐름 제어: 슬라이딩 윈도우
송신 버퍼
- 송신할 세그먼트가 저장되는 공간
수신 버퍼
- 수신된 세그먼트가 애플리케이션 프로세스에 의해서 읽히기 전에 임시로 저장되는 공간
버퍼 오버플로(buffer overflow)
- 송신 호스트가 흐름 제어를 고려하지 않고 수신 버퍼의 크기보다 많은 데이터를 전송하면 일부 세그먼트가 처리되지 못함
- 버퍼가 넘치는 이런 문제 상황을 버퍼 오버플로(buffer overflow)라고 함
흐름제어(flow control)
- 파이프라이닝 기반의 GBN/SR ARQ가 정상적으로 동작하려면 반드시 흐름제어를 고려해야함
- 호스트가 한 번에 받아서 처리할 수 있는 세그먼트의 양에는 한계가 있기 때문
- TCP의 흐름 제어: 수신 버퍼의 버퍼 오버플로를 방지하고자 송신 호스트가 수신 호스트의 처리 속도를 고려하며 송수신 속도를 균일하게 유지하는 것(주체: 수신 호스트[ 수신 호스트가 수신 윈도우를 송신 호스트에게 알려주기 때문 ])
- 흐름 제어가 필요하지 않은 경우: Stop-and-Wait ARQ를 사용할 때
- 흐름 제어가 필요한 경우: 나머지 GBN, SR ARQ를 사용할 때
- 흐름 제어를 하기 위해 슬라이딩 윈도우(sliding window)를 사용함
윈도우(window)
- 송/수신 호스트가 파이프라이닝 할 수 있는 최대량
- 윈도우의 크기만큼 확인 응답을 받지 않고도 한 번에 전송이 가능
- 수신 윈도우를 RWND(Receiver WiNDow)라 줄여서 부르기도 함
슬라이딩 윈도우(sliding window)
- 확인 응답 없이도 전송 가능한 윈도우 사이즈(수신 윈도우 크기)가 TCP 세그먼트 내의 윈도우 필드에 명시
- 송신 호스트는 수신 호스트로부터 받은 TCP 헤더의 윈도우 필드를 통해 서로가 정한 처리가능한 속도로 세그먼트를 전송
- n번째 세그먼트를 올바르게 수신했다면, 송수신 윈도우는 오른쪽으로 1칸씩 미끄러지듯 이동
- 파이프라이닝 과정에서 송수신 윈도우는 점차 오른쪽으로 미끄러지듯 움직이게 됨(슬라이딩 윈도우)
- TCP는 흐름 제어를 위해 슬라이딩 윈도우를 사용
혼잡 제어
혼잡(congestion)
- 많은 트래픽으로 인해 패킷의 처리 속도가 늦어지거나 유실될 우려가 있는 네트워크 상황
혼잡 붕괴(congestion collapse)
- 혼잡 상태로 인해 전송률이 크게 떨어지는 현상
혼잡 제어(congestion control)
- 혼잡을 제어하기 위한 기능
- 흐름 제어의 주체: 수신 호스트
- 혼잡 제어의 주체: 송신 호스트
- 송신호스트는 네트워크 혼잡도를 판단하고 혼잡한 정도에 맞춰 유동적으로 전송량을 조절하며 전송
혼잡 윈도우(congestion window)
- 혼잡 없이 전송할 수 있을 법한 데이터 양
- CWND(Congestion WiNDow)라 줄여서 부르기도 함
- 혼잡 윈도우의 사이즈
- 크면 한 번에 전송할 수 있는 세그먼트 수가 많음
- 작다면 한 번에 전송할 수 있는 세그먼트 수가 적음(네트워크가 혼잡한 상황)
적당한 혼잡 윈도우 크기
- 수신 호스트로부터 정보를 받는 수신 윈도우와는 다르게
혼잡 윈도우의 크기는 송신 호스트가 어느 정도의 세그먼트를 전송해야 혼잡을 방지할 수 있는지를 직접 계산하여 알아내야 함 - 적당한 혼잡 윈도우의 크기는 혼잡 제어 알고리즘을 통해 결정 가능
혼잡 제어 알고리즘(congestion control algorithm)
- 혼잡 제어를 수행하는 일련의 방법(로직)
AIMD(Additive Increase/Multiplicative Decrease) 알고리즘
- 가장 기본적인 알고리즘
- 직역: '합으로 증가, 곱으로 감소'
- 혼잡이 감지되지 않는다면 혼잡 윈도우를 RTT(Round Trip Time)마다 1씩 선형 증가
- 혼합이 감지되면 혼잡 윈도우를 절반으로 떨어뜨리는 동작을 반복
- 처음 연결이 수립한 뒤 혼잡 윈도우 크기가 증가되는 속도가 느림
- 혼잡 윈도우가 톱니 모양으로 변화하는 특징
- 혼잡을 제어할 수 있는 가장 기본적인 아이디어이지만, 이것만으로는 혼잡 제어가 이루어지지 않음
- 더 정교하게 만들어진 느린 시작 / 혼잡 회피 / 빠른 회복 3가지 알고리즘이 존재
1. 느린 시작(slow start) 알고리즘
- 혼잡 윈도우를 1부터 시작해 문제없이 수신된 ACK 세그먼트 하나당 1씩 증가시키는 방식
- 결과적으로 혼잡 윈도우는 RTT마다 2배씩 지수적으로 증가
- 느린 시작을 이용하면 혼잡 윈도우의 지수적인 증가를 활용해 초기 전송 속도를 어느정도 빠르게 확보할 수 있음
느린 시작 임계치(slow start threshold)
- 느린 시작 알고리즘을 사용할 때 함께 사용하는 값
- 혼잡 윈도우를 언제까지나 지수적으로 증가시킬 수는 없음
- 혼잡 윈도우가 계속 지수적으로 증가하다보면 언젠가는 혼잡 상황을 마주할 확률이 높아짐
- SSTHRESH(Slow Start THRESHold)라 줄여서 부르기도 함
- 혼잡 윈도우 값이 계속 증가하다가 느린 시작 임계치 이상이 되거나, 타임아웃이 발생생하거나, 세 번의 중복된 ACK 세그먼트가 발생하여 혼잡이 감지되면 다음 세가지 방법 중 하나를 선택
상황 분류 | 방법 |
타임아웃 발생 | 혼잡 윈도우 값을 1로, 느린 시작 임계치를 혼잡이 감지되었을 시점의 혼잡 윈도우 값의 절반으로 초기화한 뒤 느린 시작 전개 |
혼잡 윈도우 >= 느린 시작 임계치 | 느린 시작 종료, 혼잡 윈도우를 절반으로 초기화한 뒤 혼잡 회피 수행 |
세 번의 중복 ACK 발생 | (빠른 재전송 후) 빠른 회복 수행 |
2. 혼잡 회피(congestion avoidance) 알고리즘
- RTT마다 혼잡 윈도우를 1MSS(Maximum Segment Size)씩 증가시키는 알고리즘
- 혼잡 윈도우를 지수적으로 증가시키는 느린 시작과는 달리, 혼잡 윈도우 크기를 선형적으로 증가시킴
- 느린 시작 임계치를 넘어선 시점부터는 혼잡이 발생할 우려가 있으니 조심해서 혼잡 윈도우를 증가시키는 방식
- 느린 시작 임계치 전
- RTT마다 혼잡 윈도우 2배씩 증가
- 느린 시작 임계치 후
- RTT마다 혼잡 윈도우 1MSS씩 증가
- 혼잡 회피 도중 timeout이 발생하면 CWND(혼잡 윈도우) 값은 1로, SSTHRESH(느린 시작 임계치)는 혼잡이 감지된 시점의 CWND 값의 절반으로 초기화한 뒤 다시 느린 시작을 수행
- 혼잡 회피 도중 세 번의 중복 ACK 세그먼트가 발생되었을 때는 CWND 값과 SSTHRESH를 대략 절반으로 떨어뜨린 뒤 빠른 회복 알고리즘을 수행
- 이때 타임아웃이 발생한 세그먼트나 세번의 중복 ACK 세그먼트가 발생한 세그먼트는 재전송
3. 빠른 회복(fast recovery) 알고리즘
- 세 번의 중복 ACK 세그먼트를 수신했을 때 느린 시작은 건너뛰고 혼잡 회피를 수행하는 알고리즘
- 세 번의 중복된 ACK 세그먼트를 수신하면 빠른 재전송과 함께 빠른 회복 알고리즘이 수행됨(빠르게 전송률을 회복하기 위함)
- 빠른 회복 도중 도중 timeout이 발생하면 CWND(혼잡 윈도우) 값은 1로, SSTHRESH(느린 시작 임계치)는 혼잡이 감지된 시점의 CWND 값의 절반으로 초기화한 뒤 다시 느린 시작을 수행
- 중복된 ACK 세그먼트가 수신되면 빠른 회복과 빠른 재전송이 수행된다는 점에서 빠른 재전송 + 빠른 회복을 함께 묶어 혼잡 제어 방식의 일종으로 보기도 함
혼잡 제어 알고리즘 그림 정리
ECN: 명시적 혼합 알림
명시적 혼합 알림(ECN: Explicit Congestion Notification)
- 기존의 혼잡 제어 알고리즘: 혼잡을 제어하기 위해 어느정도의 양을 송신할지 결정하는 것은 오로지 송신 호스트의 몫
- 혼잡 윈도우 계산, 혼잡 윈도우 조정
- 최근의 혼잡 제어 회피: 네트워크 중간 장치(주로 라우터)의 도움을 받는 방법
- 명시적 혼합 알림. ECN
- ECN은 선택적인 기능이므로 이를 지원하는 호스트/지원하지 않는 호스트 존재
- 통신을 주고받는 양쪽 호스트가 ECN 기능을 지원해야 함
- 연결 수립 과정에서 IP/TCP 헤더의 특정 비트들을 사용해 ECN 지원 여부를 확인
- IP 헤더: 서비스 필드 내의 2bits가 ECN으로 사용
- TCP 헤더: 제어 비트의 CWR, ECE가 ECN으로 사용
- ECN을 통한 혼잡 제어
- (송신)호스트 A-> 라우터 -> (수신)호스트 B
- 중간의 라우터가 IP 패킷의 ECN 비트가 11임을 (수신)호스트B로 알림: 라우터에서 혼합 감지
- (수신)호스트 B는 TCP ACK 세그먼트 내의 ECE 비트를 통해 혼합 상태임을 알림 -> (송신)호스트A
- (송신)호스트 A는 CWND(혼잡 윈도우)를 조절
- ECN을 이용하지 않은 혼잡 제어
- 송신 호스트만 혼잡 제어를 수행
- 타임아웃, 중복된 ACK 세그먼트 수신과 같은 문제가 발생한 이후에야 혼잡 제어 수행
- ECN을 이용한 혼잡 제어 ✅
- 수신 호스트의 ACK 세그먼트를 통해 더 빠르게 혼잡 감지 가능
- 일반적으로 타임아웃, 중복된 ACK 세그먼트 수신 이후에야 혼잡을 제어하는 방식에 비해 더 빠름
숙제
Ch.04(04-1) 확인 문제 1번(p.206), (04-2) 확인 문제 2번(p.225) 풀고 설명하기
Q. IP와 연관된 통신 특성으로 알맞은 단어를 <보기>에서 골라 보세요.
신뢰성, 연결형, 비신뢰성, 비연결형
A. 비신뢰성, 비연결형
IP는 비신뢰성과 비연결형이라는 특징을 갖고 있다
이 한계를 극복하기 위해서는 전송 계층의 프로토콜(TCP)가 필요하다!
Q. 다음은 TCP 쓰리 웨이 핸드셰이크 과정을 나타내는 그림입니다. 괄호 안에 들어갈 말을 <보기>에서 골라 보세요.
SYN, ACK, FIN
A. ACK
3-way handsake의 연결 수립에서 세그먼트 종류와 순서
1. A->B: SYN
2. B->A: SYN+ACK
3. A->B: ACK
추가숙제
작업 관리자에서 프로세스별 PID 확인해 보기
MacOS에서는 윈도우의 작업 관리자 대신 활성 상태 보기라는게 있다
여기를 보면 프로그램(프로세스) 이름과 정보들(PID)를 알 수 있다
예를 들어 카카오톡은 684번 PID로 실행중이다!
후기
예전 취준생 시절, 모 기업의 면접의 일화가 생각난다.
그 당시 나는 해놓은 프로젝트가 있으니.. CS 질문을 덜 물어보겠지!?하고 준비를 제대로 안했었다.
그리고 면접관이 전송계층의 TCP에 대해서 물어봤었다. 난 대답을 잘 하지 못했다.
결국 아쉽게도.. 로 시작하는 메일을 받아서 면접에 불합격했다.
속으로 하..차라리 응용계층(WEB쪽에 좀 더 친화적) 질문이었으면.. 하고 아쉬워했던 기억이 난다.
TCP를 공부하게 되면 웹 서버와 데이터베이스 서버가 서로 어떤 방식으로 물리는지(연결되는지)도 궁금하게 되고, 웹 브라우저와 웹 서버가 어떻게 연결되는지 궁금하게 되고... 요즘 뜨고 있는 치지직이라는 플랫폼은 영상 실시간 송출을 위해서 어떤 프로토콜을 사용하는지 등등 이런 것들을 궁금해 하게 된다.
결국 아는 만큼 보이고, 아는 만큼 더 공부해야될 필요성을 느끼게 되는 것이다. (물론 몰라도 공부할 필요성은 느낄 수 있지만..!)
이번에도 되게 깊고, 많이 공부했다! 한 번 할때 한 챕터를 2~3회독 하다보니 나중에 슥 보면 대부분 다 기억날 것 같다.
추후에 이렇게 공부한 CS 지식을 다시 한 번 현업에서 녹여내보고싶다.ㅎㅎ
추가로 슬라이딩 윈도우는 알고리즘으로는 투포인터에서 사용되기도 하고, 카프카 스트림즈에서 사용되는 윈도윙 종류중 하나이다!!
이제 TCP/IP 5계층 기준으로는 응용 계층 1개가 남았고, 실습챕터와 네트워크 심화 부분만 보면 책을 완독하게 된다! 그날까지 달려보자 아잣아잣 아잣!!
책 구매처
https://www.yes24.com/Product/Goods/125830483
'Study > 한빛미디어 - 혼자 공부하는 네트워크' 카테고리의 다른 글
혼공네트 5주차 - 응용 계층(DNS, URI/URL, HTTP Message, HTTP Header, 캐시, 쿠키, 콘텐츠 협상) (0) | 2024.08.13 |
---|---|
혼공네트 3주차 - 네트워크 계층(IP, ARP, 서브넷 마스크, NAT, DHCP, Router, Routing Table) (0) | 2024.07.21 |
혼공네트 2주차 - 물리 계층과 데이터 링크 계층(이더넷, NIC, 허브/스위치) (0) | 2024.07.11 |
댓글