[네트워크] TCP/UDP, 소켓의 개념부터 TCP 커넥션까지 (feat. 3-way, 4-way handshake)

Woonil·2025년 5월 17일

컴퓨터 네트워크

목록 보기
3/9

TCP와 UDP를 각각 한마디로 표현하면 TCP는 신뢰성을 보장하는 전송 계층 프로토콜, UDP는 그렇지 않은 전송 계층 프로토콜이라 할 수 있다.

TCP(Transmission Control Protocol)는 근거리 통신망이나 인트라넷, 인터넷에 연결된 컴퓨터에서 실행되는 프로그램 간 일련의 옥텟을 안정적으로, 순서대로, 에러 없이 교환할 수 있게 해주는 프로토콜이다. 반면, UDP(User Datagram Protocl)는 비연결 지향성을 지녀 통신 채널이나 데이터 경로를 설정하기 위한 사전 통신을 요구하지 않는다.

[출처: 위키백과]

IP와의 차이
IP(네트워크 계층)는 호스트와 호스트 사이의 데이터를 전송하는 반면, UDP/TCP(트랜스포트 계층)는 특정한 프로세스와 프로세스 간의 데이터를 수송한다. (하나의 호스트에는 하나 이상의 네트워크 응용 프로세스들이 동작하고 있다.)

ex) HTTP 클라이언트 프로세스와 HTTP 서버 프로세스 간 통신

🤔개념

등장 배경

위의 TCP/IP 스택에서는 논리적으로 크게 두 계층으로 나눌 수 있다.

  • Application(application layer): 애플리케이션 레벨에서 구현되고 관리되며, 네트워크 기능을 사용하는데 목적을 둔다.
  • System(transport, internet, link layer): 하드웨어/펌웨어, 운영체제 레벨에서 구현되고 관리되며, 네트워크 기능을 지원하는데 목적을 둔다.

애플리케이션 내의 특정 프로세스가 인터넷을 통해 또 다른 프로세스와 통신을 하기 위해서는 이 Application 계층과 System 계층 간의 통신이 필요하다. 이때, 통신을 하기 위한 경로가 Port(포트)이며, 이는 프로세스와 연결된 데이터 경로 또는 채널 역할을 한다.

실제로는 애플리케이션 내에 여러 프로세스가 존재하므로 모든 프로세스에 대해 포트가 필요하다. 따라서 각 프로세스를 구분하기 위해서 포트도 유일하게 식별 가능해야 했으며, 각 system은 각자의 방식으로 포트명을 지정하여 프로세스를 구분하기 시작했다.

인터넷 상에 존재하는 두 호스트가 있고, 프로세스 간 통신하는 모습을 생각해보자. 이전에 언급했듯 프로세스 간 통신을 위해서 각 프로세스에는 포트가 연결된다.

이제 System layer에서는 인터넷을 통해 연결 경로를 확립한 후 데이터를 송수신하며, 하위 계층의 인터넷 프로토콜(Internet Protocol, IP)이 이 과정을 수행한다. IP는 호스트 A에서 호스트 B로 최적의 경로를 찾아 데이터를 전송한다.

이때, IP가 비신뢰성의 특징을 가진다는 점에 주목해야 한다. 여기서 비신뢰성이란 송신한 데이터가 중간에 유실될 수도 있으며, 순서대로 수신되지 못할 수 있음을 의미한다. 따라서 프로세스 간 안정적인 데이터 송수신을 위해 적합한 프로토콜이 필요했고, IP 위에서 동작하는 TCP가 등장한다.

Connection-Oriented

connection은 ‘연결’이란 뜻을 지닌다. TCP의 connection(커넥션)은 물리적 연결이 아닌 프로세스 간의 안정적이고 ‘논리적인’ 통신 통로를 의미한다. 두 프로세스는 먼저 이 커넥션을 열어 해당 커넥션 위에서 데이터를 주고받은 후, 데이터 송수신이 완료되면 커넥션을 닫는다.

이때, 데이터 송수신 전 커넥션을 먼저 여는 이유는 두 프로세스 간 안정적인 통신을 위한 초기화 과정을 진행하기 위함이다. 또한 커넥션을 닫는 이유는 통신 과정에서 시스템으로부터 할당받았던 자원을 반환하기 위함이다.

UDP는 연결을 맺지 않고 바로 데이터를 주고 받는 connectionless(비연결성) 형태이고, internet protocol을 거의 그대로 사용하기 때문에 unreliable(비신뢰성)의 특징을 지닌다.

소켓 = 인터넷 주소 + 포트번호

