[Network] Network Transport Layer

Dev·2021년 9월 24일
0
post-custom-banner

Transport 계층은 Host의 Process to Process Delivery를 담당합니다. 대표적으로 UDP, TCP 프로토콜이 있는데, TCP는 데이터 신뢰성을 중요시 여겨 필요 이상으로 에러 체크를 하고 UDP는 아무런 체크 없이 일단 패킷을 전송하여 빠른 속도로 패킷을 전달합니다.

1. Multiplexing & Demultiplexing

Transport 계층의 모든 프로토콜은 기본적으로 전송측에서는 Multiplexing을 수신측에서는 Demultiplexing을 수행합니다.

  • Multiplexing : 소켓으로부터 받은 패킷에 필요한 헤더를 추가하여 네트워크 계층으로 전달합니다.
  • Demultiplexing : 네트워크 계층으로부터 받은 패킷의 헤더를 체크하고 적절한 소켓으로 패킷을 전달합니다.

※ Socket

  • IP, Port, Protocol 조합으로 생성합니다.
  • Application 계층과 Transport 계층을 잇는 역할을 합니다.
  • 네트워크와 통신하기 위해서는 소켓을 생성해야 되는데 양방향 통신을 가능케합니다.

2. User Datagram Protocol

인터넷이 혼잡하든, 패킷이 손실되든 신경쓰지 않고 패킷을 그냥 보냅니다. 이것저것 체크할 필요가 없어 빠른 속도로 패킷을 전달할 수 있지만 데이터 손실의 문제점이 존재합니다.

  • 목적지 IP, Port만으로 소켓을 식별합니다. TCP는 통신할 때 각 소켓이 1:1로 통신합니다. 반면 UDP는 여러 유저가 보낸 데이터를 하나의 소켓으로 받아 들이므로 리소스 소모량이 적습니다. 하지만 모든 데이터를 하나의 소켓으로 받아들여 과부화 위험이 있습니다.
  • 헤더의 길이가 8 byte로 매우 작습니다. 왜냐하면 UDP는 패킷이 손실되거나 순서가 바뀌는 등의 데이터 신뢰를 신경 쓰지 않기 때문입니다.
  • Handshking, Flow Control, Congestion Control 등의 과정 없이 패킷을 전달하여 스트리밍, 작은 사이즈의 패킷을 전달할 때 유용합니다.
  • DNS, DHCP, SNMP, Streaming, Telephone etc

3. Transmission Control Protocol

multiplexing, demultiplexing 뿐만 아니라 신뢰성있는 데이터 전송을 위해 다양한 기능을 제공합니다. 데이터 전달을 보증하고 순서까지 보장합니다.

[1] socket

UDP 통신은 하나의 소켓으로 다른 프로세스의 소켓과 통신하는 반면, TCP 통신은 통신할 프로세스마다 1:1 통신을 진행합니다. 예를 들어, 하나의 서버에 여러 클라이언트 요청이 올 경우 door socket으로부터 child socket이 요청마다 생성됩니다.

하지만 성능상 멀티 프로세스보다 경령화된 멀티 스레드를 이용하는 경우가 많습니다.

[2] Communication of TCP

Connection of 3 way handshaking

TCP 프로토콜에서 클라이언트와 서버 사이의 패킷 전송을 위해 통신전 커넥션을 확정짓는 작업입니다.

예를 들어 a(클라이언트)와 b(서버)가 초기에 커넥션을 맺을 때 아래와 유사하게 동작합니다.
1. a -> b : 내 말 들려?
2. a <- b : 응 잘 들려, a야 너도 내 말 잘 들리니?
3. a -> b : 응 잘 들려.

Finishing connection of 4 way handshaking
TCP 프로토콜에서 남은 데이터를 모두 전송하고, 소켓을 닫는 즉, 클라이언트와 서버 사이의 정확한 종료를 위한 작업입니다.

예를 들어 a(클라이언트)와 b(서버)가 통신을 종료할 때 아래와 유사하게 동작합니다.

  1. a -> b : 나는 얼추 보낼 데이터 다 보내서 이제 종료할건데 괜찮아?
  2. a <- b : 알았어, 근데 좀만 기뎌라봐. 나 보낼 데이터 있는지 확인해볼게
  3. a <- b : 남은 데이터 모두 전송
  4. a <- b : 나도 남은 데이터 다 보내서 이제 종료할건데 괜찮아?
  5. a -> b : 알았어. 이제 우리 모두 종료하자

