이 글은 부산대학교 탁성우 교수님의 컴퓨터 네트워크 강의 자료를 바탕으로 진행됩니다.

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

스크린샷 2022-10-12 오전 8 48 37

위 사진은, TCP에서 사용되는 3 Way Handshake의 동작 과정이다.
통신을 시작할 때, 통신이 잘 개시되었는지 확인을 하려면 최소 3번이면 충분하다.

  • SYN을 통해 통신을 시작하고 싶음을 알린다.
  • 이후 Server에서 요청을 수락함을 알리는 ACK과 SYN flag가 설정된 Packet을 전송한다.
  • 마지막으로 Client 측에서, 잘 받았음을 알리는 ACK을 전송하며 논리적 연결이 완료된다.

4 Way Handshake

스크린샷 2022-10-12 오전 8 49 38

위 사진은, TCP에서 사용되는 4 Way Handshake의 동작 과정이다.
통신을 종료할 때 사용되는 방식인데, 왜 4 Way일까? 아래의 과정을 보자.

  • FIN을 통해 통신을 종료하고 싶음을 알린다.
  • 일단 Server에서는 FIN을 받았음을 알리는 ACK을 전송한다.
  • 하지만, 통신이 아직 종료된 것은 아니다! 종료를 기다리는 과정이 필요하다.
    • 이후 통신이 완전히 종료되었다면, 종료를 알리는 FIN을 다시 전송해준다.
  • 마지막으로 Client 측에서, 잘 받았음을 알리는 ACK을 전송하며 통신 종료 작업이 완료된다.

TCP Segment Header

TCP헤더

  • UAPRSF
    • URG : Urgent Data
      • 빠른 순서로 처리해야할 Data의 공간을 따로 만들어 놓는다.
      • 해당 Data는 가능한 빨리 처리한다.
    • ACK : Acknowledge
      • Reliable Protocol의 핵심인 ACK이다.
    • PSH : Push Data
      • Buffer에 쌓지 않고 즉시 보내고 올리는 Data임을 알린다.
    • RST
      • 연결의 종료를 알리는데, 오류에 대한 응답으로 강제 종료를 의미한다.
    • SYN
      • 3-Way Handshake 방식에서 연결의 시작을 알리는 Flag이다.
    • FIN
      • 연결의 종료를 알리지만, RST과 다르게 응답을 받고 안전하게 종료한다.
  • 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가 돌아가 처리를 한다.
  • Time-Waited Timer
    • TCP 연결 종료 이후에 해당 기간 동안 잠시 연결을 유지한다.
    • 어떠한 Packet이 지연 도착하는 것을 방지한다.
  • Keepalive Timer
    • Establish 된 연결이 쓸데없이 계속 연결되어있지 않도록 하기 위함이다.
    • 보통 2시간 동안 아무런 Packet이 오지 않으면 Keepalive Probe Packet 을 송신한다.
      • 75초 간격으로 10번 송신한다.
    • 그래도 응답이 없으면, 연결을 끊어버린다.

TCP Retransmission

TCP의 가장 큰 특징은 Segment가 손실되었을 때 Retransmission을 한다는 점이다.
아래의 그림을 통해 Retransmission Scenario를 살펴보자.

image
이 경우는 기본적인 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 헤더

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를 만들어서 사용한다.

  1. Pseudo Header의 값을 16비트 씩 잘라 모두 더한다.
  2. TCP/UDP Header + Data의 값을 16비트 씩 잘라 모두 더한다.
  3. 해당 값이 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을 소멸시킨다.