[Network] UDP, TCP
- [ CS기초 ]/네트워크
- 2022. 2. 15.
네트워크의 전송 계층에서 데이터의 전송을 위해 사용하는 프로토콜에는 여러 가지가 있는데, 그 중에서 대표적인 것으로 UDP와 TCP가 있다.
IP를 사용하여 패킷을 전달하는데는 여러가지 문제가 있다. 송신자는 수신자 서버의 상태를 알 수 없고, 전달 과정 중 패킷이 유실될 수도 있고, 큰 데이터를 여러 패킷으로 나누어 데이터를 전송하는 과정에 패킷의 순서가 뒤바뀔 수도 있다. 이러한 문제는 IP프로토콜만으로는 해결할 수 없고, TCP와 같은 추가적인 프로토콜을 사용하여 해결할 수 있다.
1. UDP (User Datagram Protocol)
UDP는 '빈 껍데기'같은 프로토콜이라고 할 수 있다.
UDP는 "best effort" service이다. best effort라 함은 계층에서 데이터의 전송을 위해서 최대의 노력은 하지만 보장은 하지 않는다는 의미이다. 즉, 데이터의 손실이나 out of order와 같은 현상이 발생할 수 있다.
또한 UDP는 비연결형(connectionless) 프로토콜이다. 이것은 데이터를 주고받을 때 송/수신측에 별도의 연결 과정 없이 일방적으로 데이터를 발생하는 것을 말한다. 즉 각각의 패킷들이 다른 경로로 전송되고, 각각의 패킷은 독립적인 관계를 가지게 된다. 연결지향형과 다르게 3-way handshake와 같은 연결과정이 없으며, 들어오는 순서대로 독립적으로 전달된다.
UTP는 흐름제어(데이터 송수신의 처리 속도를 조절하여 수신자의 버퍼 오버플로 방지)와 혼잡제어(네트워크망의 패킷 수가 일정 수치 이상 넘지 않도록 조절)같은 기능도 처리하지 않고 연결과정이 없으며 순서 보장도 하지 않기에 TCP와 같은 연결형 프로토콜보다 속도가 빠른 대신, 신뢰성이 낮다는 단점을 가진다.
UDP header (8byte)
이러한 이유로 UDP의 segment header는 단순하다는 특징을 갖는다. (IP에서 포트정도만 추가된 형태를 가진다.)
- source/dest port
: source port#는 메세지 송신 측의 port번호, destination port#는 메세지 수신 측의 port번호를 의미한다. UDP는 connectionless한데 왜 source port#가 필요한지 궁금할 수도 있는데, reply와 interface를 위해서 존재한다고 한다 (https://stackoverflow.com/questions/33593966/why-do-i-need-source-port-on-udp)
- length
: 헤더와 데이터를 합한 데이터그램의 전체 길이를 정의한다. UDP 데이터그램의 헤더는 8바이트 크기를 가진다
- checksum
: 전달받은 세그먼트에서 데이터를 감지하기 위해서 사용한다.
간단하게, 세그먼트의 헤더와 데이터를 16bit 정수 단위로 모두 더하여 합을 구하고 보수를 취해주면 checksum이 된다. 수신 측에서는 이렇게 전달된 checksum과 수신측에서 계산한 checksum을 비교하여 오류가 존재하지 않으면 전송도중 error가 발생하지 않은 것으로 간주한다
2. TCP (Transmission Control Protocol)
TCP를 해석하자면 전송을 제어하는 프로토콜이라는 뜻으로, 일반적으로 IP와 함께 사용된다. IP가 데이터의 전송을 처리한다면 TCP는 패킷을 추적 및 관리하는 역할을 맡는다.
TCP는 연결지향형(Connection-Oriented) 프로토콜이다. UDP와 다르게 1:1송수신 관계를 가지며, handshaking과 흐름제어(flow-control), 순서정렬(in-order)과 같은 기능들을 가지고 있기 때문에 신뢰할 수 있는 프로토콜로 평가받는다.
TCP는 신뢰할 수 있는 통신을 위해 가상 회선 방식을 사용한다. 통신에 앞서 서버와 클라이언트가 1:1로 3-way Handshaking(SYN, SYN/ACK, ACK)을 통해서 송수신 경로를 특정하여 세션(논리적인 연결)을 만들어 확실한 in-order한 전송을 보장한다. 이를 위해서 rdt service를 사용하는데, rdt의 timeout이 발생하거나 3개의 중복된 ACK를 받게 될 경우 재전송을 통해서 신뢰성을 유지한다.
timeout이 이루어지는 경우 (패킷의 손실 or 네트워크 지연 등)
fast retransmit (3 duplicate ACKs)이 발생하는 경우 (데이터 유실)
flow control
먼저 TCP는 송신측과 수신측의 데이터 처리 속도 차이를 해결하기 위해서 흐름제어를 사용하며, receiver가 처리 속도에 비해 너무 많은 패킷을 받아서 패킷이 손실되지 않도록 하는 것에 중점을 둔다. 이를 위해서 receiver가 sender에게 현재 자신의 상태에 대한 feedback을 날리는데, 이를 receiver가 sender를 control한다고 표현하기도 한다.
대표적으로 control의 방법에는 2가지가 있는데, rdt 초기방식에서 사용되던 stop-and-wait방식은 한 개의 패킷에 대한 ACK가 이루어져야만 다음 패킷을 전송하는 방식으로, 속도에서 손실을 많이 보기 때문에 보통 sliding window방식을 사용한다.
sliding window는 수신측에서 설정한 버퍼(window)의 크기만큼 송신측에서 확인응답 없이 세그먼트를 전송할 수 있게하여 데이터의 흐름을 조절하는 제어 기법을 의미한다. receiver는 TCP 헤더의 rwnd값을 통해서 여유 버퍼공간을 sender에게 알려주고, sender는 그 값을 전달받아 수신측에서 오버플로가 일어나지 않도록 데이터를 전송한다.
congestion control
먼저 혼잡이란 네트워크가 처리할 수 있는 속도보다 너무 많은 양의 정보를 보내는 것을 의미한다. sender가 보낸 데이터는 네트워크망을 통해서 전달되는데, 만약에 한 라우터에 너무 많은 양의 데이터가 몰릴 경우, 그 라우터는 자신에게 전달된 데이터를 모두 처리할 수 없게 되고, 결국 패킷이 손실되어 재전송이 이루어져야 하는 상황이 생기는데 이러한 혼잡은 버퍼 오버플로와 데이터 손실을 유발한다. 그래서 네트워크의 혼잡을 피하기 위해서 송신측에서 보내는 데이터의 양을 조절하는 작업을 혼잡제어라고 한다.
흐름제어와의 큰 차이는, 흐름제어는 송수신 사이의 전송속도를 다루고, 혼잡제어는 호스트와 라우터를 포함한 넓은 관점에서의 전송 문제를 다룬다는 것이다.
네트워크 상의 혼잡제어의 방법으로는 크게 두가지가 사용되는데, sender가 스스로 감지하여 제어가 이루어지는 End-end congestion control과, router가 망의 상태를 end system에 알려주는 Network-assisted congestion control이 존재한다. 두번째 방법은 라우터가 망의 상태를 알고있어야 하기 때문에 단일망일 경우에 사용되고, 첫번째 방법은 인터넷같이 단일망이 아닐 경우 sender가 스스로 추측하여 감지해야 하는 상황일 경우 사용된다.
TCP에서의 혼잡제어는 additive increase, multiplicative decrease(AIMD)와 slow start로 표현할 수 있다.
처음에 TCP는 exponential하게 데이터 전송량을 증가시킨다.(slow start) 그러다가 임계점(threshold)에 다다르면 지수적 증가를 멈추고, AIMD방식으로 전환하여 선형적 증가로 변환하여 window의 크기를 증가시킨다.
이러한 식으로 window size가 계속 증가하다가, timeout이나 3 duplicate ACKs등의 이유로 재전송이 발생하면 그 때 window size를 감소시키는데, Multiplicative하게 감소가 이루어진다. 그런데 timeout과 duplicate ack라는 두 가지 케이스에 따라서 감소폭이 다르다.
3 duplicate ack의 경우 전송 stream에서 일부 패킷이 lost되었음을 알 수 있다. 즉, 어떤 error로 인해서 일부 패킷의 loss만 발생되었을 뿐 아직 전체적인 연결은 유지되고 있다. 하지만 timeout이 발생했다는 뜻은, 어떤 시점 이후의 패킷들의 전달이 전혀 이루어지지 않고 있음을 의미한다. 따라서 전송 경로에 심각한 장애가 발생하였고, receiver가 현재 데이터 전송을 받을 수 없는 상태임을 의미하기도 한다.
따라서 duplicate ACK의 경우 재전송이 발생하기 전 버퍼 사이즈의 1/2정도로 감소시키고, timeout이 발생했다면 버퍼 사이즈를 1로 초기화시켜서 다시 slow start가 이루어지도록 한다.
TCP segment Header (20+byte)
UDP와 다르게 TCP header에는 reliable한 컨트롤을 위한 장치들이 추가되었다.
- source/dest port #
: UDP와 동일하게 세그먼트의 출발지와 목적지를 나타내기 위해 IP주소와 포트번호가 필요한데, IP주소는 네트워크계층의 헤더에 담기고 TCP헤더에는 포트를 표시하는 필드만 존재한다.
- sequence number
: 데이터의 순서를 파악하는데 사용된다.
-acknowledgement number
: 수신측에서 예상하는 다음 시퀀스 번호를 의미한다.
(seq#80에 대해서 20bytes의 데이터가 들어왔다면, 다음 받아야하는 seq번호는 seq#100으로, ACK 100을 보낸다)
-receive window
: 한번에 전송할 수 있는 버퍼(window)의 크기를 의미한다.
-checksum
: 데이터 송신 중에 생길 수 있는 오류를 검출하기 위한 값이다.
'[ CS기초 ] > 네트워크' 카테고리의 다른 글
[Network] IP (Internet Protocol) (0) | 2022.03.06 |
---|---|
[Network] Network Layer (0) | 2022.03.04 |
[Network] Transport Layer (0) | 2022.02.11 |
[Network] 웹과 HTTP (0) | 2022.02.08 |
[Network] HTTP 쿠키와 세션 (0) | 2022.02.03 |