서버가 마지막에 FIN 을 보내는 이유는 서버가 아직 클라이언트에 보낼 데이터가 남아있을 경우 때문입니다.

클라이언트가(a) 마지막에 FIN 신호를 받고 바로 종료하지 않고 TIME_WAIT 상태로 일정 시간을 기다리는 이유는 서버로(b) 보낸 ACK 신호의오류가 있을 수 있기 때문이다. 이 경우 재 전송해야되는데 소켓을 미리 종료하면 문제가 발생합니다.

[3] Reliable Data Transfer [RDT]

메시지 전송 중 발생하는 패킷 에러, 손실을 처리하는 프로토콜입니다

  • 패킷의 SEQ 넘버를 포함하여 보내고, 일정 기간 안에 보낸 SEQ 넘버에 대응하는 ACK 넘버를 수신하면 패킷이 정상적으로 보낸것으로 판단합니다.
  • 일정기간 안에 원하는 ACK 넘버를 수신하지 못하면 패킷의 오류 혹은 손실로 판단합니다.
  • ACK 신호를 반환할 때 수신된 패킷 중 처음부터 연속되어 잘 받은 마지막 패킷 ACK 신호를 전송합니다. 예를 들어, 1부터 5까지 패킷을 보냈고 1번, 2번, 4번, 5번 패킷은 잘 수신했지만 3번 패킷만 문제 있는 경우 2번에 해당하는 ACK신호를 반환합니다. 이후 클라이언트에서 3번패킷을 재전송하고 서버에서 3번 패킷을 잘 수신했다면 5번에 대응하는 ACK 신호를 반환합니다.
  • 패킷 에러는 SEQ 넘버에 대응하는 ACK 넘버로 판단합니다.
  • 이번엔 패킷이 손실된 경우입니다. 패킷이 손실되면 어떤 이벤트도 일어나지 않습니다. 이를 timer를 두어 해결합니다. 합리적 시간을 재서 그 시간안에 응답이 오지 않으면 패킷의 손실로 판단합니다.
  • 만약 클라이언트가 서버에게 리퀘스트를 보내고 기다리는데 서버에서 비즈니스 로직 처리 시간이 너무 길어 지정된 시간을 넘어설 경우 패킷의 문제가 없음에도 불구하고 클라이언트는 timeout을 외치는 경우도 존재합니다.

Acknowledge Number [ACK]
수신측에서 송신측으로 패킷이 잘 왔는지 여부를 알려줍니다. 즉 가장 최근에 잘 받은 패킷 넘버를 전달합니다.

Sequence Number [Seq]
송신측에서 수신측으로 전송할 패킷의 고유 번호로 0부터 차례로 맵팽하여 전달합니다.

Comulative ACK
현재까지 수신된 패킷들을 단 하나의 ACK으로 일괄 확인응답 하는 것을 말합니다. 1번부터 5번패킷이 잘 수신됬다면 5번에 대응하는 ACK 넘버만 반환하면 됩니다. 만약 1번 ~ 5번 패킷을 받았는데 3번 패킷의 에러가 있을 경우 2번 패킷에 대응하는 ACK을 전달하고 4번, 5번은 보관하고 있습니다. 이후에 3번 패킷이 재전송되면 보관하던 패킷들을 참조하여 5번 패킷에 대응하는 ACK 신호를 반환합니다. 이는 Fast Retransmit과 함께 사용하기도합니다.

4. Packet 전달 방식

[1] Stop and Wait

패킷 전송 후 알맞은 ACK 신호가 올때까지 기다리는 방식을 말합니다. 동기적으로 처리하여 이해가 쉽지만 먼 거리를 왔다 갔다하는 상황이라면 즉 RTT 시간이 길다면 비효율적입니다.

[2] Pipelining

확인 응답을 기다리지 않고 다중 패킷을 전송합니다. 중간에 패킷이 손실될 수 있는데 다중 패킷 손실 대비책으로 GBN과 SR 방식이 있습니다.

[3] Go Back N

