서로 다른 host에서 동작하는 application 간의 logical communication을 제공한다.
연결 설정 필요
reliable, congestion control, flow control
unreliable
아무것도 안함
delay 보장 (반드시 몇 초 안에 받을 수 있게 해줄게)
data rate 보장 (반드시 이 정도 속도로 받을 수 있게 해줄게)
IP 기반으로 동작하기 때문이다.
Port 번호는 네트워크에서 데이터가 전송될 때 목적지 프로세스를 식별하는 데 사용된다.
Port 번호는 16bit로 표현된다.
그럼에도 불구하고 사용하는 이유: 심플하기 때문에 real-time application에 적합함
보내는 데이터가 작고, 작은 용량의 header를 원하는 프로토콜에서 사용
DNS, SNMP, HTTP/3에서 사용한다.
multicast, broadcast 어플리케이션에서 사용
UDP Message Format
TCP/UDP는 bi-directional:
송신자이면서 수신자이다.
Reliability를 제공하기 위해서 에러를 처리해야 한다.
Error Example: bit값 변경, loss
FEC (Forward Error Correction):
송신측 - 송신 데이터에 에러를 처리할 수 있는 비트를 넣어 보냄
수신측 - 오류 Detection & Correction
Real Time에 적합함
ex) 해밍코드
BEC (Backward Error Correction):
송신측 - 재전송(Retransmission)
수신측 - Error Detection
ex) TCP 프로토콜
지금부터 이야기할 것은 BEC이다.
Transport 계층에서 Reliability를 제공할 수 있도록 프로토콜을 만들어보자.
FSM (Finite state Machine)을 통해 그림으로 설명한다.
이벤트가 발생해서 StateA 에서 StateB로 넘어갈 때는 Action을 취하면서 넘어간다.
가정
아래 층이 굉장히 reliable 하다
- no bit error
- no loss of packets
송신측 Transport
State 개수: 1
S-State1: 상위 계층의 요청 대기 상태S-State1 ➜ S-State1 (LOOP)
Event ①
: 상위 계층으로부터 데이터 받음
Action ①
: 하위 계층으로 데이터 내려 보냄
수신측 Transport
State 개수: 1
R-State1: 하위 계층의 요청 대기 상태R-State1 ➜ R-State1 (LOOP)
Event ①
: 하위 계층으로부터 데이터 받음
Action ①
: 상위 계층으로 데이터 올려 보냄
가정
비트 오류만 존재하고, 패킷 손실은 없다.
- bit error
- No loss of packets
Checksum을 사용해서 bit error check
Retransmission을 써서 error correction
수신자가 잘 받았는지 못받았는지 알려줘야 한다.
ACK(Acknowledgement) - 에러 없음
NAK(Negative Acknowledgement) - 에러 있음
송신자가 하나만 보내고 ACK 또는 NAK를 기다린다. (Stop & Wait)
(Sliding Window의 아주 simple한 기법)
송신측 Transport
State 개수: 2
S-State1: 상위 계층의 요청 대기 상태
S-State2: ACK/NAK를 기다리는 상태S-State1 ➜ S-State2
Event ①
: 상위 계층으로부터 데이터 받음
Action ①
: 하위 계층으로 데이터 내려 보냄S-State2 ➜ S-State2 (LOOP)
Event ②
: 수신측에서 NAK를 받음
Action ②
: RetransmissonS-State2 ➜ S-State1
Event ③
: 수신측에서 ACK를 받음
Action ③
: NONE
수신측 Transport
State 개수: 1
R-State1: 하위 계층의 요청 대기 상태R-State1 ➜ R-State1 (LOOP)
Event ①
: 하위 계층으로부터 데이터 받음 + ERROR 있음
Action ①
: NAK를 송신자에게 보냄R-State1 ➜ R-State1 (LOOP)
Event ②
: 하위 계층으로부터 데이터 받음 + Error 없음
Action ②
: 상위 계층으로 데이터 올려보냄 + ACK를 송신자에게 전송
수신: 잘 받음 + ACK 보냄
송신: ACK에 오류가 있어서 NAK인 줄 알고 또 보냄
duplicate
재전송 할 때 sequence number를 사용한다.
0번 받았는데 0번이 또 왔네?
-> 버림
가정
비트 오류만 존재하고, 패킷 손실은 없다.
- bit error
- No loss of packets
송신측 Transport
State 개수: 4
S-State1: 상위 계층의 요청 대기 상태 (0번 sequence)
S-State2: ACK/NAK를 기다리는 상태
S-State3: 상위 계층의 요청 대기 상태 (1번 sequence)
S-State4: ACK/NAK를 기다리는 상태► S-State1 ➜ S-State2
Event ①
: 상위 계층으로부터 데이터 받음, sequence number는 0번
Action ①
: 하위 계층으로 데이터 내려 보냄► S-State2 ➜ S-State2 (LOOP)
Event ②
: 수신측에서 NAK를 받음 or 받은 ACK/NAK 패킷에 오류가 있음
Action ②
: Retransmisson► S-State2 ➜ S-State3
Event ③
: 수신측에서 ACK를 받음 && 오류 없음
Action ③
: NONE나머지는 대칭
수신측 Transport
State 개수: 2
R-State1: 하위 계층의 0번 sequece 요청 대기 상태
R-State2: 하위 계층의 1번 sequece 요청 대기 상태R-State1 ➜ R-State2
Event ①
: 하위 계층으로부터 데이터 받음 + ERROR 없음 + sequence 0번 받음
Action ①
: 데이터를 상위로 올려보냄 + cheksum을 포함한 ACK 패킷 송신자에게 보냄R-State2 ➜ R-State2 (LOOP)
Event ②
: 하위 계층으로부터 데이터 받음 + Error 있음
Action ②
: checksum을 포함한 NAK 패킷 송신자에게 보냄R-State2 ➜ R-State2 (LOOP)
R-State2는 1번 sequence를 대기하는 중임
Event ③
: 하위 계층으로부터 데이터 받음 + 에러 없음 + sequence 0번 받음
Action ③
: 데이터 버림 + checksum을 포함한 ACK 패킷 송신자에게 보냄
수신측에서 Event ③가 발생하는 이유는 다음과 같다.
송신자: 0번 패킷 전송
수신자: 0번 패킷 잘 받고 ACK 전송
ACK 패킷이 전달되던 중 에러 발생
송신자: ACK 패킷을 받았더니 에러 발견(송신 Event ②)
수신자: 1번 패킷 기다리는 중
송신자: 0번 패킷 다시 보냄
수신자: 1번 패킷 기다리고 있는데 왜 0번 패킷 보내? (수신 Event ③)
데이터는 버리고, 0번 패킷 ACK 전송
송신자: 아 0번 패킷 잘 갔었구나, 1번 보낼 준비 할게
수신자: 1번 패킷 기다리는 중
가정
비트 오류만 존재하고, 패킷 손실은 없다.
- bit error
- No loss of packets
송신측 Transport
State 개수: 4
S-State1: 상위 계층의 요청 대기 상태 (0번 sequence)
S-State2: ACK(0번)를 기다리는 상태
S-State3: 상위 계층의 요청 대기 상태 (1번 sequence)
S-State4: ACK(1번)를 기다리는 상태S-State1 ➜ S-State2
Event ①
: 상위 계층으로부터 데이터 받음, sequence number는 0번
Action ①
: 하위 계층으로 데이터 내려 보냄S-State2 ➜ S-State2 (LOOP)
Event ②
: ACK(sequence 1번)를 받음 or 받은 패킷에 오류가 있음
Action ②
: RetransmissonS-State2 ➜ S-State3
Event ③
: ACK(sequence 0번)를 받음 && 오류 없음
Action ③
: NONE나머지는 대칭
수신측 Transport
State 개수: 2
R-State1: 하위 계층의 0번 sequece 요청 대기 상태
R-State2: 하위 계층의 1번 sequece 요청 대기 상태R-State1 ➜ R-State2
Event ①
: 하위 계층으로부터 데이터 받음 + ERROR 없음 + sequence 0번 받음
Action ①
: 데이터를 상위로 올려보냄 + cheksum을 포함한 ACK(0) 패킷 송신자에게 보냄R-State2 ➜ R-State2 (LOOP)
R-State2는 sequnce 1번 패킷을 기다리는 상태
Event ②
: 하위 계층으로부터 데이터 받음 + (Error 있음 || sequence 0번 받음)
Action ②
: ACK(0: 마지막으로 잘 받은 패킷 sequence) 패킷을 송신자에게 보냄나머지 대칭
가정
비트 오류, 패킷 손실이 존재한다.
- bit error
- loss of packets
Loss: 데이터를 보냈는데 ACK가 돌아오지 않는다.
Loss를 해결하기 위해 추가로 timer를 사용한다.
송신측 Transport
State 개수: 4
S-State1: 상위 계층의 요청 대기 상태 (0번 sequence)
S-State2: ACK(0번)를 기다리는 상태
S-State3: 상위 계층의 요청 대기 상태 (1번 sequence)
S-State4: ACK(1번)를 기다리는 상태S-State1 ➜ S-State2
Event ①
: 상위 계층으로부터 데이터 받음, sequence number는 0번
Action ①
: 하위 계층으로 데이터 내려 보냄 + 타이머 startS-State2 ➜ S-State2 (LOOP)
Event ②
: 수신측에서 (1번을 받았다고 ACK를 보냄 || 받은 패킷에 오류가 있음)
Action ②
: NONES-State2 ➜ S-State2 (LOOP)
Event ③
: Time out
Action ③
: Retransmission + 타이머 start► S-State2 ➜ S-State3
Event ④
: 수신측에서 ACK(0) 받음 && 오류 없음
Action ④
: 타이머 stop► S-State1 ➜ S-State1 (LOOP)
Event ⑤
: 이미 Time out 처리한 패킷이 옴
Action ⑤
: NONE나머지는 대칭
Event ③에서 Time out이 발생하는 경우
Receiver는 V2.2와 동일
중복 수신은 위로 올리지 않고 버린다!
위에서 설명한 방식을 Stop And Wait이라고 하는데, 효율성이 좋지 않다.
송신자가 link를 쓴 시간 = Transmission time(L/R)
나머지 시간(2𝜏 == RTT)은 대기
이러한 비효율성을 해결하기 위해서 sliding window 방식을 고안했다.
sliding window: 1RTT 내에 여러개의 패킷을 보내자.
window size: N (N * Transmission Time < 1 RTT)
⚠️ Stop And Wait도 Sliding Window의 일종이다. window가 매우 작을 뿐
효율: 사용시간/전체 시간 = Transmission time * 3 / (RTT + Transmission Time)
Stop and Wait 방식보다 3배 효율이 증가한다.
그럼 window 크기를 계속 늘리면 되나?
실제로는 제한이 있어서, TCP는 window 크기를 늘렸다 줄였다 한다.
window 사이즈: N
N = ACK를 받지 않고 전송할 수 있는 패킷 최대 개수
순서번호: 0 ~ 2^k-1 (Packet 당 하나씩)
modulo 2^k-1 연산을 사용한다.
⚠️ 데이터 하나 보내고 ACK 하나 받는 Stop And Wait과는 달리, Sliding Window에서는 ACK는 쌓여서 도착할 수 있다. (Cumulative ACK)
따라서, ACK(n)이 도착하면, sequence n 이전의 패킷은 모두 ACK 받은 것으로 판단한다.
재전송 타이머 1개를 사용한다.
ACK를 받지 못한 패킷 중 가장 오래된 것을 기준으로 타이머를 적용한다.
Time out이 발생하면 ACK를 받지 못한 패킷 모두를 재전송한다.
따라서, 버퍼가 N개 만큼 필요하다.
순서대로 오는 패킷만 accept.
순서대로 오지 않으면 discard.
Go-Back-N에서는 수신 버퍼가 없는게 기본 설계이다.
따라서, 패킷 순서가 뒤섞여서 오면 처리하지 못하고 버린다.
송신은 Go-Back-N과 거의 똑같다.
차이점은 다음과 같다.
ARQ
Automatic Repeat Request
자동 재전송
Go-Back-N에 비해서 수신측의 윈도우 크기가 N으로 늘어난다.
== 버퍼의 크기가 N개로 늘어난다.
Selective Repeat에서는 딜레마가 발생할 수 있다.
만약, 보내야 하는 패킷이 7개가 있고, 윈도우 크기를 3으로 설정했다고 가정해보자.
sequence Number는 2bit를 써서 0,1,2,3을 번갈아가며 사용한다.
송신: pck0, pck1, pck2를 보낸다.
수신: ACK0, ACK1, ACK2를 보낸다.
이 때, 모든 ACK가 Loss되는 상황이 발생한다.
하지만, 수신측은 ACK를 보냈으므로, 윈도우를 이동시켜서 pck3, pck0, pck2를 받을 준비를 한다.
송신측은 ACK를 못받아서 Time out이 발생하고, pck0, pck1, pck2를 재전송한다.
수신측은 pck0이 새로운 패킷인줄 알고 받는다.
이 딜레마를 해결하기 위해서는 윈도우 크기 N을 sequence Number 개수의 절반으로 해야 한다.
Go-Back-N의 윈도우 크기: N = 2^k-1
Selective Repeat의 윈도우 크기: N = 2^(k-1)
이 때, k는 sequence number 필드의 비트 수
Computer Networking, A Top Down Approach - JAMES F.KUROSE