[네트워크] 혼공네트 독서 #9 - TCP

2026. 1. 26. 16:18·CS/컴퓨터 네트워크

https://dev-dx2d2y-log.tistory.com/194

 

[네트워크] 혼공네트 독서 #8 - L4계층

https://dev-dx2d2y-log.tistory.com/184 [네트워크] 혼공네트 독서 #5 - 네트워크 계층과 IPv4, IPv6 패킷구조, ARPhttps://dev-dx2d2y-log.tistory.com/181 [네트워크] 혼공네트 독서 #4 - 네트워크 장비, 허브와 스위치https:/

dev-dx2d2y-log.tistory.com

저번에는 L4계층에 대해서 대략적으로 다뤄보았고, 이제는 본격적으로 L4계층의 대표적인 프로토콜인 TCP에 대해서 알아보려한다.


TCP

Transmission Control Protocol

신뢰할 수 있는 연결을 위한 연결형 프로토콜이다. 데이터를 송수신하기 전에 호스트 간 연결을 수립하고 데이터 송수신이 끝나면 연결을 해제하며, 연결이 유지되는 동안 패킷이 제대로 전송이 되는지 확인하고, 전송에 실패하면 재전송하는 기능들을 담당한다.

 

TCP 패킷 구조

TCP패킷의 구조는 이렇게 생겼다.


송수신지 포트

https://dev-dx2d2y-log.tistory.com/194

 

[네트워크] 혼공네트 독서 #8 - L4계층

https://dev-dx2d2y-log.tistory.com/184 [네트워크] 혼공네트 독서 #5 - 네트워크 계층과 IPv4, IPv6 패킷구조, ARPhttps://dev-dx2d2y-log.tistory.com/181 [네트워크] 혼공네트 독서 #4 - 네트워크 장비, 허브와 스위치https:/

dev-dx2d2y-log.tistory.com

저번에 다뤘던 L4계층의 포트를 말한다. IP주소는 L3계층에 담당하기 때문에 L4계층의 포트를 보고 패킷을 전송할 수신지 애플리케이션을 명시한다.


순서 번호 (시퀀스 번호)

보낼 데이터들을 쪼개서 보내는 경우, 각 세그먼트들의 올바른 순서를 보장하기 위해 세그먼트 데이터의 첫 바이트에 부여되는 번호다.

 

MSS(Maximum Segment Size)라는 단위가 있는데, 이는 TCP 페이로드의 크기이다. (MTU와 달리 헤더는 포함하지 않는다) 보낼 데이터의 크기가 크다면 MSS단위로 데이터를 쪼개서 보내게되는데, 이 때 가장 첫 번째로 보낼 데이터의 순서번호는 무작위로 설정된다. 가장 먼저 보낼 순서번호가 100이될 수도 있고, 1000이 될 수도 있고..

 

두 호스트가 연결되었다가 잠깐동안 연결이 끊어진 후 같은 포트로 다시 연결될 때, 잠깐동안 연결이 끊어지기 이전의 패킷이 전송이 다소 지연되어 수신지에 연결이 끊어졌다가 다시 연결될 후에 수신지에 도착했다고 치자. (지연패킷, Delayed Duplicate) 연결이 끊어지기 이전의 패킷은 쓸모가 없지만 순서 번호가 없다면 이 패킷이 연결이 끊어지기 이전의 패킷인지, 그 이후의 패킷인지 알 수 없기 때문에, 두 호스트가 연결된 후 가장 먼저 들어오는 패킷에 무작위로 번호를 부여하고 그 다음 패킷마다 송신한 데이터의 크기를 더해가는 것이다.

 

가령 초기 순서번호가 1000이고, MSS가 500이라면 초기 순서 번호는 1000, 그 이후로 들어오는 패킷의 순서번호는 1500, 2000, 2500...이렇게 되는 것이고, 초기 순서번호가 무작위로 선정되므로 새로운 연결에서는 초기 순서 번호가 100으로 맞춰지면 그 이후로는 600, 1100, 1600... 이렇게 순서 번호가 맞춰지는 것이다. 따라서 연결이 끊어지고 다시 재연결될 경우 무작위 순서 번호 선정 덕분에 패킷이 이전의 패킷과 섞일 일이 없다.

 

