TCP와 UDP
최근 UDP 통신 기능이 있는 어플리케이션을 개발하였다. 프로젝트를 마무리한 기념으로 TCP와 UDP 개념에 대해 정리해보자.
OSI 7 Layer와 TCP/IP 스택
TCP와 UDP의 동작 원리를 이해하기 위해, 먼저 OSI 7 Layer와 TCP/IP 스택의 개념을 살펴보려고 한다. OSI 7 Layer와 TCP/IP 스택은 네트워크 통신을 이해하고 설명하기 위한 두 가지 주요 네트워크 아키텍처 모델이다. 두 모델은 발전 과정, 계층 수, 관리 주체가 다르다.
OSI 7 Layer은 국제 표준화 기구(ISO)에서 개발한 이론적인 모델로 네트워크 시스템 구성을 위해 개발된 범용적인 모델이다. 7개의 계층으로 나누어져있고 ISO/IEC에서 관리한다.
TCP/IP 스택은 인터넷 프로토콜 스택으로 개발되었다. 4개의 주요 계층으로 구성되어 있으며 응용-표현-세션 계층과 물리-데이터 링크 계층이 하나의 계층으로 통합되어 있다. IETF에서 RFC 문서를 기반으로 관리한다.
요약하면, OSI 7 Layer은 이론적인 개념이며 네트워크 교육에 사용하기 위한 추상적인 프로토콜 스택이고 TCP/IP 스택은 현실 세계의 인터넷과 실제 네트워크 통신에 사용되는 실질적인 프로토콜 스택이다.
TCP/IP의 등장 배경
TCP/IP 스택의 관점에서 TCP와 UDP 프로토콜은 전송 계층(transport layer)의 프로토콜이고, IP는 인터넷 계층(internet layer)의 프로토콜이다. 전송 계층은 데이터의 전송과 통신을 관리하고 제어한다. 인터넷 계층은 데이터 패킷을 목적지로 라우팅하고 전달하는 역할을 한다.
IP(Internet Protocol)는 비신뢰성(unreliability)이라는 특징을 가지고 있다. 비신뢰성이란 데이터의 신뢰성과 순서를 보장하지 않는다는 의미로 전송과정에서 패킷이 사라지거나 손상될 수도 있으며(data-ross), 패킷의 순서가 일치하지 않을 수 있다(out-of-order). 그래서 IP의 상위 프로토콜로써 데이터를 안정적으로 주고받을 수 있도록 고안된 프로토콜이 바로 TCP(Transmission control protocol)이다.
TCP(Transmission Control Protocol)
TCP는 신뢰성과 정확성이 우선인 연결형(connection-oriented) 통신 프로토콜이다. 데이터를 세그먼트로 나누어 전송하며, 각 세그먼트에는 헤더와 데이터 부분이 있다.
- source port, destination port: 출발지와 목적지의 포트 번호다.
- sequence number: 데이터 스트림의 일련 번호로 수신자는 분할된 세그먼트를 순서대로 재조립하고 중복된 데이터는 폐기한다.
- acknowledgment number: 확인 응답 번호로 마지막으로 수신 성공한 sequence number에 1을 더하여 응답한다. 확인 응답번호가 N번이라면 N-1번까지 오류없이 수신했다는 의미다.
- data offset: 헤더 길이 필드로 데이터의 시작 위치를 나타낸다. 헤더 길이는 최소 20~60 byte다.
- reserved: 미래에 사용하기 위해 예약된 필드다.
- flag bits: TCP 연결 설정, 유지, 해제 및 데이터 전송 제어를 위해 사용된다.
- URG (Urgent): 긴급 데이터를 전달하기 위해 사용된다. URG가 1로 설정되면 순서에 관계없이 먼저 송신된다.
- ACK (Acknowledgment): Acknowledgment Number필드의 유효여부를 나타내는 필드다. 1이면 확인번호 유효, 0이면 확인번호 미포함이다.
- PSH (Push):수신자가 상위 계층 응용 프로그램에 데이터를 즉시 전달하도록 요청하는 필드다. TCP 소켓이 생성되면 출력 버퍼(send socket buffer)와 입력 버퍼(receive socket buffer)라는 메모리 공간이 자동으로 생성된다. 버퍼는 세그먼트가 일정량 적재된 뒤에 전달하지만, PSH 플래그가 1로 설정되면 버퍼링을 최소화하고 데이터를 즉시 전달한다.
- RST (Reset):연결을 재설정할 때 사용된다. RST가 1로 설정되면 TCP 연결을 강제로 종료한다.
- SYN (Synchronize):초기 TCP 연결을 설정할 때 시퀀스 넘버를 동기화하기 위해 사용된다.
- FIN (Finish):연결을 종료할 때 사용된다.
7. window size: 수신자의 버퍼 한계 크기 값, 즉 연속해서 송수신할 수 있는 데이터 크기를 나타낸다.
8. checksum: 데이터의 무결성을 검증할 때 사용된다.
연결 확립: 3-way handshake
데이터를 전송하기 전에 연결을 확립하기 위해 패킷 요청을 3번 교환하는 것을 3-way handshake라고 한다.
- 호스트 A 연결 확립 요청(SYN) 호스트 A는 호스트 B에게 연결 확립 요청(SYN, x)을 보낸다. 최초의 Sequence Number(ISN, Initial Sequence Number)는 임의의 난수를 지정하는데, 이는 두 호스트가 TCP 포트번호를 재사용하는 경우 과거connection과의 혼동을 방지하기 위해서다.
- 호스트 B 연결 확립 응답 및 연결 확립 요청 (SYN-ACK):호스트 B는 호스트 A의 연결 확립 요청을 허가한다는 응답(ACK, x+1)을 보낸다. 동시에 호스트 B도 호스트 A에게 데이터를 전송하기 위해 연결 확립 요청(SYN, y)을 보낸다.
- 호스트 A 연결 확립 응답 (ACK)호스트 A는 호스트 B의 연결 확립 요청을 허가한다는 응답(ACK, y+1)을 보낸다.
연결 종료: 4-way handshake
연결 종료 과정은 4-way handshake로 이루어진다. 연결 확립 과정과 다른 이유는 한 호스트가 데이터 전송을 완료했더라도 다른 호스트는 아직 데이터 전송 작업이 진행중일 수 있기 때문이다. 그래서 FIN에 대한 ACK만 보내고, 남은 작업을 처리한 이후에 FIN 요청을 보낸다. 한 쪽은 데이터 송신을 중단하고 다른 쪽은 데이터 수신을 이어나가면서 연결의 일부를 종료하는 것을 Half-Close 기법이라고 한다.
- 호스트 A 연결 종료 요청(FIN+ACK) 호스트 A는 호스트 B에게 연결 종료 요청(FIN, x)을 보낸다.
- 호스트 B 연결 종료 응답(ACK) 및 남은 작업 마무리호스트 B는 호스트 A의 연결 종료 요청을 허가한다는 응답(ACK, x+1)을 보낸다. 이후 호스트 B의 남은 데이터 전송 작업을 처리한다.
- 호스트 B 연결 종료 요청(FIN) 호스트 B는 호스트 A에게 연결 종료 요청(FIN, y)을 보낸다.
- 호스트 A 연결 종료 응답(ACK)호스트 A는 호스트 B의 연결 종료 요청을 허가한다는 응답(ACK, y+1)을 보낸다.
UDP(User Datagram Protocal)
UDP는 효율성이 우선인 비연결형(connectionless) 프로토콜이다. 데이터그램의 순서를 보장하지 않고, 데이터 그램이 손상될 수 있으며 손상되더라도 재전송하지 않는다. 대신 연결 설정/유지/종료에 대한 오버헤드가 없다. 데이터의 신뢰성보다 데이터 전송의 속도가 중요할 때 해당 프로토콜을 사용한다. 음성 및 비디오 스트리밍에 적합하며 멀티 캐스트 및 브로드 캐스트를 지원한다.
UDP 세그먼트 헤더(8바이트)는 TCP 세그먼트 헤더(20바이트)보다 단순하다.
1. source port, destination port: 출발지와 목적지의 포트 번호다.
2. total length: 데이터그램의 전체 길이를 의미한다.
3. checksum: 데이터의 오류를 검출한다.
UDP에선 오류 복구 기능을 제공하지 않지만, 체크섬을 활용한 오류 검출 기능은 제공한다. 송신자는 데이터를 생성할 때 세그먼트 값을 기반으로 체크섬을 계산하여 전송한다. 수신자는 데이터를 받을 때 체크섬을 다시 계산하여 비교하고 일치하지 않는 경우 오류로 간주하여 세그먼트를 폐기한다.
체크섬 계산법은 출발지 포트 번호, 목적지 포트 번호, 데이터 길이, 체크섬 필드 등이 포함된 데이터를 16비트 단위로 쪼개어 더한다. 만약 합했을 때 오버플로우가 발생하면 carry-out된 결과를 다시 더하고, 합산된 값의 1의 보수를 구하면 체크섬이 된다.
메시지 전송 방식 (유니캐스트, 브로드캐스트, 멀티캐스트)
UDP를 기반으로 브로드캐스트, 멀티캐스트 등 다자간 통신을 구현할 수 있다.
- 유니 캐스트(unicast): 고유 주소로 식별된 단일 호스트에게 1:1(one to one) 로 메시지를 전송하는 방식이다. 프레임을 받은 PC는 목적지의 MAC 주소 와 자신의 MAC 주소가 다르면 해당 프레임을 폐기한다.
- 브로드 캐스트(broadcast): LAN에 연결된 모든 호스트에게 1:N(one to all)로 메시지를 전송하는 방식이다. 각 호스트는 메시지를 무조건 수신하고 목적지 IP 주소와 자신의 IP 주소를 비교한 뒤 메시지를 재송신하거나 폐기해야하기 때문에 CPU에 부하가 발생할 수 있다.
- 멀티 캐스트(multicast): 특정 그룹의 호스트에 1:N(one to several)로 메시지를 전송하는 방식이다. 다자간 통신 상황에서 유니캐스트처럼 동일한 패킷을 반복해서 보낼 필요도 없고, 브로드캐스트와 달리 모든 호스트의 CPU를 사용하지 않기 때문에 효율적이다.