[F-Lab 모각코 챌린지 10일차] TCP/IP 트랜스포트 계층

부추·2023년 6월 10일
0

F-Lab 모각코 챌린지

목록 보기
10/66

TIL

  1. TCP/IP 3계층 : 트랜스포트 계층
  2. 포트 번호와 well-known 포트
  3. TCP와 UDP



1. 트랜스포트 계층 : 데이터를 어떤 프로그램에 전달할 것인지?

컴퓨터에서 네트워크를 사용하는 프로세스는 많다. 현재 글을 작성하고 있는 내 컴퓨터만 하더라도 글을 작성하고 전송 버튼을 보낼 크롬, 친구들이나 가족들과 연락을 주고받는 카카오톡, 업무 관련 연락이 이뤄지고 있는 슬랙 등.

TCP/IP 2계층의 인터넷 계층이 역할을 잘 수행해서 데이터가 내 컴퓨터까지 도착했더라도, 컴퓨터의 어떤 프로그램에 도달해야하는지 결정하는 것은 또다른 문제이다. 3계층, 트랜스포트 계층은 데이터를 컴퓨터의 어떤 프로세스에 전달할지 결정하는 역할을 수행한다. 더해서 신뢰성 있는 연결을 보장하기 위한 프로토콜을 제공한다. 대표적으로 TCP, UDP 프로토콜이 있는데 TCP는 데이터의 정확한 전달을, UDP는 데이터의 빠른 전달을 중시한다.



2. 포트 번호 : 프로세스를 구분짓는 16bit 번호

트랜스포트 계층은 4계층에서 받은 데이터를 적절한 크기로 나눈다. 그리고 나눈 데이터에 헤더를 붙여 "세그먼트(segment)"라는 PDU로 만든 후 2계층 인터넷 계층으로 내려보낸다. 세그먼트의 헤더에는 송신측과 수신측의 포트 번호가 포함되어 있다.

앞서 트랜스포트 계층에선 컴퓨터의 어떤 프로세스에 해당 데이터를 전할지 결정한다 했는데, 이때 사용되는 것이 포트 번호이다. 포트 번호란, 실행중인 프로그램(=프로세스)을 구분하여 데이터를 전달하기 위해 할당한 16비트의 값이다. 데이터가 하드웨어-OS를 넘어 실제 프로그램에 넘어가는 단계에서 사용되므로 "운영체제 통신의 종단점"이라고 부르기도 한다. 2^16 = 65536이고, 0번부터 시작하므로 포트 번호는 0~65535의 범위를 가진다.


포트에도 종류가 있다.

1) Well-Known Port(0~1023) : 특정 권한을 가진 서비스/프로토콜이 사용하는 포트

root 권한이 있어야 해당 포트를 이용할 수 있다. 주로 서버 프로그램이 클라이언트의 요청을 대기하기 위해 사용한다. 통신 프로토콜마다 포트 번호가 고정되어 있으며 대표적으로 알려진 웰노운 포트번호는 아래 표와 같다.

포트 번호대응하는 프로토콜
20FTP의 데이터 포트
21FTP의 컨트롤(제어 및 인증) 포트
22SSH (보안 기능이 있는 원격 제어 프로세스)
23Telnet (원격 제어 프로세스)
25SMTP (이메일 전송)
53DNS
80HTTP
110POP3 (이메일 수신)
443HTTPS (암호화된 HTTP)

브라우저로 HTTP 프로토콜을 이용한 웹 통신을 할 때 일반적으로 URL을 이용하는데, 사실 URL 뒤에 ":80"이라는 포트 번호가 생략된 것임을 알아야한다.

2) Registered Port(1024~49151) : 벤더가 할당받아 사용

포트 번호는 IANA라는 단체가 관리하는데, 1024번부터 49151번 포트는 특정 기관이나 사업자들에게 IANA가 할당한 포트번호다. 스프링을 개발하면서 톰캣 서버의 8080번 포트를 본 적이 있을 것이다. 혹은 로컬에서 MySQL 서버를 돌릴 때 기본적으로 3306번 포트를 사용한 적이 있을 것이다.

3) Dynamic Port(49152~65535) : 클라이언트 프로그램이 사용

나머지 포트번호는 클라이언트 프로그램이 자유롭게 사용한다. lsof 명령어로 현재 내 컴퓨터에서 실행중인 크롬의 IP와 포트번호를 확인해보았다.