따라서 순서 번호를 사용하는 이유는 패킷이 지연될 때 예전 패킷과 데이터가 섞이지 않게하는 목적도 가지고 있으며, 추가로 순서 번호를 무작위로 하는 이유는 패킷의 순서번호를 예측해 악성데이터를 심어놓는 일을 방지하기 위함이다.


확인 응답 번호

순서 번호에 대한 응답이다. 수신호스트가 패킷을 받으면 받았다는 알림을 송신한 호스트에게 보내야하는데, 이 때 다음 순서 번호를 명시한다. 예를 들면 "순서 번호 1000번 패킷을 잘 받았습니다. 다음으로는 순서 번호 1500번 패킷을 주십시오"라고 명시하는 필드이다.

 

패킷 번호는 TCP 페이로드로만 계산한다. 아무것도 보낼 데이터가 없다면 패킷 번호가 증가하지 않을 것이다.


데이터 오프셋

IP헤더의 데이터 오프셋과 마찬가지로 TCP 헤더의 길이를 나타낸다. 4바이트 단위로 나타내며, 최소값은 5 (헤더가 20바이트, 옵션 필드가 비어있다고 가정할 때 TCP 헤더의 필수부분만 채워넣을 때 크기), 최대값은 15 (헤더가 60바이트, 4비트로 나타낼 수 있는 최대값)


제어 비트 (컨트롤 비트)

여러 제어 값을 나타낸다.

 

CWR (Congestion Window Reduced)

아래 나올 ECE 플래그를 확인했으며, 혼잡도가 높다는 것을 알았다는 뜻이다.

 

ECE (ECN-Echo)

혼잡이 발생했다는 것을 알리는 플래그

라우터는 패킷을 받아서 버퍼에 넣어둔 다음 패킷을 하나씩 처리하는데, 수신되는 정보가 너무 많아서 버퍼의 용량이 부족해지면 혼잡이 발생한다. 따라서 라우터는 호스트에게 응답을 받았음을 알리는 패킷에다가 ECE 필드를 1로 바꿔서 보낸다. 그러면 송신호스트의 TCP가 "지금 이 라우터가 혼잡상황이구나"라고 인지한다. 이 과정을 명시적 혼잡 통지 (Explicit Congestion Notification, ECN) 이라고 칭한다.

 

만약 SYN플래그가 1일 때 ECE 플래그도 1로 활성화되면 송신측 TCP에서 ECN을 지원한다는 뜻이다.

 

URG (Urgent)

아래 나오겠지만 긴급 포인터란 값이 있는데, 이 필드의 값이 유효하다는 것을 뜻하며, 해당 패킷이 긴급하게 처리되어야한다는 것을 의미한다.

 

ACK (Ackknowledgement)

응답을 확인했음을 나타낸다. 초기 연결 시 클라이언트가 보낸 최초의 SYN 패킷 이후에는 반드시 ACK 필드가 활성화되어야한다.

 

PSH (Push Function)

밀어넣기라는 말이 있는데, 이는 OSI 7계층에서 전송계층의 윗계층이 아니라 곧바로 7번째 Application 계층으로 정보를 보낼지 여부를 확인한다. 주로 신속하게 전달해야할 때 사용한다.

 

RST (Reset)

커넥션을 강제로 끊는다. TCP연결에서 연결이 끊어지려면 몇 가지 절차가 필요한데, 패킷을 보내는 측에서 당장 연결을 끊어야할 때 사용한다.

 

SYN (Synchronize Sequence Numbers)

TCP 연결을 할 때 나오겠지만, SYN 플래그가 1로 설정되면 커넥션을 여는 역할을 한다. 양 쪽에서 주고받는 첫 번째 패킷만 SYN 플래그가 1로 설정되어있어야한다. 즉, "연결을 시작할까요?"라는 의미. SYN플래그가 1이면 초기 순서 번호가 무작위값으로 설정된다.

 

FIN (Finish)

더이상 송신할 데이터가 없어 연결을 끊는다는 의미이다.


윈도우

수신 윈도우의 크기를 명시한다. 수신 윈도우란 한 번에 수신하고자하는 데이터의 양을 말한다.


