1) Error detection
2) feedback
3) retransmission
4) sequence #
5) timeout
기본적인 reliable transfer protocol
실제로 사용할 수 있나? 성능에서 고려했을때 그렇지 않다.
utilization = (전체 시간중에서 sender가 네트워크를 사용하는 비율)
U[transmit] = L(비트당 패킷 길이) / R(전송률)
utilization이 클수록 효율이 좋은 것을 의미한다.
결론 및 문제점:
TCP는 신뢰성(reliability)은 높아도 한번에 한 패킷만 보내기 때문에 성능(utilization)이 굉장히 안좋다.

(그림설명)
1. transmission time: sender에서 패킷 하나를 link에 올리는데 (= 처음 bit가 출발하고 마지막 bit가 출발선에 올라가는데) 걸리는 시간
2. RTT (round trip time) : 패킷을 보내고 ack 를 받는데 걸리는 시간

해결책:
한번에 여러개의 packet을 전송하자.

(그림설명)
한번에 3개의 packet을 전송하니까 이전 그림과 비교할때 Utilization이 높아진 것을 확인할 수 있다.
앞으로의 블로그 방향성은 pipelined protocols를 가능하게 하는 두가지 일반적인 form에 대해 설명할 것이다. 1) go-Back-N 과 2) selective repeat
한번에 많은 패킷을 쏟아 붓지만 'window'만큼의 제한이 있다.
예를 들어)
Win = 4
0 1 2 3 4 5 6 7 8 9 10 11 12
다음의 상황은 이어서 나타나는 서술을 의미한다.
sender는 전송한 packet중 ACK를 받지 못한 가장 최신 packet에 대해 timer를 계산한다. 이때 발생할 수 있는 상황은 두가지가 있다.
i) timer 내로 원하는 ACK가 오지 않은 경우
window 내의 unack 된 모든 packet을 재전송한다.
ii) timer 내로 원하는 ACK 가 온 경우
다음 ACK되지 않은 가장 최신의 packet에 대해 timer를 계산한다.ㅁ

정상적으로 받지 못한 packet이 있는 경우)
해당 packet이 올때까지 다른 packet들이 와도 받지 못한 packet의 직전 packet에 대한 ACK를 sender로 보낸다.
예를들어 다음의 packet 전달과정을 가정해보자.
sender 전송) 1 2 3 4 5
receiver 수신) 1 2 4 5
receiver 측은 packet 3을 아직 받지 못했으므로 그 이전 packet 2에 대한 ACK만 연속으로 내보낸다.

win = 4라고 가정하고 그림을 살펴보자.
1) packet 0 ~ packet 3 까지를 보내다가 packet 2가 유실됨
2) receiver는 packet 0과 1을 잘 받아서 ACK 0 과 1을 보냄
3) packet 2는 받지 못하고 packet 3을 받아서 ACK는 2를 받기 직전이 ACK 1을 보냄
4) packet 2 에서부터 window 4인 packet 5까지 ACK1을 계속 보내면 결국 packet 2는 timeout 이 일어남
5) 이후 packet 2에서부터 재전송
window는 receiver가 받았는지 확인해야 하기 때문에 buffer 공간에 저장한다.
유실되면 N개의 window 만큼 다시 돌아와서 packet을 재전송한다.
문제점
유실된 것은 packet 1개밖에 없는데 window 만큼 모두 계속 유실된다.
문제가 있는 경우 없어진 packet만 select하여 재전송한다.
즉 유실된 packet만 재전송하여 network에 부담을 덜 주는 대신 receiver가 일을 좀더 한다.
예를 들어)
sender 전송) 1 2 3 4 5
receiver 수신) 1 2 4 5
-> receiver 전송) ACK 1 2 4 5
여기서 sender는 ACK를 받지 못한 모든 packet에 대해 timer 를 계산하고 timer가 만료될때까지 ACK 가 오지 않으면 각 packet을 재전송한다.