앞서 시스템 내의 포트를 식별하는 방법은 시스템마다 다르다고 했다. 따라서, 인터넷 상에서 프로세스의 포트를 유일하게 식별하기 위해서는 방법을 통일할 필요가 생겼다. 이때, 16 bits로 이루어진 숫자(0~65535)인 port number(number는 생략해서 port라 불리기도 함)가 식별자로 등장한다.

하지만 이 포트 번호만으로는 인터넷 상의 수많은 프로세스를 식별하는 것이 불가능하다(0~65535의 숫자만 표현 가능). 이때, 각 호스트를 식별하기 위해 인터넷 주소를 사용하고 있었던 점에 착안하여, 이 주소를 포트 번호와 조합하여 프로세스를 유일하게 식별할 수 있는 방법이 고안된다. 이로써 인터넷 주소와 포트 번호를 합친 개념인 socket(소켓)이 등장하게 된다. 즉, 소켓은 인터넷 상에 존재하는 각 포트를 유일하게 식별하기 위한 주소라 볼 수 있다.

커넥션과 소켓

인터넷 상에 존재하는 모든 커넥션을 유일하게 식별할 수 있어야 한다. 이전에 호스트 내의 특정 소켓은 해당 호스트 내에서 유일하게 식별된다고 했다. 그러면 한 쌍의 소켓은 인터넷 상에서 유일한 커넥션을 이루기에 충분하다 볼 수 있다. 이때, 커넥션을 요청한 호스트의 소켓을 출발지 소켓, 커넥션 요청을 받기 위한 호스트의 소켓을 목적지 소켓이라 하면 각 소켓을 아래와 같이 풀어서 설명할 수 있다.

하나의 프로세스가 인터넷 상의 여러 프로세스와 송수신하는 경우도 있다. 따라서 하나의 소켓은 동시에 여러 커넥션들에서 사용될 수 있다.

소켓 개념의 확장

포트 번호는 UDP에서도 사용되는 개념이다. 따라서 기존의 소켓 개념에서 protocol을 합쳐야 소켓을 유일하게 식별할 수 있고, <protocol, ip address, port number>로 정의되었다. 결국, TCP/IP 스택에서는 이 세 개의 값으로 유일하게 소켓을 식별할 수 있게 된다.

대부분의 통신은 인터넷 프로토콜을 기반으로 하기에 대부분의 네트워크 소켓은 인터넷 소켓이다. 크게 UDP프로토콜을 사용하는 경우와 TCP프로토콜을 사용하는 경우로 나눌 수 있다.

실제 네트워크 프로그래밍 시의 소켓의 개념의 의미는 지금까지의 설명과 의미가 다소 다르다. 특히 소켓 식별 방법에서는 큰 차이를 보인다.

TCP 헤더

  • MSS(Maximum Segement Size): TCP로 전송할 수 있는 최대 페이로드의 크기이며, TCP 헤더 크기는 제외된다.

[출처: geeksforgeeks]

Sequence Number & Acknowledgement Number

  • Sequence Number(순서 번호): TCP 세그먼트의 올바른 송수신 순서를 보장하기 위해 세그먼트의 첫 바이트에 매겨진 번호이다. 이 번호를 통해 현재 주고받는 TCP 세그먼트가 송수신하고자 하는 데이터의 몇 번째 바이트에 해당하는지 알 수 있다.
  • Acknowledgement Number(확인 응답 번호): 다음으로 수신하길 기대하는 순서 번호이다. 상대 호스트가 보낸 세그먼트에 대한 응답이며, 일반적으로 ‘올바르게 수신한 순서 번호에 1이 더해진 값’으로 설정된다.

Flags

현재 세그먼트에 대한 부가 정보를 나타내는 정보이며, 플래그 비트(flag bits)라고도 한다. 제어 비트는 기본적으로 8비트로 구성되며, 각 자리의 비트가 각기 다른 의미를 지닌다.

플래그명설명
URG (Urgent)데이터의 우선순위가 높다는 의미
ACK (Acknowledge)세그먼트의 승인
PSH (Push)버퍼에 쌓지 않고 지금까지 받은 데이터를 즉시 상위 계층(애플리케이션)으로 전달
RST (Reset)연결된 상태에서, 여타 문제로 인해 연결 초기화 시 사용
SYN (Synchronize)상대방과 연결 수립
FIN (Finish)연결 종료

RST(RESET) 플래그
TCP 연결을 강제 종료할 때 사용되는 플래그로, 비정상적인 세션 연결을 끊어낼 때 설정한다. 악성코드가 감지된 경우, 자원 부족으로 인한 자원 할당을 해제해야 하는 경우, TCP 연결에 장애가 생긴 경우 사용될 수 있다.

3-way handshake