IP 주소의 : 뒤에 있는 숫자가 포트 번호이다. 출발 포트번호는 65xxx로, 크롬의 프로세스들에 할당된 다이나믹 포트이다. 도착 포트 번호는 443으로 웰노운포트, 그것도 HTTPS 전용임을 알 수 있다. 포트 번호와 IP 주소를 통해 상대방을 구분하고, 상대방 역시 포트 번호와 IP 주소를 통해 내 크롬의 각 프로세스를 구분하고 있을 것이다.

추가로 내 로컬 IP 주소가 192.168.xxx.xxx인 것도 확인해 볼 수 있는데, 이건 사설 IP주소(혹은 프라이빗 IP주소 라고도 부른다)이고 포트포워딩이나 NAT/NAPT 등을 통해 인터넷에서 사용할 수 있는 공인 IP주소(퍼블릭 IP주소)로 바뀐다. 그것은 인터넷 계층에서 자세히 설명하겠다!




TCP와 UDP가 무엇인지, 차이에 대한 설명은 블로그 글에 자세히 정리해 놓았다. 여기서는 가볍게 훑는 정도로 한 번만 더 정리해보자.

3. TCP : 정확한 데이터 교환 중시

정확한 데이터의 교환이 중요한 HTTP 통신이나 SMTP 통신에서 사용하는 프로토콜이다. 다음과 같은 특징이 있다.

  • 연결형 프로토콜이다. 서버가 열려있어야 하고, 통신 참여 주체가 서로의 연결을 확인해야만 데이터의 교환이 이뤄진다.
  • 양방향 통신이다. 데이터를 주거나 받는 쪽이 꼭 정해진 것이 아니다.
  • 전이중(Full-duplex), 점대점(Point-to-Point) 통신으로, 브로드 캐스팅이 불가하다.
  • 가상 회선 방식을 사용하여, 사전의 hand-shaking 과정을 통해 연결된 경로를 통해 통신이 이뤄진다.
  • 각 패킷에 대한 수신 확인 과정을 거쳐, 누락된 패킷에 대한 재전송이 일어난다.
  • ECE, CWR, Window size 등의 헤더 정보를 통해 흐름 및 혼잡 제어가 가능하다.

상기한 특징은 모두 신뢰성 있는 연결을 보장하기 위한 특징이다. 통신 경로를 확보하여 데이터 유실 가능성을 최소화하고, 유실되었을 때 재전송을 통해 무결성을 보장한다. 또한 TCP는 통신을 시작하기 전에 주고받을 데이터의 최대 크기인 MSS(Maximum Segment Size)를 정하기도 한다. TCP는 어떻게 말하면 정확한 데이터 전달 집착광공인 것이다.


# TCP 헤더 구성

  • Source/Destination Port : 출발지와 목적지 컴퓨터의 포트 번호로, 트랜스포트 계층에서 가장 중요한 정보이다.
  • Sequence Number : 출발지 기준 패킷의 시퀀스 번호. 바이트 수 기준으로 증가한다. 보내는 쪽에서 이 값이 N이라면 받는 쪽에서 Acknowledgement Number을 N+{받은 데이터 byte}로 설정해서 다시 보낸다. 이를 통해 보내는 쪽은 N번 패킷이 상대방에게 잘 도착했다는 수신확인을 할 수 있다.
  • Acknowledgement Number : 특정 Sequence Number를 가진 패킷을 잘 받았다는 수신확인을 위해 사용하는 필드이다. 역시 바이트 기준으로 증가하며, 상대방으로부터 받아야 할 다음 Sequence Number를 담고 있다. 송신한 패킷에 대해 제대로된 수신확인 패킷이 오지 않으면 재전송이 일어난다.
  • Window Size : TCP 흐름 제어에 필요한 항목. 수신 측에서 버퍼의 남은 값을 설정해서 수신확인 패킷을 반환하면 송신측은 이에 맞춰 다음 데이터를 보낸다.
  • Control Bits : 현재 통신 상태와 관련된 플래그를 설정하는 비트들.
    • CWR / ECE : 수신 측에서 통신 경로가 혼잡하다는 것을 알리기 위해 사용. 통신 속도를 늦춰달라는 요청으로 사용된다.
    • SYN : 연결 시작을 위해 사용되는 flag bit. 양 쪽이 보낸 최초의 패킷에만 이 값이 1로 설정된다.
    • ACK : 패킷을 받는 쪽에서 패킷이 잘 도착했음을 알리는 수신 확인에 사용하는 flag bit.
    • FIN : 연결 종료를 위해 사용하는 flag bit.

