3.5 연결지향형 트랜스포트: TCP
3.5.1 TCP 연결
TCP는 애플리케이션 프로세스가 데이터를 다른 프로세스에게 보내기 전에,
두 프로세스가 서로 ’핸드셰이크’를 먼저 해야 하므로 연결지향형이다. ->( UDP는 비연결지향형이므로 핸드셰이크X)
즉, 데이터 전송을 보장하는 파라미터들을 각자 설정하기 위한 어떤 사전 세그먼트들을 보내야 한다.
TCP연결은 회선교환 네트워크에서와 같은 종단 간의 TDM이나 FDM이 아니다.
대신 연결은 두 통신 종단 시스템의 TCP에 존재하는 상태를 공유하는 논리적인 것이다.
TCP 연결은 전이중 서비스(full-duplex service)를 제공한다.
-> 전이중 서비스란 송신과 수신이 동시에 이루어질 수 있는 서비스. TCP는 서버와 클라이언트 간의 양방향 통신이 가능하다.
만약 호스트 A의 프로세스와 호스트 B의 프로세스 사이에 TCP 연결이 있다면 애플리케이션 계층 데이터는 B에서 A로 흐르는 동시에 A에서 B로 흐를 수 있다.
TCP 연결은 항상 단일 송신자와 단일 수신자 사이의 점대점(point-to-point)이다.
따라서 단일 송신 동작으로 한 송신자가 여러 수신자에게 데이터를 전송하는 ‘멀티캐스팅(multicasting)’은 TCP에서는 불가능하다.
TCP 연결 과정은 다음과 같다
한 호스트에서 동작하는 프로세스가 다른 호스트의 프로세스와 연결을 초기화하기를 원한다고 가정한다. 연결을 초기화하는 프로세스를 클라이언트 프로세스, 다른 프로세스를 서버 프로세스라고 부른다.
ClientSocket.connect( (serverName, serverPort))
- 클라이언트 애플리케이션 프로세스는 서버의 프로세스와 연결을 설정하기를 원한다고 TCP 클라이언트에게 먼저 알린다.
- 클라이언트의 트랜스포트 계층은 서버의 TCP와의 TCP 연결 설정을 진행한다. 즉, 클라이언트가 먼저 특별한 TCP 세그먼트를 보낸다.
- 서버는 두 번째 특별한 TCP 세그먼트로 응답한다
- 마지막으로, 클라이언트가 세 번째 특별한 세그먼트로 다시 응답한다.
처음 2개의 세그먼트에는 페이로드(payload, 애플리케이션 계층 데이터)가 없다.
세 번째 세그먼트부터는 페이로드를 포함할 수 있다.
일단 TCP 연결이 설정되면, 두 애플리케이션 프로세스는 서로 데이터를 보낼 수 있다.
- 클라이언트 프로세스는 소켓(프로세스의 관문)을 통해 데이터의 스트림을 전달한다.
- 데이터가 관문을 통해 전달되면, 이제 데이터는 클라이언트에서 동작하고 있는 TCP에 맡겨진다.
- TCP는 초기 세 방향 핸드셰이크 동안 준비된 버퍼 중의 하나인 연결의 송신 버퍼(send buffer)로 데이터를 보낸다.
- 때때로 TCP는 송신 버퍼에서 데이터 묶음을 만들어서 네트워크로 보낸다. TCP가 언제 버퍼된 데이터를 전송해야 하는지는 정해져 있지 않다
세그먼트로 모아 담을 수 있는 최대 데이터 양은 최대 세그먼트 크기(maximum segment size, MSS)로 제한된다.
MSS는 로콜 송신 호스트에 의해 전송될 수 있는 가장 큰 링크 계층 프레임의 길이((최대 전송 단위(maximum transmission unit, MTU))의해 일단 결정되고 TCP 세그먼트와 TCP/IP 헤더 길이( 통상40바이트)가 단일 링크 계층 프레임에 딱 맞도록 정해진다.
MSS가 헤더를 포함한 TCP 세그먼트의 최대 크기가 아니라 세그먼트에 있는 애플리케이션 계층 데이터의 최대 크기
TCP 세그먼트(TCP segment) = TCP 헤더 + 클라이언트 데이터
- 네트워크 계층에 전달되어 네트워크 계층 IP 데이터그램 안에 각각 캡슐화된다.
- 세그먼트는 네트워크로 송신된다.
- TCP가 상대에게서 세그먼트를 수신했을 때, 세그먼트의 데이터는 TCP 연결의 수신 버퍼에 위치한다.
->애플리케이션은 이 버퍼로부터 데이터의 스트림을 읽는다.
- 출발지와 목적지 포트 번호(source and destination port number)
- 체크섬 필드(checksum field)
- 32비트 순서 번호 필드(sequence number field)
- 32비트 확인응답 번호 필드(acknowledgement number field)
- 16비트 수신 윈도(receive window) : 흐름 제어에 사용된다.
(수신자가 받아들이려는 바이트의 크기를 나타내는데 사용됨) - 4비트 헤더 길이 필드(header length field) : 32비트 워드 단위로 TCP 헤더의 길이를 나타낸다.
- 옵션 필드(option field)
- 이 필드는 선택적이고 가변적인 길이를 가진다.
- 송신자와 수신자가 최대 세그먼트 크기(MSS)를 협상하거나 고속 네트워크에서 사용하기 위한 윈도 확장 요소로 이용된다.
- 플래그 필드(flag field) : 6비트를 포함한다.
- ACK 비트 : 확인응답 필드에 있는 값이 유용함을 가리키는 데 사용된다.
- RST, SYN, FIN 비트 : 연결 설정과 해제에 사용된다. RST: restart, FIN = finish
- PSH 비트 : 이 비트가 설정되었다면 이것은 수신자가 데이터를 상위 계층에 즉시 전달해야 함을 가리킨다.
- URG 비트
- 이 세그먼트에서 송신 측 상위 계층 개체가 ‘긴급’으로 표시하는 데이터임을 가리킨다.
- 이 긴급 데이터의 마지막 바이트의 위치는 16비트의 긴급 데이터 포인터 필드(urgent data pointer field)에 의해 가리켜진다.
byte 1개가 1seq#을 가진다.
MSS는 세그먼트 데이터 필드의 크기를 제한한다.
- 큰 파일 전송 시, 일반적으로 MSS 크기로 파일을 분절한다.
- 많은 대화식 애플리케이션은 MSS보다 작은 양의 데이터를 전송한다.
TCP sequence numbers, ACKs
byte 단위
순서대로 정렬되어 있는 바이트 스트림
세그먼트에 대한 순서 번호는 세그먼트에 있는 첫 번째 바이트의 바이트 스트림 번호다. (색깔의 첫번째)
TCP는 스트림에서 첫 번째 잃어버린 바이트까지의 바이트들까지만 확인응답하기 때문에, 누적 확인응답(cumulative acknowledgment)을 제공한다고 한다.
누적된 ACK ->GBN 방식과 흡사.
두 가지 선택지
- 수신자가 순서가 바뀐 세그먼트를 즉시 버린다.
- 수신자는 순서가 바뀐 데이터를 보유하고, 빈 공간에 잃어버린 데이터를 채우기 위해 기다린다.
후자가 네트워크 대역폭 관점에서는 효율적이며, 실제에서도 취하는 방법이다.
Host A(Client) 에서 B(Server)로 갈 때 ACK79가 필요하다고 B가 요청함
Host B에서 A로 다시 갈때 Seq#이79로 되어있음. 그리고 그다음 Ack인 43을 보내고 데이터 C도 같이 보냄
ex) 만약 data가 2개인 경우 CA를 보낸다 가정하면 B에서 A로 갈때 Ack는 44가 된다. Seq#은 그대로 79가 된다.
ex) 만약 data가 10bytes가 될 경우 B에서 A로 갈때 Ack는 52가 된다.
3.5.3 왕복 시간(RTT) 예측과 타임아웃
TCP round trip time, timeout
왕복 시간(round-trip time, RTT) : 세그먼트가 전송된 시간부터 긍정 확인응답될 때까지의 시간
- 너무 짧게 설정하면 미숙한 상태가 되고 그러면 재전송을 해야함.. -> 불필요한 재설정
- 너무 길게 설정하면 대응이 느려지게 됨
SampleRTT: 실제 ACK 시간을 측정한다. segment transmission에서 ACK를 수신할 때 까지 시간을 측정. 재전송은 이때 무시한다.
대부분의 TCP는 한 번에 하나의 SampleRTT 측정만을 시행한다.
- 즉, 어떤 시점에서 SampleRTT는 전송되었지만 현재까지 확인응답이 없는 세그먼트 중 하나에 대해서만 측정된다.
- 이는 대략 왕복 시간마다 SampleRTT의 새로운 값을 얻게 한다.
SampleRTT 값은 라우터에서의 혼잡과 종단 시스템에서의 부하 변화 때문에 segment마다 다르기 때문에
대체로 RTT를 추정하기 위해 SampleRTT 값의 평균값을 채택한다.
아래와 같이SampleRTT값은 변동성이 크다.
DevRTT는 RTT 변화율을 의미한다.
이는 SampleRTT가 EstimatedRTT로부터 얼마나 많이 벗어나는지에 대한 측으로 정의한다.
DevRTT = (1 - β) × DevRTT + β × | SampleRTT - EstimatedRTT |
( β의 값 : 0.25)- DevRTT는 SampleRTT와 EstimatedRTT 값 차이의 EWMA이다.
주어진 EstimatedRTT 와 DevRTT 값에서, TCP 타임아웃 주기에는 어떤 값이 사용되어야 하는가?
- 주기는 EstimatedRTT보다 크거나 같아야 한다.
(그렇지 않다면 불필요한 재전송이 보내질 것) - EstimatedRTT보다 너무 크면 안된다.
(너무 크면 세그먼트를 잃었을 때, TCP는 세그먼트의 즉각적인 재전송을 하지 않게 됨)
->타임아웃값은 EstimatedRTT에 약간의 여윳값을 더한 값으로 설정하는 것이 바람직하다.
TimeoutInterval = EstimatedRTT + 4 × DevRTT -> 0.25 를 보통 쓰기 때문에 x4를 해주는게 일반적이다.
- 초기 TimeoutInterval의 값으로는 1초를 권고한다.
- 타임아웃이 발생할 때, TimeoutInterval의 값은 두 배로 하여
조만간 확인응답할 후속 세그먼트에게 발생할 수 있는 조기 타임아웃을 피하도록 한다
d0의 영향력은 점점 줄어든다=> (1-a)^n이므로 ...
3.5.4 신뢰적인 데이터 전송
data received from applaction
- segment seq#을 만든다.
- 첫번째 segment 일어날때 timer 시작.
- 1개의 타이머가 있다.
time out일땐
- 타임오버 유발 segment 재전송
- 권장되는 TCP 타이머 관리 절차에서는 오직 단일 재전송 타이머를 사용한다.
- 타이머 재시작
ACK received
- 받지 않아도 받은것처럼 window 전진
- SendBase : 수신 확인응답이 확인되지 않은 / 가장 오래된 바이트의 순서번호
- SendBase-1 : 수신자에게서 정확하게 차례대로 수신되었음을 알리는 마지막 바이트의 순서번호
재전송(retransmit)
만약 TCP 송신자가 같은 데이터에 대해 N개의 중복 데이터 을 수신한다면,
이것은 ACK된 세그먼트의 다음 N개의 세그먼트가 분실되었음을 의미한다.
segment의 타이머가 만료되기 이전에 손실 세그먼트를 재전송한다.
아래 그림을 보면 두 번째 세그먼트를 잃어버린 경우, 타이머가 만료되기 전에 재전송되었다.
TCP 확인응답은 누적되고 올바르게 수신되지만,
순서가 잘못된 세그먼트는 수신자가 개별적으로 ACK를 받지 않는다.
TCP 송신자는 전송했지만 확인응답 안 된 바이트의 가장 작은 순서 번호, SendBase와 전송될 다음 바이트의 순서 번호, NextSeqNum을 유지해야 한다.
이런 관점에서 TCP는 GBN 형태의 프로토콜과 비슷해보이나, ’TCP에서는 올바르게 수신되었지만 순서가 바뀐 세그먼트들을 버퍼링한다’는 차이점이 존재한다.
e.g.,
패킷 n < N에 대한 긍정 확인응답이 손실되었지만,
나머지 N-1개의 긍정 확인 응답들은 타임아웃 전에 송신 측에 도달했다고 가정한다.
- GBN : 패킷 n뿐만 아니라, 연속적인 패킷 n+1, n+2, … , N 모두를 재전송한다.
- TCP
- 세그먼트 n 하나만을 재전송
- 세그먼트 n에 대한 타임아웃 전에 세그먼트 n+1에 대한 긍정 확인 응답이 도착한다면 세그먼트를 재전송하지 않는다.
TCP에서 수정제안된 선택적 확인응답(selective acknowledgment) : TCP 수신자가 마지막으로 올바로 수신된 ‘순서가 맞는’ 세그먼트에 대해 누적 확인응답을 하기보다는 ‘순서가 틀린’ 세그먼트에 대해 선택적으로 확인응답을 하게 한다.
이를 선택적 재전송과 결합했을 경우, SR 프로토콜과 매우 유사하다.
1.순서가 맞는 Segment의 도착을 위해 500msec까지 기다린다. 만약 순서에맞는 Segment가 도착하지 않으면 ACK를 그냥 보낸다.
2. 2개의 순서가 맞는 Segment들을 ACK하기위해 하나의 누적된 ACK를 즉시 보낸다.
3.순서번호가 다음의 기다리는 바이트는 중복 ACK를 즉시 보낸다.
4.그 Segment가 격차의 최솟값에서 시작한다고하면 즉시 ACK를 보낸다.
어플리케이션 프로세스는 버퍼에서 데이터를 읽지만 데이터가 도착한 시점에 읽을 필요가 없다.
데이터를 읽는 속도가 느리다면 점점 데이터는 쌓일것이고 수신 버퍼에서는 쉽게 overflow가 생길 것이다.
-> TCP는 송신자가 수신자의 버퍼를 overflow 시키는 것을 방지하기 위해 애플리케이션에게 흐름제어 서비스를 제공
읽는 속도와 전송하는 속도를 같게 해준다.
TCP송신자가 IP네트워크에서 혼잡 때문에 억제될 수 있다. 이 형태는 혼잡 제어로 알려져 있다.
혼잡 제어와 흐름 제어는 비슷한듯 다르므로 잘 구분하여야 한다.
TCP 송신자가 수신 윈도라는 변수를 유지하며 흐름제어를 제공한다.
수신 윈도는 수신측에서 가용한 버퍼 공간이 얼마나 되는지 송신자에게 아려준다.
TCP는 전이중이므로 연결의 각 측의 송신자는 수신 윈도를 유지한다.
하나의 호스트(클라이언트)에서 운영되는 프로세스가 다른 호스트(서버) 안의 또 다른 프로세스와 연결을 시작하길 원한다고 가정하자.
- 클라이언트 애플리케이션 프로세스는 서버에 있는 프로세스와 연결 설정하기를 원한다는 것을 클라이언트 TCP에게 알린다.
- 클라이언트 안의 TCP는 다음과 같은 방법으로 TCP를 이용해 서버와 TCP 연결 설정을 시작한다.
2WAY를 안쓰는 이유
이런 것이 Ddos 공격대상이 될 수 있다.
그렇기 때문에 문제가 생기지 않기 위해 3Way handshake를 사용한다.
- 클라이언트 측 TCP는 서버 TCP에게 특별한 TCP 세그먼트, SYN 세그먼트를 송신한다.
- 애플리케이션 계층 데이터를 포함하지 않는다.
- 세그먼트 헤더에 SYN 비트를 1로 설정한다.
- 클라이언트는 최소 순서 번호(client_isn)를 임의로 선택하고, 최초의 TCP SYN 세그먼트의 순서 번호 필드에 이 번호를 넣는다.
- 이 세그먼트는 IP 데이터그램 안에서 캡슐화되고 서버로 송신된다.
TCP SYN 세그먼트를 포함하는 IP 데이터그램이 서버 호스트에 도착하면,
- 서버는 데이터그램으로부터 TCP SYN 세그먼트를 추출한다.
- 연결에 TCP 버퍼와 변수를 할당한다.
- 클라이언트 TCP로 연결 승인 세그먼트, SYNACK 세그먼트를 송신한다.
- 애플리케이션 계층 데이터를 포함하지 않는다.
- SYN 비트는 1로 설정된다.
- TCP 세그먼트 헤더의 확인응답 필드는 client_isn+1로 설정된다.
- 서버는 자신의 최초의 순서 번호(server_isn)를 선택하고, TCP 세그먼트 헤더의 순서 번호 필드에 이 값을 넣는다.
연결 승인 세그먼트를 수신하면,
- 클라이언트는 연결에 버퍼와 변수를 할당한다.
- 클라이언트 호스트는 서버로 또 다른 세그먼트를 송신한다.
- 클라이언트는 TCP 세그먼트 헤더의 확인응답 필드 안에 server_isn+1 값을 넣어, 서버의 연결 승인 세그먼트를 확인한다.
- 연결이 설정되었기 때문에 SYN 비트는 0으로 설정된다.
세 번째 단계는 클라이언트에서 서버로의 데이터를 세그먼트 페이로드에서 운반할 수 있다.
위의 세 단계가 완료되면,
- 클라이언트와 서버 호스트들은 각각 서로에게 데이터를 포함하는 세그먼트를 보낼 수 있다.
- SYN 비트는 0으로 설정된다.
- 클라이언트 애플리케이션 프로세스는 종료 명령을 내린다.
- 이는 클라이언트 TCP가 서버 프로세스에게 특별한 TCP 세그먼트를 보내도록 한다.
(FIN 비트를 1로 설정) - 서버가 이 세그먼트를 수신하면, 서버는 클라이언트에게 확인응답 세그먼트를 보낸다.
- 그 다음에 FIN 비트가 1로 설정된 자신의 종료 세그먼트를 송신한다.
- 마지막으로 클라이언트는 서버의 종료 세그먼트에 확인응답을 한다.
- 클라이언트와 서버가 각각 연결을 종료하려는 경우:
- 클라이언트와 서버는 각자의 연결을 종료하기 위해 TCP 세그먼트를 보낸다. 이때 FIN 비트를 1로 설정하여 FIN 세그먼트를 보낸다.
- 수신한 FIN에 대한 응답:
- 상대편으로부터 FIN 세그먼트를 수신한 쪽은 ACK 세그먼트를 보낸다. 이것은 FIN 세그먼트를 수신했음을 확인하는 것이다.
- 동시에 FIN을 교환하는 경우:
- 두 시스템이 동시에 연결을 종료하려고 할 때, 둘 다 FIN 세그먼트를 보내고 ACK 세그먼트를 기다린다. 이렇게 함으로써 양쪽의 연결이 안전하게 종료된다.
이러한 과정을 통해 TCP 연결은 정상적으로 종료된.
'컴퓨터 네트워크' 카테고리의 다른 글
컴퓨터 네트워크 3장- 혼잡제어 (0) | 2024.04.21 |
---|---|
컴퓨터 네트워크 3장-혼잡 제어의 원리 (0) | 2024.04.16 |
컴퓨터 네트워크 3장- 신뢰적인 데이터 전송의 원리 (0) | 2024.04.12 |
컴퓨터 네트워크 3장- 비연결형 트랜스포트: UDP (0) | 2024.04.12 |
컴퓨터 네트워크 3장- 다중화와 역다중화 (0) | 2024.04.12 |