win = 4 라고 가정하고 그림을 살펴보자.
ACK0 과 ACK1을 수신하면 packet2를 시작으로 하는 4개의 단위를 버퍼에 저장해놓는다.
packet2가 유실되고 packet3부터 차례로 수신하므로 ACK3부터 5까지 sender에게 보내고 packet2가 timeout 되면 packet 2 만 재전송하여 ACK2를 받아내어 버퍼를 채운다.
sequence number는 packet의 header field에 들어가게되고 header는 작을수록 좋다. 재전송할 packet과 새로 구분해야할 packet의 sequence number가 겹치게 된다면 어떻게 해결하는가?
문제상황은 다음과 같다.
예를들어)
sequence number : 0 1 2 3
window size : 3
packet 0, 1, 2 모두 제대로 전송된후 packet 3부터 시작되는 buffer case가 있으면 이때 새로 얻게되는 4번째 5번째 packet sequence number는 0과 1이 된다. 이는 이전에 받았던 packet 0,1 과 헷갈릴 수 있으므로 문제가 생긴다.
해결방법은 buffer가 3으로 시작된다면 window size만큼 squence number가 보장돼있으면 된다. 따라서 window size가 n이면 sequence number는 2n 이상이면 해결된다.
TCP는 1) reliable data transfer 2) flow control 3) congestion control 이라는 특징 있다. 여기서 1)을 적용하려면 GBN과 SR를 사용하는데 실제 TCP에서 모든 packet에 time를 두게 되면 부담이 될 수 있다. 따라서 실제 TCP는 window를 대표하는 timer 하나와 cumulative ACK를 둬서 두가지 장점을 모두 사용한다.


예를들어)
보내고 싶은 message 중 buffer에 들어갈 msg = "computer"라고 하자.
host A와 host B의 sender receiver 의 segment 구조는 다음과 같다.
Host A <------------------------------------> Host B
(sender) (receiver)
[seq=42 | ACK=79 | "computer"] --------------> [seq=42 | ACK=79 | "computer"]
: 보내려고하는 "computer"의 첫번째 byte의 seq#가 42
(receiver) (sender)
[seq=79 | ACK=49 | "computer"] <-------------- [seq=79 | ACK=49 | "computer"]
(sender)
[seq=49 | ACK=80 |...] --->
host B에서 보내는 ACK로 구분을 해야하므로 host A의 sender의 seq #는 ACK가 된다.
그리고 ACK는 그 다음 packet에 대한 부분을 확인받아야 하기 때문에 축적되는데 이러한 특성때문에 'cumulative ACK'라고도 한다.
실제 상황에서는 data를 보낼때 ACK를 바로 하지 않고 기다린다.
1) 새로 받아온 data를 또다시 보낼 수 있으므로 그때 ACK를 받아온다.
2) TCP를 사용할때 cumulative ACK 이므로 가만히 있다가 ACK만 받아오면 되기 때문이다.
Q1) TCP timeout value는 어떻게 설정하는가?
각 segment 별로 RTT가 다르므로 timeout을 RTT로 설정하기엔 너무 모호하다. 따라서 이를 확정짓기 위한 고정된 RTT를 timeout value 를 결정하는데 이를 estimatedRTT라고 한다.

Q2) 유실이 안되어도 timeout이 되는 경우
RTT에 margin값을 더하기도 한다.

1) 유실된 ACK인 경우

host B에서 잘 받은 packet에 대해 ACK를 보냈으나 유실됐기에 그동안의 timeout 이 진행된다. 그리고 유실된 ACK부분에 대해 packet을 재전송한다.
2) timeout이 이른 경우

host A에서 seq#=92이고 8byte짜리 데이터와 seq#=100이고 20byte짜리 데이터를 순차적으로 보낸다. host B에서는 잘받은 부분에 대해 ACK100과 ACK120을 보내는데 그 동안 seq#=92인 packet에 대해 timeout이 일어난다. 이때는 ACK100에 대한 seq#=92인 packet만 재전송하고 이미 host B는 전체 buffer가 ACK120까지 채워져 있으므로 ACK120을 재전송한다. host A는 ACK120을 받고 119번까지 모두 무사히 전달받음을 확인하고 buffer를 정리한다.
3) cumulative ACK

pipeline으로 보내는데 아직 timeout이 되지 않았다. 첫번째 packet에 대해 ACK가 유실되었다고 하더라고 host B의 입장에서 ACK 120까지 모두 채워졌으므로 ACK 120을 timeout 내에 전송한다.
여기서 cumulative ACK의 장점이 보인다.
이후에 좀더 발전된 TCP를 사용하기 위해