1:1 통신: 하나의 송신자와 하나의 수신자 간에 신뢰성 있는 데이터 전송
Reliable: 신뢰성 있는 데이터 전송을 제공
In-Order Byte: 데이터는 바이트 스트림으로 전송되어 메시지 경계가 없다.
- 100바이트의 데이터가 전송되었다면 수신자는 이 100바이트 데이터를 한 번에 읽을 수도 있고 10바이트씩 10번에 걸쳐 읽을 수도 있다.
- MTU(Maximum Transmission Unit): 네트워크에서 전송 가능한 패킷의 최대 크기
- MSS(Maximum Segment Size): MTU에 맞게 Segmentation하고 전송할 때 사용되는 최대 크기
Cumulative Byte ACKs(n): TCP는 ACK를 사용하여 수신자가 어떤 데이터까지 정상적으로 받았는지 확인한다.
- n - 1번 바이트까지 잘 받았음을 의미
Pipelining: 하나의 패킷이 전송 중일 때 다음 패킷을 연속적으로 전송 가능
Connection-Oriented: 연결을 설정하고 해제하는 핸드셰이킹 과정을 거쳐 안정적인 통신을 제공
- Piggybacking : 데이터 전송과 ACK을 하나의 패킷에 함께 실어서 전송
Flow Control: 수신자의 처리 속도에 맞춰 데이터 전송 속도를 조절
→ 하나의 층당 32비트
- source port # & destination port #: 송신, 목적자의 포트 번호
- sequence number(bytes fo data): 세그먼트 데이터가 원본 데이터의 어느 위치에 있는지 나타내는 값
→ 어떤 세그먼트가 원본 데이터의 0~999번째 바이트를 가지고 있다면, 해당 세그먼트의 시퀀스 넘버는 0으로 표현된다.
이는 데이터의 시작 지점을 나타내며, 세그먼트의 순서를 보장하는 데 필요한 필드이다.
→ 비트 단위가 아닌 바이트 단위로 데이터의 위치를 나타낸다.- acknowledgement number: 수신자가 다시 송신자에게 ACK를 보낼 때 사용하는 필드로, 다음에 받기를 원하는 데이터의 sequence number를 의미한다.
→ sequence number가 0인 segment를 잘 받았으면 다음 세그먼트를 요청하기 위해서 ack number에는 1000 이 저장된다.- headlen : 헤더의 크기
→ 어디서부터 데이터가 시작되는지 offset을 담고 있다.- C: 현재 네트워크 상황이 혼잡하여 데이터 양을 줄였다는 사실을 알리기 위해 송신자 측에서 설정하는 필드
- E: 현재 네트워크가 혼잡하다는 사실을 알리기 위해 수신자 측에서 설정하는 필드
- U: 해당 TCP 세그먼트가 먼저 처리되어야 하는 긴급 메시지 여부를 나타낸다.
- A : 플래그가 1로 설정되어 있으면 해당 세그먼트가 ACK 상태임을 나타낸다.
→ 수신자가 설정하여 송신자에게 전송- P : 플래그가 설정된 세그먼트는 Threshold 값까지 버퍼에 데이터가 쌓일때까지 기다리지 말고 즉시 전송하도록 요청하는 것을 나타낸다.
- R: connection reset (비정상 종료)
- S: connection initiation
- F: connection finish (정상 종료)
- receive window : 현재 수신자가 처리할 수 있는 데이터 양을 나타낸다.
→ 송신자에게 더 많은 데이터를 전송해도 안전하다는 신호를 보내며, 더 많은 데이터를 전송할 수 있는 윈도우 사이즈를 나타낸다.
→ flow control을 돕는다.- checksum : 오류 검증 필드
→ 주소 에러 등의 추가 정보 확인을 위해 TCP는 pseudo-header를 사용하여 IP 주소와 같은 정보를 확인- Urg data Pointer : 긴급 데이터의 위치를 나타낸다.
- options: TCP 옵션은 선택적인 정보를 포함할 때 사용됩니다.
→ TCP 헤더는 20바이트에서 최대 60바이트의 공간으로 고장되어있으며 필요에따라서 option 영역의 크기를 할당할 수 있다.
→ option의 길이는 필요한만큼 사용할 수 있다(x) → TCP header의 최대크기는 제한되어있어 제한이 있다.- Application data : 실질적으로 전달되는 데이터로 응용 계층으로 전달된다.
RTT: 송신자가 데이터를 보내고 그에 대한 응답을 받을 때까지 걸리는 시간
일정 시간을 기다려도 ACK를 받지 못하면 timeout을 발생시켜 재전송한다.
여기서 일정시간을 어떻게 적절한 시간으로 설정할까?
- timeout 기준 시간은 RTT에 기반하여 설정되어야 한다.
- 너무 짧게 설정하면 premature timeout으로 인해 불필요한 재전송이 발생
- 너무 길게 설정하면 segment loss에 대한 신속한 대처가 어려워 진다.
시간 설정 방법
- 송신자가 이전에 보냈었던 RTT 기록을 참조할 수 있지만, RTT가 평균과 같은거라고 보장할 수 없다.
- SampleRTT & EstimatedRTT
- sampleRTT: 세그먼트가 송신자에서 전송되어 수신자로 ACK가 올 때까지의 실제로 측정된 RTT 값
- estimateRTT: 현재까지 측정한 여러 SampleRTT 값들의 평균
- estimatedRTT = (1-α) x estimatedRTT + α x sampleRTT
- α: 현재 영향을 미치는 정도이며 보통 0.125로 설정한다.
→ 알파(α) 값이 높다는 것은 예전에 구한 평균값에 대해 최근에 구한 SampleRTT 값을 더 큰 비중으로 두는 것을 의미- TimeoutInterval = EstimateRTT(현재 구한) + 4 * DevRTT(sample - estimatedRTT)
ACK loss
Premature timeout
Cumulative ACK
→ ACK의 손실에도 불구하고 cumulative ack을 통해 재전송을 방지할 수 있다.
Fast retransmit: timeout이 되기 전에 segment의 loss 여부를 판단하고 재전송(retransmit)
→ 중복된 ACK를 여러 번 받는다.
seq 번호가 100인 segment의 timeout interval이 길게 설정되어 있어도 ACK(100) 을 4번째 받을 때(중복 ACK가 3개 쌓이면, 표준) 해당 segment 재전송한다.
송신자와 수신자 간의 데이터 전송 속도를 조절하기 위한 메커니즘
버퍼 오버플로우: 데이터를 처리하는 속도보다 데이터가 버퍼에 쌓이는 속도가 더 빨라서 버퍼가 가득 차게 되고, 이로 인해 패킷 손실이 발생하는 상황
flow control: 수신자는 자신의 버퍼 공간 중에서 얼마나 여유가 있는지를 TCP 세그먼트의 receive window를 통해 송신자에게 전달한다.
이에 따라, 송신자는 데이터를 보낼 때 수신자의 버퍼 여유 공간을 고려하여 데이터 전송 속도를 조절할 수 있다.
→ Free buffer space: rwnd(receive widow)
→ rwnd = RcvBuffer - (LastByteRcvd - LastByteRead)
= 여유 버퍼 공간 = 수신 버퍼 - (수신했지만 상위 계층으로 전송하지 않은 데이터)
연결 지향형 프로토콜로, 데이터 교환 전에 먼저 연결을 설정하고 안정적으로 데이터를 교환한 뒤 연결을 안전하게 종료하는 과정을 handshaking 거친다.
2-way handshaking
- 송신자 호스트는 수신자 호스트에게 연결을 설정하고자 하는 메시지를 전송
- 수신자 이를 확인하는 응답 메시지를 송신자에게 다시 전송
- 문제점 I: A의 SYN에 대해 B의 ACK가 도달하기 전에 timeout이 발생
- A가 seq 100으로 SYN을 보냈을 때 B가 이에 대한 응답으로 ACK 101을 보냈지만, 해당 ACK가 도착하기 전에 timeout
- seq 200으로 retransmission
- 101에 대한 ACK를 무시
- B가 생각하는 A의 시퀀스 번호와 실제 A가 전송한 시퀀스 번호가 다르게 되는 상황 발생
- 문제점 II: B는 본인의 ACK가 잘 전송되었는지 알 수 없음
→ B의 ACK에 A도 ACK 응답을 해 주어야 TCP 양방향 통신의 신뢰성이 보장 될 수 있다.
3-way handshaking: TCP 프로토콜을 사용하여 연결을 설정할 때 사용되는 절차로 세 단계로 이루어진다.
- 클라이언트는 ISN과 함께 SYN 플래그를 설정하여 서버에 연결 요청
- ISN : 32비트 시퀀스의 고유번호이며, 이를 통해 TCP 연결을 구분하여 통신 충돌 방지
- SYN = Synchronization, 연결 요청 플래그
- ACK = Acknowledment, 응답 플래그
- 서버는 서버의 ISN 값을 생성하고, 클라이언트의 ISN + 1 값을 SYN/ACK(연결 응답) 플래그와 함께 클라이언트에게 전송
- 클라이언트는 SYN/ACK을 확인하고, 서버의 ISN + 1 값과 ACK 플래그와 함께 서버에게 전송하여 연결 설정을 완료
- 상태변화: 클라이언트, 서버 모두 CLOSED 된 상태에서 연결 시작
- 클라이언트 SYN → 클라이언트 상태는 SYN-SENT로 변경
→ 이 때, 서버는 LISTEN 상태여야 함- 서버 상태는 SYN-RECEIVED로 변경 → 서버는 SYN/ACK 전송
- 클라이언트 SYN/ACK 수신 → 클라이언트 ESTABLISHED → 클라이언트 ACK → 서버 ESTABLISHED
→ 이와 같이 3-way handshaking 과정을 거치면서 클라이언트-서버 간의 연결과정이 성립되기 때문에 TCP는 신뢰성이 있다고 말할 수 있다.
4-way handshaking: 데이터 전송이 완료되었으며 양쪽 호스트가 연결을 종료하려고 할 때 사용하는 TCP 연결 종료 과정
→ 클라이언트, 서버 모두 ESTABLESHED 되어있는 상태에서 연결 해제 시작
- 클라이언트가 연결 종료를 요청하기 위해 FIN 세그먼트를 전송하면, 클라이언트는 FIN_WAIT 1 상태로 전환
- 서버는 FIN 요청을 받으면 CLOSED_WAIT 상태로 이동하고, ACK 세그먼트를 클라이언트에게 전송하면 클라이언트는 FIN_WAIT 2 상태로 전환
- 일정 시간 후, 서버는 CLOSED_WAIT 상태에서 LAST_ACK 상태로 변경하고 FIN 세그먼트를 전송
- 클라이언트는 TIME_WAIT 상태로 변경하고 ACK를 전송한 후, 서버는 CLOSED 상태로 전환
→ 클라이언트는 설정한 TIME_WAIT 시간이 지나면 CLOSED 상태로 전환
- TIME_WAIT 상태: 연결 종료 프로세스가 완료되고 모든 리소스가 확실히 해제될 때까지 대기하는 상태
→ MSL * 2 시간으로 보통 설정
→ MSL(Maximum Segment Lifetime): 최대 패킷 수명으로 OS마다 차이가 있음 (Ubuntu : 60초, Window : 4분)- TIME_WAIT 설정 이유
- 지연 패킷을 수신: 클라이언트는 연결 종료 후 일정 시간 동안 지연 패킷을 기다릴 수 있다.
→ 데이터 무결성을 조금 더 보장- 연결이 올바르게 닫힌 상태로 만들기 위해: TCP 연결이 완전히 종료되고 더 이상 해당 연결에 관련된 리소스나 포트가 사용되지 않도록 하는 과정
→ 이후 새로운 TCP 연결이 올바르게 설정될 수 있도록 한다.