3-way handshake는 한 마디로 ‘데이터 송수신을 위해 필요한 연결 확립 과정’이라 할 수 있다.

TCP 통신에 있어 데이터 송수신(통신)을 위해서는 가상의 통신로(연결)를 확보해야 한다. 이 확보 과정에서 TCP 플래그의 코드 비트(6bit)가 활용되며, 패킷 교환이 총 세 번 이루어진다. (클라이언트의 요청 - 서버의 응답 및 요청 - 클라이언트의 확인 응답)

  • 사용되는 TCP 플래그
    • SYN(Synchronize sequence number): ‘동기화하다’ ⇒ 서로의 상태를 지속적으로 동기화한다.
    • ACK(Acknowledgement): ‘받았음을 알리다’ ⇒ 상대방의 요청을 인지함을 알린다.

2번만 하면 될 것 같은데, 왜 3번을 하지?
TCP는 연결지향형 프로토콜로 양방향성 연결을 지향하므로 클라이언트와 서버는 서로의 존재를 서로에게 알리고(SYN) 확인받는(ACK) 과정이 필요하다. 따라서 2-Way로는 부족한 것이다.

3-way handshake와 4-way handshake를 알아보기 전, TCP 연결의 상태를 표현하는 주요 명칭을 정리해보자.

  • 연결이 수립되지 않았을 때
    상태설명
    CLOSED아무런 연결이 없는 상태
    LISTEN연결 대기 상태
  • 연결 수립 과정
    상태설명
    SYN-SENTactive open 호스트가 SYN 세그먼트를 보낸 뒤, 그에 대한 응답인 SYN+ACK 세그먼트를 기다리는 상태
    SYN-RECEIVEDpassive open 호스트가 SYN+ACK 세그먼트를 보낸 뒤, 그에 대한 ACK 세그먼트를 기다리는 상태
    ESTABLISHED3-way handshake가 끝난 뒤 데이터를 송수신할 수 있는 상태
  • 연결 종료 과정
    상태설명
    FIN-WAIT-1active close 호스트가 FIN 세그먼트로 연결 종료 요청을 보낸 상태
    CLOSE-WAITFIN 세그먼트를 받은 passive close 호스트가 그에 대한 응답으로 ACK 세그먼트를 보낸 후 대기하는 상태
    FIN-WAIT-2FIN-WAIT-1 상태에서 ACK 세그먼트를 받은 상태
    LAST-ACKCLOSE-WAIT 상태에서 FIN 세그먼트를 전송한 뒤 대기하는 상태
    TIME-WAITactive close 호스트가 마지막 ACK 세그먼트를 전송한 뒤 접어드는 상태

과정

  1. 클라이언트는 서버에 SYN 플래그가 세팅된 패킷을 보낸다.
    1-1. TCP의 순서 번호에 난수를 부여 / 확인 응답 번호는 0으로 세팅

    난수 생성 이유
    클라이언트-서버 간 tcp 연결이 이전에도 이루어졌다면, 순차적으로 순서 부여 시 다른 tcp 연결로부터 오는 패킷으로 인식할 가능성이 존재하므로 난수를 생성하여 이러한 가능성을 줄인다.

  2. 서버는 클라이언트의 요청을 받고 요청을 수락한다는 ACK 플래그와 SYN 플래그가 같이 세팅된 패킷을 클라이언트에게 보낸다.
    2-1. TCP의 SEQ번호에 난수를 부여
    2-2. ACK번호에는 클라이언트로 받은 SEQ번호 + 1
  3. 클라이언트는 서버의 수락 응답인 패킷을 받고, ACK 플래그가 세팅된 패킷을 서버로 보냄으로써 연결이 성립된다.
    3-1. SEQ번호는 서버로부터 받은 ACK번호 ⇒ 동기화 완료
    3-2. ACK 번호에는 서버로부터 받은 SEQ번호 + 1

SYN Flooding
1. 해커가 가상의 클라이언트로 위장해 표적 서버로 대량의 SYN 패킷을 전송한다.
2. 공격 대상지인 서버는 각 연결 요청에 응답하며, 응답 수신 준비가 완료된 포트를 남겨둔다.
3. 도착하지 않는 마지막 ACK 패킷을 서버가 기다리는 동안 해커는 계속해서 더 많은 SYN 패킷을 전송한다.
4. 사용 가능한 모든 포트를 사용하고 나면 해당 서버는 정상적 기능 수행이 불가해진다.

⇒ 이에 대비하기 위해 수신지의 SYN 수신 대기 시간을 줄이거나 침입 차단 시스템을 활용할 수 있다.