체크섬

https://dev-dx2d2y-log.tistory.com/184

 

[네트워크] 혼공네트 독서 #5 - 네트워크 계층과 IPv4, IPv6 패킷구조, ARP

https://dev-dx2d2y-log.tistory.com/181 [네트워크] 혼공네트 독서 #4 - 네트워크 장비, 허브와 스위치https://dev-dx2d2y-log.tistory.com/180 [네트워크] 혼공네트 독서 #3 - 이더넷 프레임https://dev-dx2d2y-log.tistory.com/178

dev-dx2d2y-log.tistory.com

IP헤더의 체크섬과 매커니즘을 동일하지만, IP의 체크섬은 IP헤더만 검사했다면, TCP는 TCP헤더와 데이터, 그리고 IP헤더의 일부 정보 (송/수신지 IP 주소 등)도 계산한다. TCP헤더의 무결성도 보장하면서 IP계층의 무결성도 이중으로 검사하는 셈.


긴급 포인터

제어비트에서 URG 비트가 1로 표기될 때 유효하다. URG = 1로 설정되면 긴급포인터에서는 마지막 긴급바이트 값의 + 1로 명시되기도하고, 마지막 긴급바이트 값으로 명시되기도한다.(장비마다 다름) 즉, URG 비트가 1로 표기되면 "지금 이 패킷은 아주 신속하게 보내야하며, 긴급 포인터에 명시된 순서 번호 전 (또는 긴급 포인터에 명시된 순서번호)까지만 긴급하다"라는 뜻이다.

그리고 이 긴급 포인터는 상대거리를 나타낸다. 현재 순서 번호가 1300이고, 긴급포인터에 5가 적혀져있다면, 순서 번호 1305번 또는 1304번까지만 긴급한 패킷임을 나타낸다. 순서 번호가 1303이면 긴급포인터에 2가 적혀져있을 것이다.


TCP 연결 및 종료

이렇게 TCP의 헤더에 대해서 알아보았으니, 본격적으로 헤더를 통해 어떻게 TCP가 연결 및 종료되는지를 알아보도록 한다.

 

연결

연결은 3-way handshake를 사용한다. 호스트 A와 B가 있고, A가 B에게 요청을 전달하는 클라이언트, B가 A에게서 요청을 받는 서버라고한다면,

 

1. 연결시작

A는 B에게 연결을 시작한다고 알린다. SYN 플래그비트를 1로 설정하며, 이에 따라 A가 보낼 패킷의 초기 순서번호를 같이 전한다.

 

2. 연결허가

B는 A에게서 요청을 받고, 연결을 시작하려하면 역시 연결을 위해 SYN 플래그비트를 1로 설정하고, 이에 따라 B가 보낼 패킷의 초기 순서번호를 같이 전달한다. 또한 요청에 대한 응답으로 ACK 플래그비트를 1로 설정하고, A가 보낸 초기 순서번호에 대한 확인응답번호를 보낸다. 보통 초기 순서번호를 보낼 때에는 "연결을 시작할까요?"/"연결을 시작합시다"라는 뜻이라 페이로드 부분이 비어있어서 확인응답번호는 초기 순서번호에 +1을 해서 확인응답번호로 보낸다.

 

3. 허가 확인

A는 B가 준 허가신호를 보고 다음 순서번호와, B가 보낸 패킷의 순서번호에 대한 확인 응답 번호, 그리고 1로 설정된 ACK 비트를 보낸다. 보통 요청할 데이터를 준비할 시간이 다소 부족한 경우에는 데이터에 아무것도 채우지 않고 ACK만 보내고, 데이터가 준비되면 그 때 다시 패킷을 보낸다. 이미 준비가 끝났으면 여기서부터 데이터를 페이로드에 담아서 보낸다.

 

B는 A의 패킷 요청에 따라 응답데이터를 ACK 필드를 1로 설정해 A에게 보내고, 이 과정이 반복된다.

 

처음 연결을 시작하는, 그러니까 A와 같은 클라이언트의 역할을 액티브 오픈이라고 칭하고, 요청이 도착해야 연결이 시작되는, 그러니까 B와 같은 서버의 역할을 패시브 오픈이라고 칭한다.


