이 글은 부산대학교 탁성우 교수님의 컴퓨터 네트워크 강의 자료를 바탕으로 진행됩니다.
TCP
TCP(Transmission Control Protocol)이란, Transport 계층에서 사용되는 통신 규약이다.
보통 하위 계층에서 사용하는 IP Protocol과 묶어서 TCP/IP라고 얘기하곤 한다.
TCP의 특징
- Reliable
- Host와 Host간의 Reliable한 연결을 보장해주는 Protocol이다.
- Reliable 하다는 것은, Retransmission 을 지원함을 의미한다.
Error Control, Flow Control, Congestion Control
을 통해서 Retransmission을 지원할 수 있다.- Congestion Control은 Sender의 입장, Flow Control은 Receiver의 입장에서 Control 하는 것이다.
- Connection-Oriented
- UDP와의 가장 큰 차이로, 연결을 끊지 않는 연결 지향적 Protocol이다.
- 연결을 시작할 때에는 3-Way Handshake 방식을 이용한다.
- 연결을 끊을 때에는 4-Way Handshake 방식을 이용한다.
- Unicast
- 1대1 연결만 지원한다.
- 즉, Group Chat 같은 기능을 구현하려면 모든 참여자와 Connect 되어 있어야 한다.
- Byte Stream의 형태
- Byte의 연속적인 흐름으로 Data를 전달한다.
- Packet Segmentation
- Byte를 모아서 Segmentation하고, TCP Header를 통해 순서를 제어한다. (IP Packet과 동일)
- Adaptive Timeout
- 특정 시간동안 Data 교환이 없으면, 연결을 끊어야 하는데 그 시간을 어떻게 알 수 있을까?
- Adaptive Timeout을 통해 보통은 2시간이 지나면 연결을 끊도록 한다.
- 물론 직접 설정도 가능한 정보이다.
3 Way Handshake
위 사진은, TCP에서 사용되는 3 Way Handshake의 동작 과정이다.
통신을 시작할 때, 통신이 잘 개시되었는지 확인을 하려면 최소 3번이면 충분하다.
- SYN을 통해 통신을 시작하고 싶음을 알린다.
- 이후 Server에서 요청을 수락함을 알리는 ACK과 SYN flag가 설정된 Packet을 전송한다.
- 마지막으로 Client 측에서, 잘 받았음을 알리는 ACK을 전송하며 논리적 연결이 완료된다.
4 Way Handshake
위 사진은, TCP에서 사용되는 4 Way Handshake의 동작 과정이다.
통신을 종료할 때 사용되는 방식인데, 왜 4 Way일까? 아래의 과정을 보자.
- FIN을 통해 통신을 종료하고 싶음을 알린다.
- 일단 Server에서는 FIN을 받았음을 알리는 ACK을 전송한다.
- 하지만, 통신이 아직 종료된 것은 아니다! 종료를 기다리는 과정이 필요하다.
- 이후 통신이 완전히 종료되었다면, 종료를 알리는 FIN을 다시 전송해준다.
- 마지막으로 Client 측에서, 잘 받았음을 알리는 ACK을 전송하며 통신 종료 작업이 완료된다.
TCP Segment Header
- UAPRSF
- URG : Urgent Data
- 빠른 순서로 처리해야할 Data의 공간을 따로 만들어 놓는다.
- 해당 Data는 가능한 빨리 처리한다.
- ACK : Acknowledge
- Reliable Protocol의 핵심인 ACK이다.
- PSH : Push Data
- Buffer에 쌓지 않고 즉시 보내고 올리는 Data임을 알린다.
- RST
- 연결의 종료를 알리는데, 오류에 대한 응답으로 강제 종료를 의미한다.
- SYN
- 3-Way Handshake 방식에서 연결의 시작을 알리는 Flag이다.
- FIN
- 연결의 종료를 알리지만, RST과 다르게 응답을 받고 안전하게 종료한다.
- URG : Urgent Data
- Options
- TCP Header은 기본적으로 20byte이지만, Option이 추가로 40byte까지 붙을 수 있다.
- TCP Header가 20byte가 넘어가는 경우엔, 반드시 Option Field를 Check해야만 한다.
- Kind 0 : Option Field의 끝.
- Kind 1 : No operation. Memory Padding(4byte 배수)을 맞추기 위해 사용한다.
- Kind 2 : MSS, 초기에 SYN과 함께 전송된다.
- 미 지정시 536byte가 기본으로 설정된다.
- Kind 3 : Window scaling option
- 해당 옵션은 SYN과 함께 전송된다.
- TCP에서 Window size는 16bit(65536)지만, 해당 옵션을 통해 Shift가 가능하다.
- Kind 8 : Timestamp, RTT(Round Trip Time)을 계산할 때 용이한 Option이다.
- Kind 4, 5는 SACK(선택 확인 옵션)에 대한 Option이다.
How to be reliable?
Protocol을 Reliable하게 유지하기 위해서는 뭐가 필요할까?
지속적으로 상태를 감시하고 주기적으로 알려야 하기 때문에 Timer 가 필요하다!
- Retransmission Timer
- 송신 측은, 매 Segment마다 해당 Timer를 가동해야 한다.
- 정해진 시간 내에 ACK이 도착하지 않으면? Segment를 재전송한다.
- 해당 시간은 Custom이 가능하다.
- Persistence Timer
- Sliding Window Protocol에 대해서 Window size 결정에 관여하는 Timer이다.
- Zero-Window : Window의 크기가 0인데도 일정시간 이후에 아무런 ACK이 없다면, 수신 측에서 더 이상 Data를 보내지 말라는 의미가 된다.
- 이후 수신 측 상황을 알아보기 위해 1byte짜리 Window Probe Packet 을 전송해본다.
- 또한 Deadlock 상태에 빠졌을 때에도, 해당 Timer가 돌아가 처리를 한다.
- Sliding Window Protocol에 대해서 Window size 결정에 관여하는 Timer이다.
- Time-Waited Timer
- TCP 연결 종료 이후에 해당 기간 동안 잠시 연결을 유지한다.
- 어떠한 Packet이 지연 도착하는 것을 방지한다.
- Keepalive Timer
- Establish 된 연결이 쓸데없이 계속 연결되어있지 않도록 하기 위함이다.
- 보통 2시간 동안 아무런 Packet이 오지 않으면 Keepalive Probe Packet 을 송신한다.
- 75초 간격으로 10번 송신한다.
- 그래도 응답이 없으면, 연결을 끊어버린다.
TCP Retransmission
TCP의 가장 큰 특징은 Segment가 손실되었을 때 Retransmission을 한다는 점이다.
아래의 그림을 통해 Retransmission Scenario를 살펴보자.
이 경우는 기본적인 Retransmission Scenario 이다.
정해진 Timeout 내에 ACK을 받을 수 없는 경우, 이전 ACK에 따라 재전송한다.
- Cumulative ACK
- 이 경우는 ACK에 Loss가 발생하는 경우이다.
- 중간에 ACK에 Loss가 발생했더라도, 마지막으로 받은 ACK이 해당 번호보다 크다면?
- 이전 번호에 해당하는 ACK은 잘 받았다고 인지를 한다.
- Go Back N
- TCP는 또 다른 방안으로 Go Back N을 사용한다.
- 이 경우는 ACK이 아닌 Segment가 Loss가 발생한 경우이다.
- 어떤 Segment가 Loss에 의해 Server에 도착하지 않았다면?
- Server은 이후 들어오는 Segment를 모두 Drop한다.
- Loss가 발생한 Segment에 대한 ACK을 다시 보내 Segment를 받아낸다.
UDP
UDP(User Datagram Packet)이란, TCP와 동일하게 Transport 계층에서 사용되는 통신 규약이다.
UDP의 특징
- Unreliable
- TCP와 다르게 신뢰성을 보장하지 않는다.
- Connectionless
- 연결을 계속 유지해야하는 TCP와는 다르게 연결을 끊으며 사용한다.
- Broadcast
- TCP와 다르게 Unicast가 아닌 Broadcast 방식을 사용할 수 있다.
UDP Segment Header
UDP Header은 TCP와는 다르게 매우 간단한 형태를 갖는다.
당연히 Reliable Protocol이 아닌 UDP에는 많은 정보가 필요없기 때문이다.
그래도 Best-Effort(IP) 와 같이 Checksum은 존재한다.
에러가 있는지 없는지 정도는 검사가 가능하며, 오류가 존재할 시 Drop한다.
TCP / UDP Pseudo Header
서로 너무나도 다른 TCP와 UDP Header에 유일한 공통점이 있었다.
바로 Checksum 부분이다!
Checksum은 잘 알고 있듯이, Error를 검출할 떄 사용하는 값이다.
그럼 TCP와 UDP는 해당 값을 어떻게 사용할까?
바로, Pseudo Header 라는 가짜 Header를 만들어서 사용한다.
- Pseudo Header의 값을 16비트 씩 잘라 모두 더한다.
- TCP/UDP Header + Data의 값을 16비트 씩 잘라 모두 더한다.
- 해당 값이 Checksum과 동일하면, Error가 없는 Segment인 것!
- 기본적으로 초과 값에 대해서는 Wrap-around가 적용된다.
[사진 첨부]
Bonus : TCP/IP Socket
Socket이란 어떤 것을 의미할까?
Socket은 원래 전구를 끼워 전선과 접촉하게끔 하는 연결 기구를 의미한다.
네트워크에서도 마찬가지이다.
socket()
: 새 소켓을 생성한다.bind()
: 생성한 Socket을 서버에 등록한다.listen()
: Client의 SYN Packet을 기다리는 상태이다.accept()
: Client 접속 요청 대기 및 접속 허가 상태이다.read()
/write()
: Data의 송/수신을 담당하는 함수이다.close()
: 연결 종료 시, Client Socket을 소멸시킨다.