Multi Thread
단일 스레드로는 여러 개의 요청이 왔을 때, 이전 요청의 처리로 인해 이후 요청이 스레드를 할당받기 위해 대기하는 상황이 생긴다. 이때, 처리 지연으로 두 요청 모두 죽을 수 있는데, 여러 개의 스레드를 생성하여 이런 문제를 해결할 수 있다(요청마다 스레드를 생성하는 방식과 쓰레드 풀에 일정량의 스레드를 관리하는 방식 등이 있음).

4-way handshake

클라이언트와 서버가 데이터 통신이 종료된 이후에 해당 연결을 끊는 과정(세션 종료)이다. 양쪽 호스트 모두 그 주체가 될 수 있으며, 3-way Handshake와 마찬가지로 TCP 헤더의 플래그가 사용된다.

과정

  1. 클라이언트는 서버에게 FIN 플래그를 설정한 패킷을 서버에 전송한다.

    FIN(FINISH) 플래그
    세션 연결을 종료시킬 때 사용되며 더 이상 전송할 데이터가 없음을 나타낸다.

  2. 서버는 클라이언트에게 ACK 응답 패킷을 전송한다.

  3. 서버는 소켓을 해제하고 통신 종료를 의미하는 FIN 패킷을 클라이언트에 전송한다.

  4. 클라이언트는 서버에게 ACK 응답 패킷을 전송한다.

    연결을 끊는 주체의 TIME-WAIT
    연결을 끊는 FIN를 보내는 엔드포인트가 마지막 ACK를 수신자에게 보낸 후 TIME-WAIT 상태에 빠지는 이유는?

    TIME_WAIT이란 수신자로부터 FIN를 수신하더라도 일정시간(디폴트 240초) 동안 세션을 남겨놓고 잉여 패킷을 기다리는 과정으로, 일정시간이 지나면 세션을 만료시키고 연결을 종료하며 CLOSE 상태로 변화한다.

    • 수신자가 FIN를 전송하기 전에 전송한 패킷(ex. 마지막으로 세션을 종료하기 위한 과정에서 보내지는 데이터)이 라우팅 지연이나 패킷 유실로 인한 재전송 등으로 인해 FIN 패킷보다 늦게 도착하는 경우가 생기는 상황에 대비가 가능하다.
    • 수신자가 ACK 수신에 실패하면 수신자는 송신자에게 다시 한번 FIN를 송신하게 된다. 만약, TIME-WAIT 상태 없이 통신을 종료하게 된다면 수신자는 정상적인 소켓 종료를 행하지 못할 것이다.

UDP 헤더

UDP는 사실상 IP 위에 씌어진 껍데기 정도의 수준의 헤더를 가지며, 포트 정보 이외에는 IP 통신과 크게 다를 것이 없다.

[출처: GeeksforGeeks]

  • 송신지 포트: 데이터를 생성한 애플리케이션의 포트 번호
  • 수신지 포트: 목적지 애플리케이션이 사용하는 포트 번호
  • 길이: UDP 헤더와 데이터를 합친 총 길이
  • 체크섬: 전송된 데이터그램의 훼손 여부를 검사하는 값으로, TCP와 다르게 필수 옵션은 아니다.

체크섬 상세

  • 순서
    1. UDP 세그먼트를 word(16비트) 단위로 나눈다.
    2. 나누어진 각 word를 모두 더한 후, 1의 보수 연산을 수행하여 checksum을 만든다.
    3. 수신측에서 세그먼트를 수신하면 해당 세그먼트에 대해 checksum을 다시 만든다.
    4. 수신된 checksum과 비교하여 오류 여부를 판단할 수 있다.

TCP vs UDP 한 눈에 비교표

TCPUDP
연결방식연결형 서비스비연결형 서비스
패킷 교환가상 회선 방식데이터그램 방식
전송 순서 보장보장보장 x
신뢰성높음낮음
전송 속도느림빠름
예시웹 브라우징(HTTP/HTTPS), 파일 전송(FTP 등), 메일 서버(STMP 등)실시간 스트리밍, DNS 서버, tftpd, RIP

참고자료
BJ.58-1 (이론편) 표준 스펙에서 정의한 Socket(소켓), Port(포트), TCP connection 개념 설명. 실제와는 조금 다름. 실제 개념은 2부에서!
[따라學IT] 09. 연결지향형 TCP 프로토콜 - TCP 프로토콜 구조와 TCP의 플래그
[따라學IT] 09. 연결지향형 TCP 프로토콜 - TCP 3Way Handshake
[취업을 위한 CS 지식] 30강. 전송 계층 - TCP와 UDP

profile
프론트 개발과 클라우드 환경에 관심이 많습니다:)

0개의 댓글