종료

종료는 연결보다 한 가지 과정이 더 있다. four-way-handshake라고도 칭한다.

 

1. 연결종료시작

A가 연결을 끊고 싶다면 FIN 비트를 1로 설정해서 보낸다. 역시 페이로드에는 데이터가 없다.

 

2. 연결종료확인

B는 A의 FIN 비트를 확인하면 A가 보낸 패킷에 대한 확인응답번호와, ACK 비트를 1로 설정해서 보낸다.

 

3. 연결종료

B는 다시 FIN 비트를 1로 설정해서 A에게 보낸다.

 

4. 진짜연결종료

A는 B의 응답에 대한 확인응답번호와 1로 설정된 ACK 비트를 함께 보내고 응답을 종료한다.

 

역시 A와 같이 처음 응답을 종료하는 경우를 액티브 클로즈, B와 같이 요청이 와야 응답을 끊는 경우를 패시브 클로즈라고 칭한다.


TCP 상태

TCP는 호스트가 서로 연결된 상태로 통신이 지속되므로 호스트의 다양한 상태가 있다. 현재 호스트가 어떤 통신과정에 있는지를 나타내며, TCP는 항상 상태가 있다는 점에서 stateful 프로토콜이라고도 한다.

 

상태는 크게 미연결, 연결수립 중, 연결 종료 중 으로 나뉠 수 있다.


미연결 중 상태

CLOSED

아무런 연결이 없는 상태를 뜻한다.

 

LISTEN

패시브 오픈 호스트의 경우에는 액티브 오픈 호스트의 SYN 세그먼트를 기다려야한다. 따라서 LISTEN 상태는 주로 패시브 오픈 호스트가 SYN 세그먼트를 기다리는 상황이라고 볼 수 있다.


연결 수립 상태

SYN-SENT

액티브 오픈 호스트가 SYN 세그먼트를 보낸 후, 패시트 오픈 호스트로부터 SYN + ACK 세그먼트를 기다리는 상태이다. 즉, 연결 요청을 보낸 후에 기다리고 있는 상황이다.

 

SYN-RECEIVED

패시브 오픈 호스트가 SYN + ACK 세그먼트를 보내고 그에 대한 ACK 세그먼트를 기다리고 있는 상태를 뜻한다.

 

ESTABLISHED

연결이 확립되었다. 두 호스트가 서로 ACK 세그먼트를 주고받았으며 본격적으로 데이터를 보내는 과정이 일어날 수 있음을 뜻한다.


연결 종료 상태

FIN-WAIT-1

연결 종료의 첫 번째 단계로, 액티브 클로즈 호스트는 FIN 세그먼트를 보내고 FIN-WAIT-1 단계에 있다. 즉, 패시브 클로즈 호스트에게 연결종료요청을 보내고 기다리는 상태

 

CLOSE-WAIT

패시브 클로즈 호스트가 액티브 클로즈 호스트로부터 FIN 세그먼트를 받고 이에대한 ACK 세그먼트를 보낸 후 대기하는 상태

 

FIN-WAIT-2

액티브 클로즈 호스트가 FIN-WAIT-1 상태에서 ACK 세그먼트를 받으면 FIN-WAIT-2 상태가 된다. 패시브 클로즈 호스트가 다시 FIN 세그먼트를 보내기를 대기하는 중이다.

 

LAST-ACK

패시브 클로즈 호스트가 CLOSE-WAIT 상태에서 FIN 세그먼트를 전송하고, 이에 대한 액티브 클로즈 호스트의 응답을 기다리는 상태를 뜻한다.

 

TIME-WAIT

액티브 클로즈 호스트가 FIN 세그먼트를 받아서 이에 대한 ACK 세그먼트를 전송한 뒤의 상태이다. 패시브 클로즈 호스트는 마지막 ACK 세그먼트를 받으면 CLOSED 상태로 곧바로 바뀌지만, 액티브 클로즈 호스트는 TIME-WAIT 상태에서 일정시간이 지난 후 CLOSED 상태로 바뀐다.

 

이 이유는 마지막 ACK 세그먼트가 제대로 전송되지 않은 경우, 재전송해야하기 때문에 잠깐동안 연결은 유지하는 것이기도하고, 연결이 끝난 후 곧바로 재연결하면 서로 다른 연결의 패킷들에 혼란이 올 수도 있기 때문이다.


