ARQ
오류가 났을 때 재전송하는 방식이다.
애크, 내크, 시퀀스 번호, 타임아웃 등을 활용해서 구현한다.
재전송 프로토콜 1

왼쪽 위가 전송자의 유한 상태 머신이고 오른쪽 아래가 수신자의 유한 상태 머신이다.
현재 버전은
- 애크와 내크가 고장났는지 확인 안 함
- 재전송시 수신자가 해당 패킷이 새 패킷인지 구분할 수 없음
- 스탑 앤 웨이트임
전송자 입장
전송자는 다음과 같은 두 상태를 갖는다.
- 위에서 응용이 패킷을 보내라고 하는 명령을 기다리는 상태
- 응답을 기다리는 상태
초기 상태에서
응용이 무엇을 보내라고 하면
- 데이터와 체크섬을 이용해 패킷을 만들고
- 신뢰성이 보장되지 않는 채널로 패킷을 보낸다.
- 애크를 기다리는 상태로 변한다.
애크를 기다리는 상태에서
패킷을 받았는데 내크이면
- 신뢰성이 보장되지 않는 채널로 패킷을 재전송한다.
- 상태는 변하지 않는다.
패킷을 받았는데 애크이면
- 응용이 자신에게 패킷을 보내라고 하는 명령을 기다리는 상태로 변한다.
수신자 입장
수신자는 하나의 상태만 갖는다.
패킷이 왔는데
오류가 있다면
- 신뢰성이 보장되지 않는 채널로 내크를 보낸다.
- 상태는 바뀌지 않는다.
오류가 없다면
- 패킷에서 데이터를 뽑아내고
- 데이타를 응용에게 주고
- 신뢰성이 보장되지 않는 채널로 애크를 보낸다.
재전송 프로토콜 2
전송자 입장

전송자는 4개의 상태를 갖는다.
- 0번 패킷을 보내라는 명령을 기다리는 상태
- 0번 애크나 내크를 기다리는 상태
- 1번 패킷을 보내라는 명령을 기다리는 상태
- 1번 애크나 내크를 기다리는 상태
스탑 앤 웨이트라 시퀀스 번호는 0, 1 두개이면 충분하다.
초기 상태
응용이 무엇을 보내라 하면
- 시퀀스 번호, 데이터, 체크섬을 이용해서 패킷을 만들고
- 신뢰성이 보장되지 않는 채널로 패킷을 보낸다.
- 0번 피드백을 기다리는 상태로 변한다.
0번 피드백을 받길 기다리는 상태
패킷이 왔는데 오류가 있거나 내크이면
- 신뢰성이 보장되지 않는 채널로 패킷을 재전송한다.
패킷이 왔는데 오류가 없고 애크이면
- 1번 패킷을 보내라는 명령을 기다리는 상태로 변한다.
- 스탑앤 웨이트기 때문에 몇번 애크인지 구분할 필요가 없다.
수신자 입장

수신자는 두가지 상태를 갖는다.
- 0번 패킷을 기다리는 상태
- 1번 패킷을 기다리는 상태
초기 상태
패킷이 왔는데 이상하면
- 체크섬도 넣어서 내크 패킷을 만든다.
- 신뢰성이 보장되지 않는 채널로 패킷을 보낸다.
패킷이 왔는데 이상하지 않고 1번 패킷이 오면
- 수신자는 패킷을 잘 받아 애크를 보냈지만 전송자가 애크를 받지 못한 경우이다.
- 채크섬을 넣어서 애크 패킷을 만든다.
- 신뢰성이 보장되지 않는 채널로 패킷을 보낸다.
패킷이 왔는데 이상하지 않고 0번 패킷이 오면
- 데이터를 뽑아
- 응용에게 주고
- 체크섬을 넣어서 애크 패킷을 만든다.
- 신뢰성이 보장되지 않는 채널로 패킷을 보낸다.
- 1번 패킷이 오길 기다리는 상태로 변한다.
재전송 프로토콜 3

