(컴퓨터 네트워크) 4. Reliable Data Transfer
해당 내용은 kocw 한양대학교 컴퓨터 네트워크 강의를 정리한 내용입니다.
강의 링크 - http://www.kocw.net/home/search/kemView.do?kemId=1169634&ar=relateCourse
이미지 출처 : http://www.dcs.bbk.ac.uk/~ptw/teaching/IWT/transport-layer/notes.html
네트워크의 경우 5개의 layer로 나뉘는데, 하위 layer는 상위 layer에게 서비스를 제공하는 것을 의무로 하고 있습니다.
또한, 하위 layer에게 서비스를 받고 있습니다.
그중 transport 계층에는 TCP / UDP 방식으로 통신을 진행할 수 있는데, 이 계층에서는 Application에게 두 방식 공통적으로 Multiplexing, ErrorChecking을 지원해 주어야 합니다.
- Multiplexing : Application에서 온 여러 개의 Data를 구분 지어주어야 합니다.
- Error Checking : 에러가 난 packet을 Application에게 보내주어선 안됩니다.
위 두 기능은 TCP와 UDP가 공통적으로 지원해 주는 기능이고
TCP가 지원해주는 기능으로는 Reliable Data Transfer, flow control, congestion control 등이 있습니다.
그중 이번 시간에는 reliable data transfer에 대해서 알아보도록 하겠습니다.
1) unreliable data transfer
reliable 한 데이터 전송은 application에서 다른 application까지 데이터 전송에 에러가 없이 보내는 것을 말합니다.
실제로는 하부 네트워크는(layer 1, 2, 3) unreliable 하게 데이터를 전송합니다. (라우터의 큐에 네트워크 요청이 가득 차면 유실됩니다. queueing delay)
unreliable 한 상황에서는 1. 패킷이 유실되거나, 2. 패킷의 에러만 발생합니다.
그래서 오늘은 TCP에서 reliable한 data transfer를 제공하기 위해 어떤 메커니즘이 필요한지 살펴보도록 합니다.
2) RDT 환경
먼저 한 번에 패킷 하나만 보내고 받는 사고 실험을 해보도록 합니다.
1. RDT 1.0
하나의 패킷만 보내는 환경에서 하부 채널 (layer 1, 2, 3)이 완벽한 채널이라면 (패킷 에러도 없고, 패킷 유실도 없는 경우)
특별히 TCP가 하는 일이 없습니다.
2. RDT 2.0
만약에 패킷 에러가 발생 가능한 채널이라면
보낸 패킷에 에러를 체크해야 합니다. (Check sum) 이는 받는 측에서 데이터를 받은 후, 에러를 체크해야 합니다..... 1
그리고 에러가 있는 패킷을 받았다면 다시 보내달라고 요청도 해야 합니다..... 2
다시 보내달라는 요청이 온다면 재전송해야 합니다...... 3
1번의 경우 Check sum을 이용해서 에러를 체크해야 합니다.
2번의 경우 패킷을 받은 후 Feedback을 해야 합니다. (잘 받았으면 잘 받았다는 Feedback, 에러 난 걸 받았으면 에러가 났었다 하는 Feedback이 필요합니다.)
- 잘 받았다는 Feedback : ACK
- 에러가 있는 패킷을 받았다는 Feedback : NACK
3번의 경우 Sender 측에서 받은 Feedback이 에러가 일어난 것이면 재전송해야 합니다.
(NACK를 받으면 sender가 같은 packet을 재전송한다)
하지만 위 상황은 완벽한 상황이 아닙니다.
만약에 Feedback에 에러가 있는 경우라면 -> Feedback에도 (ACK에도) checksum이 있어야 한다.
Feedback에 checksum을 봤는데 에러가 있다면
-> sender는 receiver가 받았을 수도 있고 안 받았을 수도 있기 때문에 재전송해야 됩니다.
그런데 receiver 입장에서는 해당 패킷이 중복된 패킷인지 같은 패킷이 2개인 건지 확인할 방법이 없습니다.
(hello hello를 보내려는 건지, hello를 보낼려는건지 확인할 방법이 없다)
그래서 packet에 번호를 붙여서 중복인지 새로운 packet인지 구분해야 합니다. (Sequence number)
2.1) Sequence Number
sequence number는 TCP의 Header에 들어가서 전송됩니다.
그래서 sequence number는 무한대가 될 수 없고, sequence number 필드 크기를 최소화시키고 전송해야 합니다.
위에서 확인한 프로토콜(RDT)에서는 sequence number는 2개면 충분합니다.
(한 번에 하나의 데이터만 전송되기 때문에) 0, 1, 0, 1, 0, 1의 1bit로만 구분할 수 있습니다.
그리고 이러한 Sequence Number를 ACK에 넣어서 NACK를 사용하지 않고 통신하는 경우도 있습니다.
ACK의 sequence number로 가장 최근에 잘 받은 packet의 sequence number를 담아서 보내줍니다.
sender가 0번 packet 보낸다 >> (잘 받았으면) 0번 ACK를 보낸다.
sender가 1번 packet을 보낸다.(에러 발생) >> 가장 마지막에 잘 받은 게 0번이기 때문에 0번 ACK를 보낸다
sender는 1번 보냈는데 0번 ACK가 왔기 때문에 다시 1번 packet을 보낸다. >> 잘 받았으니 1번 ACK를 보낸다.
위와 같은 방식으로 진행됩니다.
3. RDT 3.0
이번에는 패킷 유실 (loss)도 일어날 수 있는 환경을 생각해 보겠습니다.
sender입장에서는 packet을 보냈는데 해당 pakcet이 loss 되면 reciever는 아무것도 받지 못했기 때문에 ACK를 보내지 않고, sender도 아무것도 받지 못합니다.
그래서 Timer를 만들어서 packet을 보낸 후 timer를 작동시키고 난 뒤, timer가 다 되도록 데이터를 받지 못하면 다시 보냈던 packet을 보냅니다.
그럼 여기서 timer의 시간을 얼마로 맞추어야 하나에 대해서 고민을 해야 하는데, 이는 답이 없이 그냥 적당히 맞추어야 합니다.
만약 timer의 시간이 짧으면
- 장점 : recovery가 빠르다 (빠르게 패킷 유실의 복구가 가능하다)
- 단점 : packet의 중복이 일어난다.(단순히 느린 건데 유실되었다고 빨리 판단해 버리니까)
만약 timer의 시간이 길다면
- 장점 : packet의 중복이 줄어든다. (네트워크 overhead가 적다)
- 단점 : recovery가 느리다.
Receiver의 ACK의 유실 또한 Sencer의 Timeout으로 해결합니다.
지금까지 살펴본 내용을 정리하자면
unreliable 한 data transfer의 상황에서 일어날 수 있는 두 가지 에러 사항인
1. 패킷의 에러
2. 패킷의 유실
위 두 가지가 일어나는데, 이를 극복하기 위해서
- 패킷의 에러 : Feedback, ReTransmission, Sequence Number
- 패킷의 유실 : Timeout
을 이용해서 극복합니다. 이러한 정보들은 TCP pakcet의 Header에 담아서 통신이 이루어집니다.