인터넷 프로토콜에는 두 가지의 종류가 있다.
TCP/IP 표준과 OSI 표준 두 가지가 존재하는데, TCP/IP 표준에서 응용계층이 Application, Presentation, Session 세 가지의 계층으로 나뉜 것이 OSI 표준이다.
전송 계층
전송계층은 TCP 또는 UDP 연결을 하는 단계이다.
TCP
TCP 연결은 아래 네 가지 기능을 제공한다.
- 신뢰성: 오류 발생 시 탐지 및 복구, 파일을 순서대로, 중복을 제거하여 전송
- 흐름제어: 수신자의 상태에 따른 전송량 조절
- 혼잡제어: 네트워크 + 수신자의 혼잡 상태(Buffer에 패킷이 많은 경우)에 따른 전송량 조절
- 연결 관리: TCP 연결을 관리함.
UDP
UDP는 어떠한 기능도 제공하지 않는다.
TCP에서 기본적으로 제공하는 기능으로 인해 최대 속도에 한계가 생기자
부가적인 기능을 배제하고 전송에만 초점을 맞추어 개발한 패킷이다.
전송 계층 활용 시에 가장 간단하다는 장점이 있다.
TCP 패킷과 UDP 패킷은 공통적으로 일정 시간 내에 도착해야 하는 지연 시간과
패킷 전달 시 요구되는 대역폭을 보장해주지는 않는다.
프로세스
전송은 하나의 프로그램과 같이 프로세스로 동작한다.
따라서 전송계층의 양끝인 송신자, 수신자는 프로세스로 동작하며
포트번호를 통해서 프로세스를 식별한다.
위 사진에서 각 ip 주소 끝 콜론(:) 뒤에 존재하는 번호가 포트번호로
프로세스를 구분해주는 번호이다.
멀티플렉싱 / 디멀티플렉싱
통신 시, 데이터를 각 계층 별로 헤더를 붙여 패킷화를 한다.
수신자를 향해 패킷이 전달되려면 많은 라우터를 건너가는데,
라우터를 건너갈 때 라우터에서 수신자까지로의 ip를 변경해준다.
다시 이야기 하자면, 컴퓨터가 패킷을 수신했을 때 이 패킷을 어떤 프로세스에 전달해야 하는지 알기 위한 과정이다.
ip를 변경하기 위해서는 목적지가 어디인지 확인을 하기 위해 패킷의 헤더를
계층별로 벗겨내고 이후 다시 전송하기 위해 헤더를 입혀주는 과정이 필요한데,
이 과정에서 헤더를 입히는 작업이 multiplexing, 헤더를 벗기는 작업이 demultiplexing이다.
따라서 프로세스에게 패킷을 전달하는 과정이 mulplexing로 구현되어 있어야 한다.
- Demultiplexing: 수신 세그먼트(패킷)를 적절한 소켓에 전달
- Multiplexing: 여러 소켓에서 데이터를 수집, 적절한 헤더를 붙임
UDP Multiplexing
UDP는 connectionless demultiplexing이므로 연결을 생성할 필요가 없다.
TCP Multiplexing: port, thread
쓰레드 단위는 multiplexing하는 포트번호로 식별하지 않는다. context swith를 통해 식별한다.
UDP(User Datagram Protocol)
UDP는 RFC768 표준으로 포트번호를 이용한 멀티플렉싱 이외의 기능이 없으며,
연결 또한 만들지 않는다. (connectionless)
UDP는 아래와 같은 장점으로 인해 사용한다.
1. 연결 설정을 하지 않고 헤더크기가 작기 때문에 빠르게 전송이 가능하다.
2. 재전송을 하지 않기 때문에 단순하다.
따라서 게임, 화상회의 WebRTC, 구글의 QUIC(HTTP/3)에 주로 사용한다.
UDP Packet
UDP 패킷의 생김새를 보자.
이때, checksum 칸은 bit 오류만 확인하며 필수적인 부분은 아니다.
UDP CheckSum
UDP checksum은 전송된 세그먼트의 bit 에러를 탐지하기 위해 존재한다.
체크섬은 세그먼트 내용의 합에 대해 1의 보수를 취한 것이다.
송신자
송신자는 세그먼트의 내용을 16비트의 정수 단위로 취급하여
체크섬의 값을 UDP checksum 필드에 채운다.
수신자
수신자는 수신된 세그먼트에 대해 체크섬을 계산한 후
계산된 체크섬 값이 필드의 값과 동일한지 검사한다.
동일하지 않다면 오류가 발생한 것이고 동일하다면 오류가 발생하지 않은 것이다.
하지만 오류가 발생하지 않았다고 확정할 수 없다.
이 문제에 대해서는 나중에 알아보자.
아래 예제를 통해 체크섬을 자세하게 보도록 하자.
체크섬을 계산 할 때에는 최상위 비트의 캐리아웃 값은 결과에 다시 더해야 한다.
신뢰성 있는 데이터 전송 원리
신뢰성 있는 데이터의 전송은 응용, 전송, 링크 계층에서 매우 중요하다.
일반적인 절차로는
1. 패킷 손실 발생 탐지
헤더 체크섬으로는 패킷이 도착하지 않은 경우 탐지가 안 되므로 순서번호를 통해 확인해야 한다.
2. 재전송을 통한 패킷 복구
재전송 시 필요한 도구는 타이머/순서번호, 재전송 패킷(버퍼에 저장)이 있다.
이러한 오류 탐지 및 재전송 프로토콜은 ARQ(Automatic Repeat Request)라고 한다.
ARQ의 종류는 아래와 같으며, 하나씩 살펴보자.
- Stop-and-Wait ARQ
- Go-back-N ARQ
- Selective-Repeat ARQ
- TCP
ARQ에 대한 설명을 들어가기에 앞서 기본적인 용어를 알고 가자.
ACK: 수신 측에서 순서에 맞는 정상적인 패킷을 수신했을 때 전달하는 응답 패킷이다.
NAK: 수신 측에서 순서에 맞지 않는 비정상적인 패킷을 수신했을 때 전달하는 응답 패킷이다.
Stop-and-Wait ARQ
위 방식은 패킷을 하나 전송한 후 타이머를 가동시켜 전송한 패킷에 대해 ACK이나 NAK를 수신하는 프로토콜이다.
구현 방식이 단순하고, 송신 윈도우와 수신 윈도우의 크기를 1로 설정하여 물리 자원이 풍부하다.
하지만, 하나의 패킷을 보낸 후 타이머가 종료되거나 ACK나 NAK를 수신할 때까지
기다리기만 해야 하므로 전송 효율이 떨어진다.
1Gbps인 대역폭에 15ms의 전파지연시간이 발생한다고 했을 때, 8000bits인 패킷을 보낸다고 가정하자.
이 가정에서 전송지연시간은 아래와 같다.
전송지연시간이 8micro초라고 할 때 RTT(Return Trip Time)는 전파지연시간의 2배로 계산한다.
따라서 RTT는 15ms = 15,000이고 15,000micro * 2 = 30,000이다.
실제로 전송에 필요한 시간은 30,000 + 8 = 30,008micro초로 30.008ms이다.
위 계산된 식을 통해 utilization 시간을 구할 수 있다.
이때 utilization이란 주어진 시간 동안 얼마의 용량을 사용하고 있는가를 나타낸다.
Pipelining Protocol
Pipelining은 송신자가 ACK 신호를 수신하지 않아도 여러 개의 패킷을 송신하는 것이다.
따라서 송수신자의 sequence number 범위가 커져야 하고, 버퍼링이 필요하다.
파이프라이닝 프로토콜은 Go-Back-N과 seletive repeat에서 사용된다.
위 Stop-and-Wait와 동일한 조건에서 utilization을 구했을 때,
3개의 패킷을 연속으로 전송하기 때문에 효율이 3배 좋아진 것을 확인할 수 있다.
Go-Back-N
GBN에서 송신자는 ACK를 수신받지 않은 N개의 패킷을 전송할 수 있다.
수신자는 누적 ACK를 전송한다. 이 말은 ACK를 하나만 유지한다는 뜻이다.
송신자는 가장 오래된 ACK 미수신 패킷에 대한 타이머를 유지하여
타이머 초과 시 ACK 미수신한 모든 패킷을 재전송한다.
이때 송신자는 sliding window 기법을 사용하는데, 이때 윈도우의 크기는
송신자가 수신자로부터 ACK 신호를 받지 않아도 보낼 수 있는 양을 말한다.
그러나 수신자의 윈도우 크기는 1이다.
따라서 한 번에 여러 개의 패킷을 수신하지 못하고 해당 번호에 맞는 패킷만 수신할 수 있는 것이다.
따라서 GBN 프로토콜을 통해 패킷 전송 시 패킷 loss가 발생하면
아래 사진과 같이 작동한다.
윈도우의 크기가 4이므로 4개까지의 패킷을 전송할 수 있다.
이때, 중간에 두 번째 패킷이 손실되었다.
따라서 이후에 패킷3, 4, 5를 전송해도 수신자 윈도우는 패킷2만 수용할 수 있으므로
3, 4, 5번째 패킷을 받을 수 없어 ACK번호 1를 계속 전송한다.
이후 타이머가 타임아웃이 되면 ACK 1 만 받았기 때문에
원래 수신자가 기대했던 2, 3, 4, 5번의 패킷을 차례대로 송신한다.
또한, 1번 패킷에 대한 ACK 1을 받았을 때 2번 패킷의 타이머를 계산하여 손실을 탐지한다.
즉, 위 사진에서도 ACK가 오지 않은 가장 최근의 패킷(2번 패킷)에 대해 타임아웃까지의 타이머를 계산한다.
이때, 사진에서는 매 패킷마다 ACK를 전송하였지만 수신 윈도우의 크기가 1이므로
만약 0, 1, 2, 3번째의 패킷을 잘 받았을 때 ACK 3만 전송해도
송신자는 0, 1, 2, 3번째의 패킷을 수신했다고 판단할 수 있다.
이후 4번째 패킷이 손실되었을 때 ACK 3을 계속해서 전송하면
송신 측에서 손실이 발생함을 알아차리고 타이머가 종료되면 재전송한다.
Seletive Repeat
마찬가지로 Selective-Repeat 방식도 ack를 수신하지 않고 N개의 패킷을 전송한다.
이때 상위 계층으로 순서에 맞는 데이터 전달을 위해서 패킷 버퍼링이 필요하다.(버퍼: 데이터를 다른 곳으로 전송하는 동안 일시적으로 데이터를 보관하는 메모리 영역,버퍼링: 버퍼를 채우는 동작)
수신자는 매 패킷마다 ACK 신호를 전송하고 송신자는 ACK 미수신 패킷에 대해서만 재전송을 진행한다.따라서 송신자는 타이머를 모든 ACK를 미수신한 패킷에 대해 유지한다.
이때 수신자도 마찬가지로 여러 개의 패킷을 수신하고 각 패킷 별로 ACK를 전송해야 하므로수신자의 윈도우 크기 또한 2 이상이어야 한다.
사진에서 위가 송신자, 아래가 수신자의 윈도우 모습이며
수신자의 윈도우에서 수신 받은 패킷은 분홍색, 수신 받지 못한 패킷은 회색으로
순서에 맞지 않는 패킷이라도 잘 수신함을 보여준다.
또한 송신자의 패킷에서 초록색은 전송한 패킷에 대해 ACK 신호를 잘 수신한 것이고,
노란색은 전송한 패킷에 대해 아직 ACK를 미수신한 패킷이다.
위 사진을 통해 Seletive-Repeat 프로토콜을 더 잘 이해할 수 있을 것이다.
두 번째 패킷이 손실됐을 때 두 번째 패킷에 대한 타이머가 타임아웃이 될 경우 두 번째 패킷만 재전송한다.
Seletive-Repeat Dilemma
이 Seletive-Repeat 프로토콜에서는 딜레마가 존재한다.
송신자와 수신자는 서로의 상태를 전혀 모르는 상태이므로
현재 내가 전송하는 0번째 패킷이 앞에서의 0번째인지, 뒤에서의 0번째인지 가늠할 수가 없다.
0, 1, 2의 패킷을 전송했을 때 모든 패킷에 대한 ACK를 수신하고
3번 패킷을 전송한다면 문제가 없다.
만약, 0, 1, 2번 패킷을 수신자는 잘 받았지만 ACK 신호가 모두 손실되는 경우
송신자 측은 0번 패킷을 재전송할 것인데, 수신자는 이미 윈도우를 슬라이딩하여
옳지 못한 자리에 0번 패킷을 수신할 수 있는 것이다.
이러한 문제는 송신자의 윈도우 크기가 너무 크면 발생하는 문제이므로 윈도우의 크기를 조정해야 한다.
위의 사진은 Seletive-Repeat 프로토콜에서 발생하는 경우이다.
Seletive-Repeat 프로토콜에서는 윈도우의 크기를 2의 m-1승인 크기로 설정해야 하며,
2의 m-1승보다 커서는 안 된다.
아래의 사진은 GBN 프로토콜에서 발생하는 경우이다.
GBN 프로토콜은 송신자의 윈도우 크기는 2의 m승(bit)보다 작아야 한다.
출처 및 참고
https://seungjuitmemo.tistory.com/83
https://velog.io/@dongvelop/ARQAutomatic-Repeat-Request%EB%9E%80
https://raptor-hw.net/xe/computing/135396
https://ko.wikipedia.org/wiki/%EB%B2%84%ED%8D%BC_(%EC%BB%B4%ED%93%A8%ED%84%B0_%EA%B3%BC%ED%95%99)
'Computer Science > 컴퓨터네트워크(ComNet)' 카테고리의 다른 글
[컴네/CN] TCP (0) | 2023.12.04 |
---|---|
[컴네/CN] 비동기 프로그래밍 (1) | 2023.12.04 |
[컴네/CN] 응용계층 프로토콜: FTP, SMTP (1) | 2023.11.29 |
[컴네/CN] 응용 P2P (1) | 2023.11.29 |
[컴네/CN] 응용 DNS (0) | 2023.11.29 |