중간에 패킷 손실시, 손실된 패킷 이후부터 모두 재전송하는 메커니즘입니다.
만일 3번 패킷까지만 수신 했고, 4번 패킷이 도착 하지 않았다면 수신측은 4번부터 날아오는 패킷들을 모두 버리고 4번 패킷이 날아오길 기다립니다. 동기적으로 처리하여 구현이 편리하지만, 순서가 낮은 패킷이 손실되면 이후의 모든 프레임을 재전송해야 하는 단점이 있습니다.

[4] Selective Repeat

잘못된 순서의 패킷을 받았더라도 버퍼에 저장하고 중간에 수신을 실패한 패킷만 재전송 합니다. 최종적으로 패킷을 재정렬하는 비용이 필요합니다. TCP는 신뢰성있는 데이터 뿐만 아니라 순서 역시 보증하기 때문입니다. 실패한 패킷만 재전송하므로 성능이 좋지만 구조가 복잡하고 재정렬하는 단점이 있습니다.

5. Flow Control

송신측과 수신측의 데이터 처리 속도 차이 문제를 해결합니다. 수신측이 송신측보다 빠르게 패킷을 처리하는 것은 문제가 없지만 송신측이 수신측보다 속도가 빠르면 문제가 발생합니다. 수신측에 패킷이 오면 큐에 패킷을 담는데 큐에 공간보다 크게 패킷이 모일 경우 데이터 손실이 발생합니다. 따라서 window 사이즈를 참고하여 송신측의 속도를 조절합니다.

6. Congestion Control

인터넷의 혼잡을 피하기 위해 송신자의 전송속도를 줄이는 방법입니다. 만약 한 라우터에 데이터가 몰릴 경우, 자신에게 온 데이터를 모두 처리할 수 없습니다. 이 경우 몇몇의 패킷은 다시 재전송하고 이는 오버헤드로 이어집니다. 따라서 송신측의 데이터 전송 속도를 강제로 줄입니다.

[1] Additive Increase / Multicative Decrease

  • window size에 해당하는 패킷 모두가 문제 없이 도착하면 window 크기를 1씩 증가합니다.
  • 만약 패킷 전송이 실패한다면 window 크기를 절반으로 줄입니다.
  • 네트워크 수용량 근처에서 효율적으로 동작합니다.
  • 하지만 처음에 전송 속도를 올리는데 오랜시간이 걸립니다.

[2] Slow Start

  • ACK 패킷마다 window size가 1씩 증가하여 한 주기가 지나면 window size가 2배로 증가합니다. 즉, window 크기가 지수 함수 꼴로 증가합니다.
  • 패킷 오류시 window를 1로 감소시킵니다.
  • 전송 속도를 빠르게 증가시킬 수 있지만 네트워크 수용량 근처에서 오랫동안 머무르지 못합니다.

[3] Fast Recovery

Slow Start 처럼 window size를 증가시키다가 혼잡상태를 만나면 window size를 1이 아닌 절반으로 감소시킨 후 선형적으로 증가시키는 방법입니다.

Congestion Avodance
Threshold 전까지 Slow Start로 빠르게 전송 속도를 올리고 Threshold를 넘어서면 AIMD 방식으로 전송 속도를 천천히 올리는 방식을 말합니다. 여기서 Threshold란 "여기서부터는 네트워크 수용량 근처니 천천히 올라가세요" 의미와 비슷합니다.

[4] Fast Retransmit

  • 재전송 타이머 값이 상대적으로 길 경우 패킷을 재전송하는데 많은 시간이 소모됩니다. 따라서 중복 ACK 방식으로 손실된 패킷을 검출합니다.
  • 누적 ACK 신호를 보내기 때문에 이전에 잘 받은 ACK 넘버를 계속 받으면 받아야할 패킷의 문제가 있음을 알 수 있습니다.
  • 하지만 패킷 스위칭을 사용하다보면 패킷의 순서가 달라질 수 있기 때문에 2번까지는 괜찮고 3번부터는 문제가 있음으로 판단합니다.

7. Transport Header

* Window

  • Window : 데이터를 보내기 전 3 way-handshaking 을 통해 수신측이 데이터를 받을 수 있는 버퍼양과 송신측이 데이터를 보낼 양을 맞추게 되는데 이 데이터 양을 window size라고 합니다.
  • CWND : 송신할 수 있는 패킷의 양으로 Congestion Control에 필요합니다.
  • RWND : 수신할 수 있는 패킷의 양으로 Flow Control에 필요합니다.
profile
성장하는 개발자가 되고싶어요
post-custom-banner

0개의 댓글