이번 포스팅에서는 전송계층에서 사용하는 TCP와 UDP에 대해서 알아볼 것입니다.
목차는 다음과 같고 중간중간 '더보기'를 통해 필요한 개념 정리를 했습니다.
- 전송계층이 무엇이고 존재하지 않으면 어떤 문제가 있는지 알아봅니다.
- TCP와 TCP 서버의 특징, TCP 헤더의 구조
- UDP와 UDP 서버의 특징, UDP 헤더의 구조
전송 계층(TransportLayer)은 무엇이고 왜 존재할까요?
전송 계층은 End Point 간 신뢰성있는 데이터 전송을 담당하는 계층입니다.
전송 계층을 이용함으로써, 포트 번호에 해당하는 프로세스에 데이터를 전달(전송)하는데
데이터를 순차적이고 안정적으로 전달(신뢰성)할 수 있습니다.
1. 데이터를 순차적으로 전송하는 것을 원활히 해줍니다.
만약 순차 전송이 원활히 되지 않으면 데이터가 패킷 1,2,3으로 쪼개져 전송됐을 때, 수신측에서는 3,2,1로 데이터를 재결합하게 됩니다.
2. 흐름을 제어해줍니다.(흐름 문제 해결)
만약 흐름을 제어해주지 않는다면, 송수신자 간 데이터 처리 속도에 차이가 있을 때 문제가 발생합니다.
예를 들어, 송신자는 1초에 1개씩 보내지만, 수신자는 3초에 1개씩 처리할 수 있다면 어느 순간 수신자가 처리할 수 있는 데이터양을 초과하여 그 이후로 전송된 데이터가 누락될 수 있습니다.
- 수신자가 패킷을 지나치게 많이 받지 않도록 조절합니다.
- 기본 개념은 수신자가 송신자에게 현재 자신의 상태를 feedback 함으로써 조절합니다.
3. 혼잡도를 제어해줍니다. (혼잡 문제 해결)
네트워크의 데이터 처리 속도에 상관없이 계속해서 송신자가 데이터를 보내게 되면 혼잡도는 계속 증가하여 문제가 발생합니다.
만약 한 라우터에 데이터가 몰릴 경우, 자신에게 온 데이터를 모두 처리할 수 없게 됩니다.
이때 수신자의 응답에 따라 송신자는 다시 재전송을 하게되고 결국 혼잡만 가중시켜 오버플로우나 데이터 손실을 발생시킵니다.
- 송신측에서 보내는 데이터의 전송속도를 강제로 줄여
송신측의 데이터 전달과 네트워크의 데이터 처리 속도 차이를 해결합니다. - 혼잡제어는 호스트와 라우터를포함한 보다 넓은 관점에서 전송 문제를 다룹니다.
결과적으로, 전송 계층이 없다면 데이터의 손실이 발생할 수 있다는 큰 문제를 가지게 됩니다.
그래서 전송 계층에서 프로토콜(규약)을 세우는데, TCP라는 규약을 세웁니다.
TCP (Transmisstion Control Protocol)
- 신뢰성 있는 데이터 통신을 가능하게 해주는 프로토콜
- Connection 연결 (3 way-handshake) : 양방향 통신 -> 시간손실 발생
- 데이터의 순차 전송을 보장
- 패킷을 조금만 손실해도 재전송 요청 -> 시간손실 발생
- 흐름 제어 (Flow Control)
- 혼잡 제어 (Congestion Control)
- 오류 감지 (Error Detection)
결국 TCP는 장비들 간의 통신 과정에서 정보를 안정적으로, 순서대로, 에러 없이 교환하는 것에 목적을 둔 프로토콜입니다.
TCP는 세션 계층으로부터 받은 데이터를 더 작은 단위로 분할합니다.
그리고 분활된 데이터에 TCP Header를 붙이게 됩니다. 이것을 Segment라고 부릅니다.
TCP 서버의 특징
- 서버 소켓은 연결만을 담당합니다.
- 연결 과정에서 반환된 클라이언트 소켓은 데이터의 송수신에 사용됩니다.
- 통신 방식은 1대1로 이루어집니다.
- 스트림 전송으로 전송 데이터의 크기가 무제한입니다.
- 패킷에 대한 응답을 해야해 성능이 낮습니다. (시간 지연, CPU 소모)
- 그래서 Streaming 서비스에 불리합니다.
▼간단히 TCP 헤더 살펴보기▼
TCP는 전송의 신뢰성과 흐름 제어, 혼잡 제어 등의 역할을 맡고 있는 프로토콜이기 때문에,
TCP 헤더에도 이러한 기능을 하기 위한 여러 값들이 담겨있습니다.
TCP의 헤더
- Source port & Destination Port (16bits) : Segment의 출발지와 목적지를 포트 번호로 나타내는 필드입니다. (위 전송 계층의 정의에서 "포트 번호에 해당하는 프로세스에게 데이터를 전송한다"고 언급했었습니다!)
- 출발지와 목적지 주소를 판별하는데에는 IP주소도 필요합니다. (이는 네트워크 계층에서 IP주소의 헤더에 담깁니다.)
- Sequence Number (32bits) : 전송하는 데이터의 순서를 의미합니다. 최대 4,294,967,296까지의 수를 담기 때문에 쉽게 중복되지 않습니다. => 순차 전송 보장
- 송신자가 최초로 데이터를 전송할 때는 이 번호를 랜덤한 수로 초기화
- 이후 자신이 보낼 데이터의 1 bytes당 시퀀스 번호를 1씩 증가시키며 데이터의 순서를 표현하다 4,294,967,296를 넘어갈 경우 다시 0부터 시작
- Acknowledgment number (32bits) : 수신자가 예상하는 다음 시퀀스 번호 (시퀀스 번호는 1bytes당 1씩 증가)
- Data Offset (16bits) : TCP 헤더의 시작부터 데이터 이전까지의 길이 (32-bit 단어로 표시)
- TCP Segment의 시작부터 실제 데이터까지의 Offset
- Reserved (3bits) : 미래를 위해 예약된 필드 (0 으로 채워져야 합니다.)
- Flags (16bits) : 현재 Segment의 속성을 나타내는 필드
- ACK : Segment를 받고 응답할 때 설정하는 필드
- 송신자가 보낸 초기 SYN 패킷 이후의 모든 패킷에는 이 플래그가 설정되어 있어야 합니다.
- SYN : Connection하기 위해 설정하는 bit. 각 endpoint에서 보낸 첫 번째 패킷에만 이 플래그가 설정되어야 합니다.
- FIN : 송신자가 마지막 패킷에 설정하는 bit로, Connection을 끊어도 됨을 알려줍니다.
- ACK : Segment를 받고 응답할 때 설정하는 필드
- Window Size (32bits) : 한 번에 전송할 수 있는 데이터 양을 의미하는 값을 담는 필드
- Checksum (16bits) : 데이터 송신 중 발생할 수 있는 오류를 검출하기 위한 값을 담는 필드 (데이터 변조 여부 체크) => 에러 검출
- Urgent pointer (32bits) : Flags 필드 중 URG 플래그가 1이라면, 이 포인터가 가리키고 있는 데이터를 우선 처리합니다. (즉, 어디서부터 긴급 데이터인지 알려주는 offset)
- Options (가변적) : TCP 기능 확장 시 사용하는 필드들
구체적인 TCP의 구조는 해당 글을 참고하면 좋을 것 같습니다.
▼3 way-handshake & 4 way-handshake 살펴보기▼
3 way-handshake (Connection Open)
1. Client는 Server에 접속을 요청하는 SYN 패킷을 보냅니다.
2. Server는 SYN 요청을 받고, 요청을 수락한다는 ACK와 SYN flag를 설정하여 패킷을 보냅니다.
3. Client는 SYN 요청을 받고 ACK flag를 설정하여 응답합니다.
=> 연결 Connected!
4 way-handshake (Connection Close)
1. Client가 데이터를 전부 송신했다면 연결을 종료하기 위해 FIN 플래그를 1로 설정하고 송신합니다.
이때 Client는 FIN-WAIT 상태가 됩니다.
2. Server가 FIN 패킷을 받으면, 잘 받았다는 확인 메시지로 ACK를 1로 설정하고 송신합니다.
이때 Server는 자신의 App에게 종료를 알리고, 통신이 끝날 때까지 CLOST-WAIT 상태로 기다립니다.
3. Server에서 남은 패킷을 송신합니다.
Client의 상태가 FIN-WAIT으로 Server의 FIN 패킷을 기다립니다.
4. Server가 전부 송신했고 연결을 종료할 준비가 다 됐으면, 이를 알리기 위해 Client에게 FIN을 1로 설정하고 송신합니다.
이때 Server 상태는 LAST-ACK 상태가 되고, FIN을 송신합니다.
5. Client가 잘 받았다는 확인 메시지로 ACK를 1로 설정하고 송신합니다.
Client의 ACK를 받으면 Server는 CLOSED 상태로 변경합니다.
Client의 상태가 FIN-WAIT에서 TIME-WAIT으로 변경되고, 일정 시간 후 CLOSED됩니다.
* Closed가 아닌 TIME-WAIT으로 변경하고 일정시간 (default:240초) 기다리는 이유는?
Server에서 FIN 패킷을 보내기 전에 송신한 남은 패킷들이 Routing 지연이나 패킷 유실로 인한 재전송 등으로 FIN 패킷보다 늦게 도착한 경우 가 있을 수 있는데,
Client가 서버로부터 FIN 패킷을 받고 바로 CLOSED 상태로 전환한다면 해당 데이터는 유실되는 문제가 발생합니다.
그래서 이러한 잉여 패킷들을 기다리기 위해 세션을 열어놓는 상태(TIME-WAIT 상태로) 일정 시간 세션을 열어놓습니다.
메일, FTP(File Transfer Protocol), Web Browsing과 같이 데이터가 손실되지 않는 것이 매우 중요한 환경이라면 TCP를 사용하는 것이 좋지만,
라이브 스트리밍처럼 약간의 데이터 손실이 문제가 되지 않는 곳에서 TCP를 사용하여 통신하는 것은 생각보다 비효율적일 것 같습니다.
그래서 등장한 것이 UDP(User Datagram Protocol) 입니다.
UDP(User Datagram Protocol)
- TCP보다 신뢰성이 떨어지지만 전송속도가 일반적으로 빠른 프로토콜 (순차 전송X, 흐름 제어X, 혼잡 제어X)
- 비교적 데이터의 신뢰성이 중요하지 않을 때 사용 ex) 영상 스트리밍
- Connectionless (3-way handshake X) : 단방향 통신 => 연결 설정/해제 과정이 존재하지 않습니다.
- 비연결형 서비스로 데이터 그램 방식을 제공합니다.
- Error Detection (Checksum을 통해 에러 검출)
- 실시간 전송에 유리한 만큼, 신뢰성보다는 속도가 중요시되는 네트워크에서 사용됩니다.
- TCP에 비해 상대적으로 단순한 헤더 구조를 가지기 때문에 오버헤드가 적습니다.
TCP는 데이터를 분할하는 것과 달리,
UDP는 데이터를 쪼개지 않고 데이터에 UDP Header를 붙여 User Datagram을 완성합니다.
UDP는 데이터를 작은 크기로 분할하지 않기 때문에 필요하다면, 데이터를 분할시키고 전송 계층으로 넘겨줘야한다고 합니다.
▼간단히 UDP 헤더 살펴보기▼
UDP의 헤더
- Source port & Destination Port (16bits) : Segment의 출발지와 목적지를 포트 번호로 나타내는 필드
- Length (16bits) : 헤더와 데이터의 전체 길이(bytes)를 나타내는 필드
- Checksum (16bits) : 데이터 송신 중 발생할 수 있는 오류를 검출하기 위한 값을 담는 필드 (데이터 변조 여부 체크) => 에러 검출
- IPv4에서는 선택, IPv6에서는 의무사항입니다. 만약 사용하지 않는다면 0으로 채워서 전송합니다.
UDP 단점
- 전송 도중 데이터가 유실되더라도 재전송 하지 않습니다.
- 송신자가 수신자에게 정보가 잘, 순차적으로 전달되었는지 알 수 없습니다.
- 신뢰성이 낮습니다.
UDP 서버의 특징
- 연결 자체가 없으므로 클라이언트 소켓과 서버 소켓의 구분이 없습니다.
- 소켓 대신 IP를 기반으로 데이터를 전송합니다.
- 통신 방식은 1대1, 1대N, N대M 등으로 가능합니다.
- 데이터 그램 단위로 전송되는데, 65536 Bytes 크기를 초과하면 잘라서 보냅니다.
지속적으로 업데이트할 예정입니다.
피드백과 댓글은 환영입니다 :^)
'Computer Science' 카테고리의 다른 글
[네트워크] 프로토콜과 OSI 계층 (0) | 2022.04.25 |
---|---|
멀티 프로세스와 멀티 스레드 (feat. 아파치와 톰캣) (0) | 2022.04.18 |
프로세스(Process)와 스레드(Thread) (0) | 2022.03.14 |
링킹 (Dynamic Linking vs Static Linking) (2) | 2022.02.17 |