3-way handshaking

통신 시작 전, 서버-클라이언트 간 연결을 확보하고 가상 회선을 구축하기 위해 3-way handshaking 과정을 거친다.

  1. A에서 특정 Sequence Number를 가진 패킷을 SYN 비트를 1로 설정하여 B로 전송한다. 해당 패킷을 보낸 A는 이후 SYN_SENT 상태가 된다.
  2. 연결 시작 패킷(SYN=1)을 받은 B는 SYN_RCV 상태가 된다. 해당 패킷을 받았다는 수신 확인을 위해, 그리고 본인 역시 통신을 시작할 준비가 됐음을 알리기 위해 패킷의 SYN과 ACK 비트를 1로 설정한다. 그리고 (A가 설정한 Sequence Number + 1) 값을 Acknowledgement Number로 설정하여 다음 패킷을 보내라는 수신확인을 한다.
  3. B에게 SYN 플래그를 되받은 A는 ESTABLISHED 상태가 되어 본격적으로 통신을 한다. 데이터를 보내기 전, B가 보낸 SYN 패킷을 수신했다는 신호로 (B가 설정한 Sequence Number + 1) 값을 Acknowledgement Number로 설정한다. 그리고 B가 보낸 Acknowledgement Number에 맞춰 Sequence Number을 설정한 후 해당 번호에 맞는 패킷을 전송한다.

이 이후 A와 B는 본격적으로 양방향 데이터를 송수신할 수 있게 된다. 이 때 서로간에 전송되는 ACK 비트는 모두 1이된다.

참고로 A와 B가 handshaking 과정에서 보내는 세그먼트의 시퀀스 번호는 임의의 숫자이다. 이는 패킷 번호를 유추해서 malfunction 데이터를 보내는 해킹을 방지하고, 포트가 재사용됐을 때 패킷 데이터의 혼선을 막기 위함이다.

# TCP 통신 과정

전반적으로 패킷 보내기 -> 수신 확인 -> 다음 패킷 보내기 과정으로 이뤄진다. 편의를 위해 Sequence nubmer을 seq로, Acknowledgement number을 ack로 표현한다.

  1. 클라이언트가 644~1181의 seq를 가진 패킷 데이터를 서버로 보낸다.
  2. 서버는 해당 패킷 데이터를 모두 처리하고 ack 번호를 1182로 설정한다.(클라이언트가 보낼 다음 패킷의 seq번호) 그리고 4473~6134의 seq를 가진 패킷 데이터를 클라이언트로 보낸다.
  3. 클라이언트는 해당 패킷 데이터를 모두 처리하고 ack번호를 6135로 설정한다.(서버가 보낼 다음 패킷의 seq번호) 그리고 서버가 보낸 수신 확인 패킷의 ack번호인 1182부터 1757번까지의 seq 패킷 데이터를 서버로 보낸다.
  4. 서버는 클라이언트가 보낸 1182~1757 데이터를 처리 후 1758번 패킷을 보내라는 신호로 ack 번호를 1758로 설정한다. 그리고 클라이언트로부터 받은 ack번호인 6135의 seq데이터를 보낸다.

여러가지 이유로 패킷이 수신 측에 제대로 도착하지 않거나 전송 과정 중 패킷이 손상될 수도 있다. 이 경우 수신 측에선 해당 패킷에 맞는 ack 패킷을 보내지 않는다. 일정한 시간이 지나도 전송한 패킷에 대한 ack 패킷이 도착하지 않으면 송신 측은 같은 패킷을 한 번 더 보낸다.


패킷을 MSS 단위로 보낸 뒤 하나하나 수신확인을 하기도 하지만, 보통은 송신 측에서 한 번에 여러 개의 세그먼트들을 보내고, 보낸 세그먼트들 각각에 대한 수신확인 세그먼트들 역시 여러 개를 받는다.

한 번에 어느 정도의 세그먼트를 보낼지는 수신측이 보낸 세그먼트 헤더의 Window Size에 의해 결정된다. Window Size는 수신 측 버퍼의 남은 공간으로, 남은 공간이 많으면 더 많은 패킷을 한꺼번에 보내고 반대의 경우엔 더 적게 보내는 식으로 통신 속도를 조절할 수 있다.


