전송 계층
- 네트워크 계층과 응용 계층 사이에 위치
- 신뢰할 수 있는 통신과 연결형 통신을 가능하게 하여 네트워크 계층 IP의 한계를 보완
- 포트 번호를 통해 응용 계층의 애플리케이션 프로세스들을 식별
신뢰할 수 없는 통신과 비연결형 통신
- IP를 통한 패킷의 전달은 신뢰성이 없는 통신이자 연결을 수립하는 과정이 없는 통신
- 신뢰할 수 없는 (비신뢰성) 프로토콜(unreliable protocol)
- 비연결형 프로토콜(connectionless protocol)
신뢰할 수 없는 통신
- IP 프로토콜이 패킷이 수신지까지 제대로 전송되었다는 보장을 하지 않음
- 최선형 전달(best effort delivery)
- 통신 과정에서 패킷의 데이터가 손상되거나 중복된 패킷이 전송되었더라도 이를 확인하지 않고,
- 재전송도 하지 않으며, 순서대로 패킷이 도착할 것이라는 보장도 하지 않는다는 의미
비연결형 통신
- 송수신 호스트 간에 사전 연결 수립 작업을 거치지 않음
- 그저 수신지를 향해 패킷을 보내기만 할 뿐
IP는 왜 어떠한 보장도 없이 신뢰할 수 없는, 비연결형 통신을 할까?
- 주요한 이유는 성능
- 모든 패킷이 제대로 전송되었는지 일일이 확인하고,
- 호스트 간에 연결을 수립하는 작업은 일반적으로 패킷의 ‘빠른’ 송수신과는 배치되는 작업
- 더 많은 시간, 대역폭, 부하가 요구되고, 이는 곧 성능상 악영향
- 인터넷상에서 돌아다니는 패킷의 종류와 개수는 매우 다양함
- 반드시 신뢰성 있는 전송을 보장해야 하는 경우
- 한두 개의 패킷 손실은 감수하더라도 빠른 전송이 우선시되는 경우
- 이처럼 신뢰성 있는 전송이 모든 경우에 필요한 것은 아님.
- 무조건 좋은 것은 아니고 때로는 성능을 위해 UDP를 하기도 한다.
IP의 한계를 보완하는 전송 계층
- 연결형 통신을 가능하게 함
- 전송 계층의 연결형 프로토콜인 TCP는 이와 유사하게 두 호스트가 정보를 주고받기 전에 마치 가상의 회선을 설정하듯이 연결을 수립 (물리적 X)
- 송수신하는 동안에는 연결을 유지하고, 송수신이 끝나면 연결을 종료
- 신뢰성 있는 통신을 가능하게 함
- 신뢰성 있는 통신 또한 TCP를 통해 가능
- TCP는 패킷이 수신지까지 올바른 순서대로 확실히 전달되는 것을 보장하기 위해
- 재전송을 통한 오류 제어, 흐름 제어, 혼잡 제어 등 다양한 기능들을 제공
- UDP 프로토콜
- 신뢰할 수 없는 통신, 비연결형 통신을 가능하게 하는 전송 계층의 프로토콜
- TCP보다는 비교적 빠른 전송이 가능
- 최근에는 TCP를 거의 사용한다. 기술적인 발달로 TCP로도 UDP만큼의 속도가 나오기 때문이다.
응용 계층과의 연결 다리, 포트
- 포트의 정의
- 패킷의 송수신은 실행 중인 특정 애플리케이션 프로세스까지 전달되어야 함
- 포트(port)
- 4계층에서 사용하는 주소이다.
- 패킷이 실행 중인 특정 애플리케이션의 프로세스(실행 중인 프로그램)까지 전달되려면 패킷에 특정 애플리케이션을 식별할 수 있는 정보가 포함되어 있어야 한다.
- 응용 계층과 연결 다리 역할을 한다.
- Q. 프로세스 ↔ 포트?
- 프로세스
- 실행 중인 프로그램
- 같은 프로그램일지라도 여러 번 실행하면 각기 다른 독립적인 프로세스로 실행
- 각 프로세스는 PID(Process ID)라는 번호로 식별 - 프로세스의 고유한 식별 번호
- 포트의 분류
- 전송 계층에서는 포트 번호를 통해 특정 애플리케이션을 식별
- 패킷 내 수신지 포트와 송신지 포트를 통해 송수신지 호스트의 애플리케이션을 식별
- 전송 계층의 핵심 프로토콜인 TCP와 UDP
- 포트 번호 필드인 송신지 포트 번호와 수신지 포트 번호를 포함
- 포트 번호는 16비트로 표현 가능하며, 사용 가능한 포트의 수는 2^16(65,536)개
- 할당 가능한 포트 번호는 0번부터 65535번까지, 총 65536개가 존재
- 잘 알려진 포트(well known port, system port)
- 등록된 포트(registered port)
- 포트 번호 1024번부터 49151번까지
- 잘 알려진 포트(well known port)에 비해서는 덜 범용적
- 사용하려면 IANA에다가 등록해야 함.
- 흔히 사용되는 애플리케이션 프로토콜에 할당하기 위해 사용
- 동적 포트(dynamic port), 사설 포트(private port), 임시 포트(ephemeral port)
- 포트 번호 49152번부터 65535번까지
- 인터넷 할당 번호 관리 기관에 의해 할당된 애플리케이션 프로토콜이 없음
- 특별히 관리되지 않는 포트 번호인 만큼 자유롭게 사용
- 보통의 경우 잘 알려진 포트와 등록된 포트를 사용한다.
- 잘 알려진 포트와 등록된 포트는 인터넷 할당 번호 관리 기관(IANA)에 의해 할당된다.
- 포트 번호 예시는 권고 사항일 뿐, 강제 사항은 아니다.
- 주로 사용되는 포트
- 서버로서 동작하는 프로그램
- 잘 알려진 포트와 등록된 포트로 동작하는 경우가 많음
- 클라이언트로서 동작하는 프로그램
- 동적 포트 번호 중에서 임의의 번호가 할당되는 경우가 많음
- 예) 웹 브라우저
- 특정 호스트에서 실행 중인 특정 애플리케이션 프로세스 식별
- IP 주소와 포트 번호에 대한 정보로 식별 가능
- IP 주소:포트 번호 형식
포트 기반 NAT
- NAT 변환 테이블
- NAT 변환 테이블(이하 NAT 테이블)에는 변환의 대상이 되는 IP 주소 쌍이 명시
- 예시
- 네트워크 내부에 192.168.0.5라는 사설 IP 주소를 가진 호스트가 있고, 수신지 주소가 10.11.12.13인 네트워크 외부의 호스트에게 패킷을 전송한다고 가정
- 패킷이 NAT 기능을 갖춘 라우터를 거쳐 네트워크 외부로 나가게 되면 패킷의 송신지 주소는 네트워크 외부에서 사용되는 공인 IP 주소인 1.2.3.4
반대의 경우,
- 수신지 주소가 1.2.3.4인 패킷이 네트워크 외부에서 네트워크 내부로 전송되는 상황일 때,
- 이 패킷의 수신지 주소는 NAT 라우터를 거쳐 192.168.0.5
- 변환의 대상이 되는 IP 주소가 일대일로 대응 - 사설 IP 주소 하나당 공인 IP 주소 하나가 대응
- 이 방식만으로 많은 사설 IP 주소를 변환하기에는 무리가 있음
- 사설 IP 주소와 공인 IP 주소가 일대일로 대응된다면 네트워크 내부에서 사용되는 사설 IP 주소의 수만큼 공인 IP 주소가 필요
- 포트 포워딩
- NAPT
- NAPT(Network Address Port Translation) 또는 APT(Address Port Translation)
- 포트 기반의 NAT
- NAPT는 NAT 테이블에 변환할 IP 주소 쌍과 더불어 포트 번호도 함께 기록하고, 변환
- NAPT는 포트를 활용해 하나의 공인 IP 주소를 여러 사설 IP 주소가 공유할 수 있도록 하는 NAT
- 네트워크 내부에서 사용할 IP 주소와 네트워크 외부에서 사용할 IP 주소를 N:1로 관리
- 공인 IP 주소 수 부족 문제를 개선한 기술
- 네트워크 내부의 호스트 192.168.0.5, 192.168.0.6이 공인 IP 주소 1.2.3.4를 공유하며 네트워크 외부 호스트 10.11.12.13에게 데이터를 송신하는 예시
전송 계층에서 가장 중요한 프로토콜은 TCP와 UDP
- TCP(Transmission Control Protocol)
- 신뢰할 수 있는 통신을 위한 연결형 프로토콜 (4.5 정도의 계층)
- UDP(User Datagram Protocol)
- TCP보다 신뢰성은 떨어지지만 비교적 빠른 통신이 가능한 비연결형 프로토콜
TCP 통신 단계와 세그먼트 구조
- TCP는 통신(데이터 송수신)하기 전에 연결을 수립하고 통신이 끝나면 연결을 종료
- 데이터 송수신 과정에서 재전송을 통한 오류 제어, 흐름 제어, 혼잡 제어 등의 기능을 제공
- TCP 통신 단계
- 연결 수립
- 데이터 송수신(04-3에서 학습)
- 연결 종료
- https 기반 애플리케이션 로드밸런서 ALB, TCP/UDP 로드밸런서 NLB
- MSS(Maximum Segment Size) 단위 ( → MTU와 유사)
- MSS란 TCP로 전송할 수 있는 최대 페이로드 크기이다.
- MSS의 크기를 고려할 때 TCP 헤더 크기는 제외
- 3계층에서는 1500바이트에 포함했음, 여기서는 제외
- 헤더의 크기까지 포함했던 단위인 MTU와는 대조적
- 세그먼트를 주고 받는다.
- 예) 애플리케이션에서 5000바이트의 데이터를 보낸다.
- MSS를 넘지 않도록 미리 세그먼트를 잘라서 분할한다.
- 그 상태로 데이터를 보낸다.
- 보통은 MSS값이 1460 바이트이다. (1500 - IP 헤더(20바이트) - TCP 헤더(20바이트))
- MTU에서 쪼개지지 않도록 1460 바이트로 한다.
- TCP의 세그먼트 구조 (암기보다는 특징을 보고 개념을 이해하자)
- 송신지 포트(source port)와 수신지 포트(destination port)
- 송신지 또는 수신지 애플리케이션을 식별하는 포트 번호가 명시되는 필드
- 순서 번호(sequence number)
- 순서 번호 필드에 명시
- 세그먼트의 올바른 송수신 순서를 보장하기 위한 번호
- 순서 번호 - 송수신되는 세그먼트 데이터의 첫 바이트에 부여되는 번호
- 초기 순서 번호(ISN, Initial Sequence Number)
- 처음 통신을 위해 연결을 수립한 경우, 즉 제어 비트에서 연결을 수립하기 위한 비트인 SYN 플래그가 1로 설정된 세그먼트의 경우 순서 번호는 무작위 값이 됨
- 초기 순서 번호가 100이라면 가장 먼저 보내게 될 세그먼트 A의 순서 번호가 초기 순서 번호인 100이 됨
- 확인 응답 번호(acknowledgment number)
- 상대 호스트가 보낸 세그먼트에 대한 응답
- 다음으로 수신하기를 기대하는 순서 번호가 명시
- 호스트가 방금 데이터가 잘 도착했는지 확인 가능
- 확인 응답 번호 값을 보내기 위해서는 제어 비트에서 승인을 나타내는 비트인 ACK 플래그를 1로 설정
- Data Offset - TCP 헤더의 길이
- 제어 비트(control bits) 또는 플래그 비트(flag bits) - 8비트, SYN와 ACK 중요
- 현재 세그먼트에 대한 부가 정보
- 신뢰성있는 통신이 가능하다.
- CWR, ECE (x)
- 상대방과의 연결 가능? 등 여러 상태를 나타낸다.
- URG - Urgent Flag, Urgent Pointer(어디서부터 긴급 비트인지)와 세트
- 긴급 비트
- 내가 보내는 데이터가 우선 순위가 높은 것이 있어.
- ACK
- TCP에서 중요
- 승인 비트, 응답을 해준다.
- 세그먼트의 승인을 나타내기 위한 비트
- PSH
- 밀어넣기 비트
- 버퍼가 어느정도 쌓여야 전송을 한다 (클라이언트 관점)
- 상관없이 데이터를 밀어넣겠다.
- RST
- 초기화 비트
- 연결 중 추가적으로 주고 받으려고 하는데 문제가 발생하여 리셋(강제로 폐기하고 다시 시작)하는 것
- SYN
- 동기화 비트
- 연결을 수립하기 위한 비트
- 연결 시작 시 무조건 사용되는 것
- 서로 주고 받으면서 데이터를 보내도 되는지 응답을 받는다.
- FIN
- 종료 비트
- 연결을 종료하기 위한 비트
- 데이터를 다 주고, 연결을 유지하고 있을 필요가 없다.
- 연결을 끊을 때 사용하는 비트
- 윈도우(window)
- TCP는 연결 지향 → 상대방에게 더 보내도 될까? → Yes → 보내고 나서 잘 받았어? → 100 정도는 더 보내도 돼. 총 100만큼 양이 되도록 연속해서 세그먼트들 더 보내. → 보내고 나서 또 반복.
- 내 사용 공간이 얼마나 남았는지 상대방에게 알려준다.
- 수신 윈도우의 크기가 명시
- 수신 윈도우 - 한 번에 수신하고자 하는 데이터의 양
- 패킷이 쌓이고, 쌓인 것들은 버퍼에 보관한다.(창고 전에 복도 → 버퍼)
- 버퍼에서 어플리케이션이 데이터를 꺼내서 가져간다. 결국 어플리케이션이 쓰는 것이다.
- 버퍼가 넘친다 → 버퍼 오버플로우 (보통의 경우 볼 일이 없다.)
- Q. 버퍼의 크기가 윈도우 크기?
- 참고 - https://en.wikipedia.org/wiki/Transmission_Control_Protocol
연결 수립: 쓰리 웨이 핸드셰이크
- 쓰리 웨이 핸드셰이크(three-way handshake) 세 개의 단계로 이루어진 TCP의 연결 수립 과정
- TCP에서 중요한 것은 둘 사이의 연결을 수립하는 것이다.
- 클라이언트가 서버에게 요청 패킷을 보낸다. (SYN)
- SYN + ACK
- ACK
- 액티브 오픈(active open)
- 처음 연결을 시작하는 호스트의 연결 수립 과정
- 패시브 오픈(passive open)
- 연결 요청을 받고 나서 요청에 따라 연결을 수립해 주는 호스트의 연결 수립 과정
- 1단계 - SYN(클라이언트 → 서버)
- 플래그 SYN이 1로 켜진다, 시퀀스 번호 100 (악용 방지를 위해 랜덤 숫자)
- 뜻: “안녕… 연결하자~”
- 2단계 - SYN + ACK (서버 → 클라이언트)
- 플래그 SYN = 1, ACK = 1
- 시퀀스 번호: 3000 (랜덤 숫자), ACK 번호: 101
- 핵심 규칙: ACK 번호 = 받은 SYN 번호 + 1
- 뜻: “100번 받았음. 다음에는 101줘”
- 3단계 - ACK (클라이언트 → 서버)
- 플래그: ACK = 1, SYN 없음 (동기화가 이미 됐으니)
- 시퀀스 번호(SEQ) = 101, ACK = 3001
- Q. 왜 시퀀스 번호가 101인가?
- 순서
- SYN, SEQ = 100, ACK = 0 (클라이언트 → 서버)
- SYN + ACK, SEQ = 3000, ACK = 101 (클라이언트 ← 서버)
- ACK, SEQ = 101, ACK = 3001 (클라이언트 → 서버)
- 실제 데이터 전송
- 실제 예시
연결 종료
- 송수신 호스트가 각자 한 번씩 FIN과 ACK를 주고받으며 TCP가 연결을 종료
- 액티브 클로즈(active close)는 먼저 연결을 종료하려는 호스트에 의해 수행
- 패시브 클로즈(passive close)는 연결 종료 요청을 받아들이는 호스트에 의해 수행
- 연결 종료 시 4Way Handshake
- ACK와 FIN이 B에서 따로 나간다.
- ACK와 FIN을 합치는게 어렵기 때문이다.
- A는 다 끝났지만, B의 입장에는 줄 데이터가 남아있을 수도 있다.
- ACK로 답장을 하고, 추가로 확인을 한 뒤에 FIN을 보내는 것이다.
TCP 상태
- TCP는 연결형 통신과 신뢰할 수 있는 통신을 유지하기 위해 다양한 ‘상태’를 유지
- 상태(state) - 현재 어떤 통신 과정에 있는지를 나타내는 정보
- TCP는 상태를 유지하고 활용한다는 점에서 스테이트풀(stateful) 프로토콜
- TCP의 상태
- 연결이 수립되지 않은 상태
- 연결 수립 과정에서 주로 볼 수 있는 상태
- 연결 종료 과정에서 주로 볼 수 있는 상태
- 핵심 상태
- LISTEN
- ESTABLISHED
- SYN SENT → ESTABLISHED
- A → CLOSE, B → LISTEN
- CLOSED → LISTEN : 서버가 포트를 열어놓고 있음.
- 클라이언트가 SYN을 보낸다.
- TCP의 다양한 상태는 간단한 명령어로 확인
- 맥OS나 리눅스 - 터미널을 열고 netstat을 입력
연결이 수립되지 않은 상태
- CLOSED - 아무런 연결이 없는 상태
- LISTEN - 일종의 연결 대기 상태
- 일반적으로 서버로서 동작하는 패시브 오픈 호스트는 LISTEN 상태를 유지
- LISTEN 상태는 SYN 세그먼트를 기다리는 상태
- LISTEN 상태인 호스트(일반적으로 서버)에게 SYN 세그먼트를 보내면 쓰리 웨이 핸드셰이크가 시작
연결 수립 상태
- SYN-SENT
- 액티브 오픈 호스트가 SYN 세그먼트를 보낸 뒤
- 그에 대한 응답인 SYN + ACK 세그먼트를 기다리는 상태
- 연결 요청을 보낸 뒤 대기하는 상태
- SYN-RECEIVED
- 패시브 오픈 호스트가 SYN + ACK 세그먼트를 보낸 뒤 그에 대한 ACK 세그먼트를 기다리는 상태
- ESTABLISHED
연결 종료 상태
- FIN-WAIT-1
- 일반적인 TCP 연결 종료 과정에 있어 FIN-WAIT-1은 연결 종료의 첫 단계
- CLOSE-WAIT
- 종료 요청인 FIN 세그먼트를 받은 패시브 클로즈 호스트가 그에 대한 응답으로 ACK 세그먼트를 보낸 후 대기하는 상태
- FIN-WAIT-2
- FIN-WAIT-1 상태에서 ACK 세그먼트를 받게 되면 FIN-WAIT-2 상태가 됨
- 상대 호스트의 FIN 세그먼트를 기다리는 상태
- LAST-ACK
- CLOSE-WAIT 상태에서 FIN 세그먼트를 전송한 뒤 이에 대한 ACK 세그먼트를 기다리는 상태
- TIME-WAIT
- 액티브 클로즈 호스트가 FIN 세그먼트를 수신한 뒤, 이에 대한 ACK 세그먼트를 전송한 뒤 접어드는 상태
- 패시브 클로즈 호스트가 마지막 ACK 세그먼트를 수신하면 CLOSED 상태로 전이하는 반면,
- TIME-WAIT 상태에 접어든 액티브 클로즈 호스트는 일정 시간을 기다린 뒤 CLOSED 상태로 전이
TIME-WAIT 상태가 필요한 이유는 무엇인가요?
- TIME-WAIT 상태에 접어든 액티브 클로즈 호스트는 일정 시간을 기다린 뒤 CLOSED 상태로 전이
- 그런데 TIME-WAIT 상태는 왜 필요한 것일까?
- 왜 굳이 일정 시간을 기다렸다가 연결을 종료하는 것일까?
- 가장 주요한 이유
- 호스트 B의 입장에서 보내고 있는 것이 남아있을 수도 있다.
- 상대 호스트가 받았어야 할 마지막 ACK 세그먼트가 올바르게 전송되지 않았을 수 있기 때문임
- (04-3절) TCP 송수신 과정에서는 세그먼트가 올바르게 전송되지 않았다면 해당 세그먼트를 재전송
- 만약 TIME-WAIT 상태로 일정 시간 대기하지 않고 곧바로 연결을 종료해버리면 상대 호스트 입장에서는 마지막 ACK 세그먼트를 재전송받을 수 없음
- 또 다른 이유
- 한 연결을 종료하고 다른 연결을 수립하는 과정 사이에 대기 시간이 없다면 서로 다른 연결의 패킷들이 혼란을 야기
- TIME WIAIT 2 - 한번더 기다리는 이유
UDP 데이터그램 구조
- UDP는 TCP와 달리 비연결형 통신을 수행하는 신뢰할 수 없는 프로토콜
- 그래서 연결 수립 및 해제, 재전송을 통한 오류 제어, 혼잡 제어, 흐름 제어 등을 수행하지 않음
- TCP처럼 상태를 유지하지도 않음 - 스테이트리스(stateless) 프로토콜
- UDP 데이터그램 구조
- 송신지 포트와 수신지 포트: 송수신지의 포트 번호
- 길이: 헤더를 포함한 UDP 데이터그램의 바이트
- 체크섬: 데이터그램 전송 과정에서 오류 발생가 발생했는지 검사하기 위한 필드
- 체크섬이 알려주는 것은 도착한 데이터가 망가졌는가? 유무일 뿐이다.
- 다시 요청하거나 하지 않는다. 도착하지 않으면 그조차 모른다.
- UDP는 TCP에 비해 적은 오버헤드로 패킷을 빠르게 처리
- 주로 실시간 스트리밍 서비스, 인터넷 전화처럼 실시간성이 강조되는 상황에서 TCP보다 더 많이 쓰임
TCP의 오류·흐름·혼잡 제어
- TCP는 재전송을 기반으로 다양한 오류를 제어하고,
- 흐름 제어를 통해 처리할 수 있을 만큼의 데이터만을 주고받으며,
- 혼잡 제어를 통해 네트워크가 혼잡한 정도에 따라 전송량을 조절한다.
오류 제어: 재전송 기법
- 오류 검출과 재전송
- TCP 세그먼트에 오류 검출을 위한 체크섬 필드만으로 신뢰성을 보장하기는 부족
- TCP가 신뢰성을 제대로 보장하려면
- 송신 호스트가 송신한 세그먼트에 문제가 발생했음을 인지
- 오류를 감지하게 되면(세그먼트가 잘못 전송되었음을 알게 되면) 해당 세그먼트를 재전송
- TCP가 오류를 검출하고 세그먼트를 재전송하는 상황
- 중복된 ACK 세그먼트를 수신했을 때
- 타임아웃이 발생했을 때
- 중복된 ACK 세그먼트를 수신했을 때
- 송수신이 올바르게 이루어진 경우
- 예) 호스트 A와 B가 올바르게 세그먼트를 주고받는 경우
- A는 첫 순서 번호를 담은 세그먼트를 보내고 그에 대한 ACK 세그먼트를 받음
- 다음 순서 번호를 담은 세그먼트를 보내고, 그에 대한 ACK 세그먼트를 받는 것을 반복
- 수신 호스트 측이 받은 세그먼트의 순서 번호 중에서 일부가 누락된 경우
- 중복된 ACK 세그먼트를 전송
- 호스트 A의 n+1번 세그먼트가 잘못 전송되었고, 호스트 B가 n+1번 ACK 세그먼트를 반복해서 전송(못받아서 달라고)
- RTT(Round Trip Time)
- 메시지를 전송한 뒤 그에 대한 답변을 받는 데까지 걸리는 시간
- RTT는 ping 명령어로 쉽게 조회
- 타임아웃이 발생했을 때
- TCP 세그먼트를 송신하는 호스트는 모두 재전송 타이머(retransmission timer) 값을 유지
- 호스트가 세그먼트를 전송할 때마다 재전송 타이머를 시작
- 타임아웃(timeout) - 이 타이머의 카운트다운이 끝난 상황(정해진 시간이 끝난 상황)
- 타임아웃이 발생할 때까지 ACK 세그먼트를 받지 못하면 세그먼트가 상대 호스트에게 정상적으로 도착하지 않았다고 간주하여 세그먼트를 재전송
- 타임아웃을 몇초로 할지가 중요하다. 그 시간의 기준이 RTT이다. 이것을 기준으로 측정한다.
- ARQ: 재전송 기법
- ARQ(Automatic Repeat Request, 자동 재전송 요구)
- 수신 호스트의 답변(ACK)과 타임아웃 발생을 토대로 문제를 진단하고, 문제가 생긴 메시지를 재전송함으로써 신뢰성을 확보하는 방식
- ARQ의 대표적인 세 가지 방식
- Stop-and-Wait ARQ
- 제대로 전달했음을 확인하기 전까지는 새로운 메시지를 보내지 않는 방식
- 메시지를 송신하고, 이에 대한 확인 응답을 받고, 다시 메시지를 송신하고, 확인 응답을 받는 것을 반복
- 단순하지만, 높은 신뢰성을 보장하는 방식
- 문제점 - 네트워크의 이용 효율이 낮아지고 성능이 저하됨
- 전송되었음을 확인해야만 비로소 다음 전송을 시작하는 Stop-and-Wait ARQ의 특성으로,
- 송신 호스트(A) 입장에서 확인 응답을 받기 전까지는 다음 전송을 할 수 있어도 하지 못함
- 수신 호스트(B) 입장에서도 훨씬 더 많은 데이터를 한 번에 전송받을 수 있음에도 불구하고 한 번에 하나씩만 확인 응답
- Go-Back-N ARQ
- Stop-and-Wait ARQ의 문제 해결 방법
- 각 세그먼트에 대한 ACK 세그먼트가 도착하기 전이더라도 여러 세그먼트를 보낼 수 있어야 함
- Go-Back-N ARQ와 Selective Repeat ARQ는 모두 이러한 방식으로 동작
- 파이프라이닝(pipelining) - 연속해서 메시지를 전송할 수 있는 기술
- 오늘날 TCP는 이러한 파이프라이닝이 사용되는 Go-Back-N ARQ와 Selective Repeat ARQ를 기반으로 동작
- Go-Back-N ARQ는 파이프라이닝 방식을 활용
- 여러 세그먼트를 전송하고, 도중에 잘못 전송된 세그먼트가 발생할 경우 해당 세그먼트부터 전부 다시 전송하는 방식
- Go-Back-N ARQ에서 순서 번호 n번에 대한 ACK 세그먼트는 ‘n번만의’ 확인 응답이 아닌 ‘n번까지의’ 확인 응답
- 누적 확인 응답(CACK, Cumulative Acknowledgment)
- Selective Repeat ARQ
- 선택적으로 재전송하는 방법
- Selective Repeat ARQ는 수신 호스트 측에서 제대로 전송받은 각각의 패킷들에 대해 ACK 세그먼트를 보내는 방식
- Go-Back-N ARQ의 ACK 세그먼트가 누적 확인 응답이라면,
- Selective Repeat ARQ의 ACK 세그먼트는 개별 확인 응답(Selective Acknowledgment)
- 송신 호스트는 올바르게 수신받지 못한 ACK 세그먼트가 있는지 검사하고, 만일 응답받지 못한 세그먼트가 존재한다면 해당 세그먼트를 재전송
- 오늘날 대부분의 호스트는 TCP 통신에서 Selective Repeat ARQ를 지원
- Selective Repeat ARQ를 사용하지 않을 경우 Go-Back-N ARQ 방식으로 동작
흐름 제어: 슬라이딩 윈도우
- 파이프라이닝 기반의 Go-Back-N ARQ와 Selective Repeat ARQ가 정상적으로 동작하려면
- 호스트가 한 번에 받아서 처리할 수 있는 세그먼트의 양에는 한계가 있기 때문임
- 예) 수신 호스트가 한 번에 n개의 바이트를 받아서 처리할 수 있다면, 송신 호스트는 이 점을 인지하여
- 만약 이 양보다 더 많은 양을 한 번에 전송하면 마치 우편함이 가득 차 일부 편지가 넘치는 것처럼
- 일부 세그먼트가 처리되지 못할 우려가 발생
- n개 바이트를 넘지 않는 선에서 송신
- 반드시 흐름 제어(flow control)를 고려해야 함
- 수신 호스트의 ‘수신 버퍼’와 ‘버퍼 오버플로’ 개념
- 수신 버퍼 - 수신된 세그먼트가 애플리케이션 프로세스에 의해 읽히기 전에 임시 저장 공간
- 송신 호스트가 흐름 제어를 고려하지 않고 수신 버퍼의 크기보다 많은 데이터를 전송하면 일부 세그먼트가 처리되지 못할 수 있음 - 저장 가능한 공간보다 더 많은 데이터를 저장할 수 없음
- 버퍼 오버플로(buffer overflow)
- TCP의 흐름 제어
- 이러한 문제 상황을 방지하고자 송신 호스트가 수신 호스트의 처리 속도를 고려하며 송수신 속도를 균일하게 유지하는 것을 의미
- Stop-and-Wait ARQ를 사용하면 별도의 흐름 제어가 필요하지 않음
- 파이프라이닝 기반의 Go-Back-N ARQ와 Selective Repeat ARQ에서는 흐름 제어가 필요
- 파이프라이닝이 연속해서 세그먼트를 전송하지만, 무작정 무한한 데이터를 연속해서 보낼 수는 없기 때문임
- 버퍼의 크기를 헤더에 적어둔다(?)
- 오늘날 TCP에서는 흐름 제어로 슬라이딩 윈도우(sliding window)를 사용
- 윈도우(window) - 송신 호스트가 파이프라이닝할 수 있는 최대량
- 즉, 윈도우의 크기만큼 확인 응답을 받지 않고도 한 번에 전송 가능하다는 의미
- 송신 호스트가 보내려는 데이터와 윈도우가 다음 그림과 같다면 첫 번째 세그먼트부터 네 번째 세그먼트까지가 확인 응답을 받지 않고도 전송할 수 있는 양
- 반면에 윈도우 크기에서 벗어난 숫자에 해당하는 세그먼트는 전송할 수 없음
- 앞의 상황에서 윈도우에 포함된 첫 번째, 두 번째, 세 번째, 네 번째 세그먼트를 전송했고, 곧 수신 호스트로부터 첫 번째 세그먼트에 대한 ACK 세그먼트를 받았다고 가정
- 윈도우는 오른쪽으로 한 칸 이동
- 송신 호스트 뿐만 아니라 수신 호스트도 윈도우를 고려
- 송신측 윈도우(이하 송신 윈도우)는 수신 호스트가 알려 주는 수신 측 윈도우(이하 수신 윈도우)를 토대로 알 수 있는 정보
- 수신 호스트는 TCP 헤더(윈도우 필드)를 통해 송신 호스트에게 자신이 받을 데이터의 양을 알려줌
- 송신 호스트는 이 정보를 바탕으로 수신 호스트의 처리 속도와 발맞춰 균일한 속도로 세그먼트를 전송
- 슬라이딩 윈도우(sliding window)
- 수신 호스트가 첫 번째 세그먼트를 올바르게 수신했다면(송신 윈도우와 마찬가지로) 수신 윈도우는 오른쪽으로 한 칸 이동
- 또 두 번째 세그먼트를 올바르게 수신했다면 수신 윈도우는 다시 한번 오른쪽으로 한 칸 이동
- 파이프라이닝 과정에서 송수신 윈도우는 점차 오른쪽으로 미끄러지듯 움직이게 됨