- 이제는 애크만 사용한다.
- 애크에 시퀀스 번호가 붙어 중복 애크를 구분한다.
- 중복 애크는 내크처럼 작동하여 재전송하게 만든다.
전송자 입장
상태는 4가지이다.
- 0번 패킷을 보내라는 명령을 기다리는 상태
- 0번 애크를 기다리는 상태
- 1번 패킷을 보내라는 명령을 기다리는 상태
- 1번 애크를 기다리는 상태
초기 상태
응용이 무엇을 보내라 하면
- 시퀀스 번호는 0으로 하고 데이터와 체크섬을 이용해 패킷을 만들고
- 신뢰성이 보장되지 않은 채널로 패킷을 전송하고
- 0번 애크를 기다리는 상태로 변한다.
0번 애크를 기다리는 상태
패킷을 받았는데 잘못되었거나 1번 애크라면
- 신뢰성이 보장되지 않은 채널로 패킷을 재전송한다.
패킷을 받았는데 오류가 없고 0번 애크라면
- 1번 패킷을 보내라는 명령을 기다리는 상태로 변한다.
수신자 입장
상태는 2가지이다
- 0번 패킷을 기다리는 상태
- 1번 패킷을 기다리는 상태
초기 상태
패킷을 받았는데 잘못되었거나 1번 패킷이라면
- 신뢰성이 보장되지 않는 채널로 1번 애크를 재전송한다.
패킷을 받았는데 오류가 없고 0번 패킷이라면
- 데이터를 뽑아내고
- 응용에게 전달하고
- 0번 애크와 체크섬을 넣어서 패킷을 만들고
- 신뢰성이 보장되지 않는 채널로 패킷으르 보낸다.
재전송 프로토콜 4
- 패킷 로스도 생각한다.
- 로스가 있으니 타임아웃도 도입해야 한다.
전송자 입장

상태는 4가지이다.
- 0번 패킷을 보내라는 명령을 기다리는 상태
- 0번 애크를 기다리는 상태
- 1번 패킷을 보내라는 명령을 기다리는 상태
- 1번 애크를 기다리는 상태
초기 상태
응용이 메세지를 보내라고 하면
- 데이터, 체크섬 시퀀스 번호를 0으로 하면 패킷을 만들고
- 신뢰성이 보장되지 않은 채널로 패킷을 보내고
- 타이머를 설정한다.
어떤 패킷이 오면
- 이미 애크를 잘 받아서 응용의 명령을 기다리는 상태로 변했으므로 중복된 애크일 것이다. 따라서 아무것도 하지 않는다.
0번 애크를 기다리는 상태
패킷이 왔는데 고장났거나 1번 애크라면
- 잘못된 애크를 받았다고 재전송을 하지 않는다.
- 타임아웃이 설정되어 있으니 좀 더 기다리면서 아무것도 하지 않는다.
타임아웃이 발생한다면
- 신뢰성이 보장되지 않은 채널로 패킷을 재전송하고
- 타이머를 설정한다.
패킷이 왔는데 고장나지 않았고 0번 애크라면
- 타이머를 끄고
- 1번 패킷을 보내라는 명령을 기다리는 상태로 변한다.
성능

패킷 하나를 보내는데 걸리는 총 시간은 전송 시간 + rtt이다.
총 시간에서 링크를 이용하는 시간은 전송 시간
전체 시간에 비해서 링크 이용시간이 적다.
스탑 앤 웨이트라 rtt동안 놀고 있기 때문이다.
타임아웃 시간이 짧다면

- 타임아웃이 너무 짧아서 패킷1에 대한 응답이 오기도 전에 재전송이 되었다.
- 재전송한 패킷 1에 대한 응답이 오기 전에 처음 보낸 패킷1에 대한 응답이 왔다.
- 전송자 입장에서는 이를 구분할 수 없고 재전송한 패킷 1이 잘 갔다 생각하고 패킷 0을 보낸다.
- 패킷 0에 대한 응답이 오기 전에 애크 1이 오고 시퀀스 번호가 맞지 않으니 무시당한다.
- 애크 0이 오고 패킷 1이 보내지낟.
이렇게 애크 1이 버려지는 것처럼 낭비가 있을 수도 있다. 따라서 적절한 타임아웃 시간을 정하는 것이 중요하다.