# 4-way handshaking

양방향 통신이 끝나고, TCP 연결이 해제되는 과정은 4-way handshaking을 통해 이뤄진다. TCP 연결 해제에서 중요한 점은 연결이 해제되기 전 미처 도착하지 못한 패킷에 대비하는 것이다. 전송되어야 할 패킷이 남은 상황에서 한 쪽에서 일방적으로 연결을 끊어버리면, 상대방은 자신이 보낸 패킷이 잘 수신되었는지 확인할 수 없다. 이 경우를 대비하기 위해 TCP는 wait 상태를 둔 4-way handshaking을 실행한다.

A-B가 연결된 상황에서, A가 연결을 끊으려고 할 때 어떤 과정이 일어나는지 살펴보자.

  1. A는 FIN flag를 1로 설정하여 세그먼트를 보낸다. 이후 A는 FIN_WAIT 상태에 들어간다.
  2. FIN 플래그를 받은 B는 ACK 플래그가 1인 세그먼트를 보낸다. B는 CLOSE_WAIT 상태에 들어간다.
    • 만약 B가 아직 보내지 못한 패킷이 있으면 계속 보낸다. FIN_WAIT 상태에 있는 A는 B가 보내는 데이터를 받을 수만 있다.
    • 위 그림에서 B가 FIN 플래그를 받은 뒤 5바이트의 데이터를 추가로 보내고, A가 수신확인 세그먼트를 반환하는 과정을 확인하자.
  3. 남은 데이터를 모두 보낸 B가 FIN flag를 1로 설정하여 세그먼트를 보낸다.
  4. 이를 받은 A는 마지막으로 ACK flag를 1로 설정한 세그먼트를 보낸다. 그리고 TIME_WAIT 상태로 2MSL(Maximum Segment Lifetime, 세그먼트가 네트워크 선상에 존재할 수 있는 최대 시간) 동안 기다린다. 이는 연결이 종료된 후, 혹시 모를 회선 상에 존재하는 지연 패킷을 위함이다.

보낸 패킷의 수신 확인을 하고, 순서대로 보내고, 재전송을 하고, 네트워크 혼잡이나 수신측의 사정에 따라 전송 속도를 조절한다. 이는 모두 통신을 통해 정확한 데이터를 보내고자 하는 TCP가 사용하는 여러가지 방법들인 것 같다.



4. UDP : 빠른 데이터 전송 중시

UDP는 TCP와 비교하면 굉장히 간단한 통신과 헤더 구조를 이루고 있다. 정확한 데이터 교환보단 빠른 데이터 전송이 필요한 네트워크에서 선호된다.

  • 비연결형 프로토콜로, TCP와 같은 사전 연결 과정이 필요하지 않고 송신 측에서 데이터를 일방적으로 보낼 뿐이다.
  • '데이터그램' 이라는 단위로 데이터를 분할해 보내는데, 헤더에는 트랜스포트 계층에서 필요한 포트 번호 외에 오류 검출을 위한 체크섬만이 존재한다.
  • 단방향 통신이다. 송신 측에서 데이터를 쏴줄 뿐이므로 멀티/브로드 캐스팅도 가능하다.
  • 재전송 과정이 없다. 네트워크 혼잡이나 수신측의 과부하에 따른 흐름/혼잡 제어 기능도 없다.

오로지 데이터의 빠른 전송만을 고려한 프로토콜이라고 할 수 있다.

# UDP 헤더 구성

온갖 컨트롤 비트, seq/ack 번호, window size 등이 들어있는 TCP 헤더와는 다르게 간단한 구조다.

  • Soucre / Destination Port Number : 출발지와 도착지의 포트 번호. 통신 프로세스를 구분하기 위함이다.
  • Total Length : 데이터그램이 가진 전체 크기
  • Checksum : 해당 데이터그램의 오류를 검출하기 위해서 사용된다. 오류가 검출되면 데이터그램은 파기된다.

# UDP 통신 과정

handshaking도, 수신 확인도, 재전송도, 혼잡 및 흐름 제어도 없다. 사용자 요청에 따라서 응답 데이터를 데이터그램 단위로 우다다다 보낼 뿐이다.



간단하게 TCP와 UDP의 차이에 대해 표로 정리해보았다.



REFERENCE

https://eunhyee.tistory.com/246

profile
부추튀김인지 부추전일지 모를 정도로 빠싹한 부추전을 먹을래

0개의 댓글