CLOSING

CLOSING 상태는 주로 양쪽 도잇에서 요청을 종료하려할 때 나타내는 상태다. 서로가 FIN 세그먼트를 보냈고, 그래서 FIN-WAIT-1 상태에 접어들었다. 그리고 서로 그에 대한 ACK 세그먼트를 받아야하는데, 이 때 대기하고 있는 상태를 CLOSING 상태로 한다. ACK 세그먼트를 받았다면 TIME-WAIT 상태로 곧바로 바뀐 후 연결이 종료된다.

 

이렇게 꽤 많은 상태들이 있는데, 이에 대한 그림은 220쪽에 명시되어있으므로 확인하면 좋을듯하다.

CMD에 netstat을 입력하면 이렇게 주변 기기들과의 TCP 연결상태가 뜬다.

보면은 ESTABLISHED는 이미 연결이 완료되었다는 것이고, 127.0.0.1의 IP주소를 사용하는 연결은 컴퓨터 내의 프로그램끼리의 대화를 뜻한다. netstat -ano 명령어로 프로그램의 PID까지 확인할 수 있는데, 3~4번째 줄 보면 127.0.0.1:49698과 127.0.0.1:49699 간 TCP 통신이 일어나고 있는데, PID로 확인하면 mysqld.exe 가 자기자신에게 TCP 요청을 보내고 받은 것임을 확인할 수 있다. 동기화, 내부 상태 확인 등의 목적으로 사용 중인 것이다.


'CS > 컴퓨터 네트워크' 카테고리의 다른 글

[네트워크] 지연과 패킷손실, 네트워크 계층 프로토콜  (0) 2026.07.01
[네트워크] 인터넷이란 무엇인가?  (0) 2026.06.30
[네트워크] 혼공네트 독서 #8 - L4계층  (0) 2026.01.24
[네트워크] 혼공네트 독서 #7 - 라우팅, 라우팅테이블, 라우터  (0) 2026.01.23
[네트워크] 혼공네트 독서 #6 - IP주소  (1) 2026.01.17
'CS/컴퓨터 네트워크' 카테고리의 다른 글
  • [네트워크] 지연과 패킷손실, 네트워크 계층 프로토콜
  • [네트워크] 인터넷이란 무엇인가?
  • [네트워크] 혼공네트 독서 #8 - L4계층
  • [네트워크] 혼공네트 독서 #7 - 라우팅, 라우팅테이블, 라우터
컬러잇
컬러잇
탄천러너지망생
  • 컬러잇
    Color it
    컬러잇
  • 전체
    오늘
    어제
    • 분류 전체보기 (252)
      • 신년사 (3)
        • 2025년 (2)
        • 2026년 (1)
      • CS (79)
        • JVM (12)
        • 인프라 (6)
        • 백엔드 (22)
        • 논리회로 (5)
        • 언어구현 (1)
        • 인공지능 (1)
        • 코드설계 (3)
        • 컴퓨터구조 (9)
        • 데이터베이스 (4)
        • 컴퓨터 네트워크 (16)
      • 보안 (3)
        • 웹보안 (3)
        • AI보안 (0)
        • 시스템보안 (0)
        • 네트워크보안 (0)
      • 언어공부 (65)
        • Java | Kotlin (49)
        • JavaScript | TypeScript (9)
        • C | C++ (6)
      • 개인 프로젝트 (11)
        • [2025] Happy2SendingMails (3)
        • [2026] 골든리포트! (8)
        • 기타 이것저것 (0)
      • 팀 프로젝트 (29)
        • [2025][GDG]홍대 맛집 아카이빙 프로젝트 (29)
      • 알고리즘 (13)
        • 백준풀이기록 (11)
      • 에러 수정일지 (4)
      • 고찰 (33)
        • CEOS 23기 회고록 (9)
        • 놀이터 (0)
  • 링크

    • 교양있는컬러잇
  • 최근 글

  • 인기 글

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.5
컬러잇
[네트워크] 혼공네트 독서 #9 - TCP
상단으로

티스토리툴바