- TCP/IP 3계층 : 트랜스포트 계층
- 포트 번호와 well-known 포트
- TCP와 UDP
컴퓨터에서 네트워크를 사용하는 프로세스는 많다. 현재 글을 작성하고 있는 내 컴퓨터만 하더라도 글을 작성하고 전송 버튼을 보낼 크롬, 친구들이나 가족들과 연락을 주고받는 카카오톡, 업무 관련 연락이 이뤄지고 있는 슬랙 등.
TCP/IP 2계층의 인터넷 계층이 역할을 잘 수행해서 데이터가 내 컴퓨터까지 도착했더라도, 컴퓨터의 어떤 프로그램에 도달해야하는지 결정하는 것은 또다른 문제이다. 3계층, 트랜스포트 계층은 데이터를 컴퓨터의 어떤 프로세스에 전달할지 결정하는 역할을 수행한다. 더해서 신뢰성 있는 연결을 보장하기 위한 프로토콜을 제공한다. 대표적으로 TCP, UDP 프로토콜이 있는데 TCP는 데이터의 정확한 전달을, UDP는 데이터의 빠른 전달을 중시한다.
트랜스포트 계층은 4계층에서 받은 데이터를 적절한 크기로 나눈다. 그리고 나눈 데이터에 헤더를 붙여 "세그먼트(segment)"라는 PDU로 만든 후 2계층 인터넷 계층으로 내려보낸다. 세그먼트의 헤더에는 송신측과 수신측의 포트 번호가 포함되어 있다.
앞서 트랜스포트 계층에선 컴퓨터의 어떤 프로세스에 해당 데이터를 전할지 결정한다 했는데, 이때 사용되는 것이 포트 번호이다. 포트 번호란, 실행중인 프로그램(=프로세스)을 구분하여 데이터를 전달하기 위해 할당한 16비트의 값이다. 데이터가 하드웨어-OS를 넘어 실제 프로그램에 넘어가는 단계에서 사용되므로 "운영체제 통신의 종단점"이라고 부르기도 한다. 2^16 = 65536이고, 0번부터 시작하므로 포트 번호는 0~65535의 범위를 가진다.
root 권한이 있어야 해당 포트를 이용할 수 있다. 주로 서버 프로그램이 클라이언트의 요청을 대기하기 위해 사용한다. 통신 프로토콜마다 포트 번호가 고정되어 있으며 대표적으로 알려진 웰노운 포트번호는 아래 표와 같다.
포트 번호 | 대응하는 프로토콜 |
---|---|
20 | FTP의 데이터 포트 |
21 | FTP의 컨트롤(제어 및 인증) 포트 |
22 | SSH (보안 기능이 있는 원격 제어 프로세스) |
23 | Telnet (원격 제어 프로세스) |
25 | SMTP (이메일 전송) |
53 | DNS |
80 | HTTP |
110 | POP3 (이메일 수신) |
443 | HTTPS (암호화된 HTTP) |
브라우저로 HTTP 프로토콜을 이용한 웹 통신을 할 때 일반적으로 URL을 이용하는데, 사실 URL 뒤에 ":80"이라는 포트 번호가 생략된 것임을 알아야한다.
포트 번호는 IANA라는 단체가 관리하는데, 1024번부터 49151번 포트는 특정 기관이나 사업자들에게 IANA가 할당한 포트번호다. 스프링을 개발하면서 톰캣 서버의 8080번 포트를 본 적이 있을 것이다. 혹은 로컬에서 MySQL 서버를 돌릴 때 기본적으로 3306번 포트를 사용한 적이 있을 것이다.
나머지 포트번호는 클라이언트 프로그램이 자유롭게 사용한다. lsof 명령어로 현재 내 컴퓨터에서 실행중인 크롬의 IP와 포트번호를 확인해보았다.
IP 주소의 : 뒤에 있는 숫자가 포트 번호이다. 출발 포트번호는 65xxx로, 크롬의 프로세스들에 할당된 다이나믹 포트이다. 도착 포트 번호는 443으로 웰노운포트, 그것도 HTTPS 전용임을 알 수 있다. 포트 번호와 IP 주소를 통해 상대방을 구분하고, 상대방 역시 포트 번호와 IP 주소를 통해 내 크롬의 각 프로세스를 구분하고 있을 것이다.
추가로 내 로컬 IP 주소가 192.168.xxx.xxx인 것도 확인해 볼 수 있는데, 이건 사설 IP주소(혹은 프라이빗 IP주소 라고도 부른다)이고 포트포워딩이나 NAT/NAPT 등을 통해 인터넷에서 사용할 수 있는 공인 IP주소(퍼블릭 IP주소)로 바뀐다. 그것은 인터넷 계층에서 자세히 설명하겠다!
TCP와 UDP가 무엇인지, 차이에 대한 설명은 블로그 글에 자세히 정리해 놓았다. 여기서는 가볍게 훑는 정도로 한 번만 더 정리해보자.
정확한 데이터의 교환이 중요한 HTTP 통신이나 SMTP 통신에서 사용하는 프로토콜이다. 다음과 같은 특징이 있다.
상기한 특징은 모두 신뢰성 있는 연결을 보장하기 위한 특징이다. 통신 경로를 확보하여 데이터 유실 가능성을 최소화하고, 유실되었을 때 재전송을 통해 무결성을 보장한다. 또한 TCP는 통신을 시작하기 전에 주고받을 데이터의 최대 크기인 MSS(Maximum Segment Size)를 정하기도 한다. TCP는 어떻게 말하면 정확한 데이터 전달 집착광공인 것이다.
통신 시작 전, 서버-클라이언트 간 연결을 확보하고 가상 회선을 구축하기 위해 3-way handshaking 과정을 거친다.
이 이후 A와 B는 본격적으로 양방향 데이터를 송수신할 수 있게 된다. 이 때 서로간에 전송되는 ACK 비트는 모두 1이된다.
참고로 A와 B가 handshaking 과정에서 보내는 세그먼트의 시퀀스 번호는 임의의 숫자이다. 이는 패킷 번호를 유추해서 malfunction 데이터를 보내는 해킹을 방지하고, 포트가 재사용됐을 때 패킷 데이터의 혼선을 막기 위함이다.
전반적으로 패킷 보내기 -> 수신 확인 -> 다음 패킷 보내기 과정으로 이뤄진다. 편의를 위해 Sequence nubmer을 seq로, Acknowledgement number을 ack로 표현한다.
여러가지 이유로 패킷이 수신 측에 제대로 도착하지 않거나 전송 과정 중 패킷이 손상될 수도 있다. 이 경우 수신 측에선 해당 패킷에 맞는 ack 패킷을 보내지 않는다. 일정한 시간이 지나도 전송한 패킷에 대한 ack 패킷이 도착하지 않으면 송신 측은 같은 패킷을 한 번 더 보낸다.
패킷을 MSS 단위로 보낸 뒤 하나하나 수신확인을 하기도 하지만, 보통은 송신 측에서 한 번에 여러 개의 세그먼트들을 보내고, 보낸 세그먼트들 각각에 대한 수신확인 세그먼트들 역시 여러 개를 받는다.
한 번에 어느 정도의 세그먼트를 보낼지는 수신측이 보낸 세그먼트 헤더의 Window Size에 의해 결정된다. Window Size는 수신 측 버퍼의 남은 공간으로, 남은 공간이 많으면 더 많은 패킷을 한꺼번에 보내고 반대의 경우엔 더 적게 보내는 식으로 통신 속도를 조절할 수 있다.
양방향 통신이 끝나고, TCP 연결이 해제되는 과정은 4-way handshaking을 통해 이뤄진다. TCP 연결 해제에서 중요한 점은 연결이 해제되기 전 미처 도착하지 못한 패킷에 대비하는 것이다. 전송되어야 할 패킷이 남은 상황에서 한 쪽에서 일방적으로 연결을 끊어버리면, 상대방은 자신이 보낸 패킷이 잘 수신되었는지 확인할 수 없다. 이 경우를 대비하기 위해 TCP는 wait 상태를 둔 4-way handshaking을 실행한다.
A-B가 연결된 상황에서, A가 연결을 끊으려고 할 때 어떤 과정이 일어나는지 살펴보자.
보낸 패킷의 수신 확인을 하고, 순서대로 보내고, 재전송을 하고, 네트워크 혼잡이나 수신측의 사정에 따라 전송 속도를 조절한다. 이는 모두 통신을 통해 정확한 데이터를 보내고자 하는 TCP가 사용하는 여러가지 방법들인 것 같다.
UDP는 TCP와 비교하면 굉장히 간단한 통신과 헤더 구조를 이루고 있다. 정확한 데이터 교환보단 빠른 데이터 전송이 필요한 네트워크에서 선호된다.
오로지 데이터의 빠른 전송만을 고려한 프로토콜이라고 할 수 있다.
온갖 컨트롤 비트, seq/ack 번호, window size 등이 들어있는 TCP 헤더와는 다르게 간단한 구조다.
handshaking도, 수신 확인도, 재전송도, 혼잡 및 흐름 제어도 없다. 사용자 요청에 따라서 응답 데이터를 데이터그램 단위로 우다다다 보낼 뿐이다.
간단하게 TCP와 UDP의 차이에 대해 표로 정리해보았다.