[CS]/[컴퓨터네트워크]

전송계층3 - TCP Protocol

broship 2021. 3. 11. 14:14

※kocw에서 제공하는 이석복 교수님의 컴퓨터네트워크 수업을 듣고 필기한 내용입니다.

출처를 따로 밝히지 않는 한 전부 해당 수업에서 제공한 자료들이며 제가 작성한 부분에 있어 틀린 부분이 있을 수도 있다는 점 양해바랍니다.


 

 

TCP 특징


1. point-to-point: 1대1 연결(1 센더 소켓 - 1 리시버 소켓)

2. reliable, in-order byte stream: 전송간 데이터 에러, 유실이 없음

3. pipelined: 한꺼번에 다수의 패킷 전송(윈도우 만큼)

4. full duplex data: 데이터가 양뱡향으로 통신함(받기만 하거나 보내기만 하지 않고 받고 보내고 둘다 함)

5. send & receive buffers: 센더,리시버 둘다 패킷을 임시 보관할 버퍼를 가지고 있음(모두가 센더, 리시버므로 각각 센더용 버퍼, 리시버용 버퍼 총 2개 버퍼 가지고 있음)

6. connection-oriented: 커넥션을 유지하기 위한 3-way handshaking, 4-way handshaking

7. flow controlled: 리시버가 받을 수 있을 만큼만 데이터를 보냄

8. congestion controll: 네트워크가 받을 수 있을 만큼만 데이터를 보냄

 

- TCP의 가장 중요한 기능 3가지

1. reliable data transfer

2. flow control

3. congestion control

 

 

 

TCP segment


 

1. 포트(source port 16비트, dest port 16비트):

- 이론상으로 한 컴퓨터 내에서 동시에 동작할 수 있는 네트워크 포트 개수는 2^16-1(약 6만5천개)

- source port: 센더의 포트 번호

- dest port: 리시버의 포트 번호

2. 주고 받는 데이터 갯수 카운팅(counting by bytes of data)

- sequence number

- acknowledgement number

3. checksum: 에러체크

4. Reveive window: 리시버의 버퍼 크기 알려주는 기능(flow controlled에 필요)

5. 1비트 짜리 데이터

- S: SYN 비트, 처음 tcp 커넥션 연결시 사용

- F: FIN 비트, tcp 커넥션 close 때 사용

 

 

대략적인 TCP 전송방식


- TCP의 동작 방식을 함축적으로 요약한 사진

- TCP도 GBN과 같은 cumulative ACK를 보냄

- 다른점은 ACK10일 경우 9번까지 잘받았다, 10번을 보내달라 라는 뜻

- Seq=42, ACK=79 라는 뜻은 내가 보내는 데이터는 42번째 데이터고, 받아야할 데이터는 79번째 데이터라는 뜻

- 그럼 B는 79번째 데이터를 보내고 43번째 데이터를 보내달라고 보냄

 

 

 

TCP Connection Management(tcp연결, 해제)


TCP 3-way handshake(연결)

- TCP 통신을 위해선 기본적으로 준비되어야 하는것:

1. 각 엣지마다 센더, 리시버 버퍼

2. 센더측 시퀀스 넘버

3. 리시버측 시퀀스 넘버

- 본격적으로 통신을 하기 전에 이런 사전 준비를 하는 과정을 3-way handshake 라고함

- 총 3번의 동작과정이 있어서 3-way handshake

1. 클라이언트가 서버에게 세그먼트 전송

- 데이터는 없이 헤더의 SYN 부분이 1비트로 되어있음

- SYN은 다른때는 0, 처음 연결할때만 1

- SYN이 1이면 tcp 연결하고 싶다 라는 뜻

- 그러면서 자신의 시퀀스 넘버를 보냄

2. 서버가 응답 세그먼트(ACK) 전송

- 똑같이 SYN을 1로, 서버의 시퀀스 넘버를 보냄

- ACK도 1비트로 클라이언트 시퀀스넘버 +1 해서 보냄

3. 클라이언트가 ACK를 보냄

- 이때는 SYN을 다시 0으로

- 서버 시퀀스 넘버+1 한 ACK값을 보냄

- 이때부터 데이터를 포함할 수 있음

 

- 2번을 통해서 client는 ACK를 받게되고, 센더용 버퍼, 리시버용 버퍼 생성함

- 3번을 통해서 server는 ACK를 받게되고, 센더용 버퍼, 리시버용 버퍼 생성함

- 이러한 과정을 통해 버퍼도 생기고, 서로의 시퀀스 넘버도 알게됨, reliable한 데이터 전송이 가능해짐

 

 

Closiong TCP Connection(해제)

- client가 먼저 데이터를 다 보내면 클라이언트는 먼저 close

1. SYN과 똑같이 FIN의 1bit를 담아서 보냄(평소엔 0)

2. 서버는 계속 ACK 보내다가 서버도 데이터를 다 전송했으면 FIN을 전송

3. 클라이언트는 서버 FIN의 대한 ACK를 보내고, 일정시간 기다림(timed wait)

4. 서버가 마지막 ACK를 받으면 서버도 close, 이때 ACK를 못받으면 다시 FIN 보냄(서버가 마지막 ACK를 못 받을 경우를 대비해서 클라이언트가 FIN을 받고 일정시간 기다리는 것임)

- 총 4번의 동작 과정이 있어서 4-way handshake라고도 함

 

TCP Connection Lifecycle

 

 

 

TCP의 reliable data transfer


- TCP의 특징:

1. 파이프라인 방식 (한꺼번에 많은 패킷 전송)

2. Cumulative ACK (ACK10: 9번까지 잘받았다 10번 보내라)

3. 타이머가 하나뿐임(GBN과 달리 하나 터지면 전체 윈도우를 다시 보내는 것이 아닌 터진 세그먼트만 재전송)

 

타이머 시간을 resonable하게 맞추기:

- 데이터가 전송되어 ACK가 돌아오는데 까지 걸리는 시간을 RTT(Round-Trip Time) 이라고함

- 타이머를 RTT와 똑같이 맞출경우 오차범위가 너무 커짐

- RTT를 보정한 EstimateRTT에 4*DevRTT 만큼 더해줘서 넉넉하게 타이머를 잡음

 

TCP 재전송 시나리오

1. 센더는 타임아웃되면 재전송

2. 리시버가 보낸 ACK가 유실되서 중복된 패킷을 재전송 해도 리시버는 제일 최신 ACK 전송

3. 센더는 받은 최신 ACK에 판단하여 전송

 

- 항상 타임아웃될때까지 기다렸다가 재전송하는것은 비효율적임

- 센더는 중복된 ACK를 3개더 전달받으면 해당 패킷은 유실되었다고 판단하고 해당 패킷 재전송

- 이걸 "fast retransmit" 이라고함(필수 사항은 아닌 성능이 더 좋아지는 권고사항)

 

- 센더가 재전송하는 2가지 경우:

1. 타임아웃

2. 중복된 ACK 3개 더 받을경우

 

 

 

TCP의 flow control(흐름제어)


- TCP는 파이프라인 방식으로 한꺼번에 많은 데이터를 보낼 수 있음

- 이때 센더가 리시버가 받을수 있는 속도만큼 보내주는 것이 flow control

- 리시버가 센더에게 보내는 세그먼트 해더 중 Receive window라는 칸에 남은 버퍼의 사이즈를 담아서 전달함

- 센더는 세그먼트 헤더를 받은 후 리시버의 남은 버퍼 사이즈만큼만 데이터를 보냄

 

리시버의 버퍼가 차는 이유:

- 버퍼가 차는 이유는 단순히 유실된 데이터가 있어서 그 다음 데이터를 담는 용도로만 사용되지 않음

- 리시브 버퍼에서 애플리케이션 계층으로 올리는 속도와도 연관이 있음

 

이때 주의사항:

- 리시브 버퍼가 가득 차면 receive window에 0바이트 남았다고 보냄

- 리시브 버퍼가 0이라서 센더가 아무것도 보내지 않을경우, 리시버는 데이터를 받지 않으면 ACK를 보내지 않기에 리시브 버퍼가 다시 공간이 생겨도 센더는 알수있는 방법이 없음

- 그래서 센더는 리시브 버퍼가 0이어도 1바이트씩 데이터를 보냄

 

 

 

 

TCP의 Congetion control


 

- 센더가 데이터를 보낼때 참고해야할것:

1. 네트워크가 받아드릴수 있는 양

2. 리시버가 받아드릴수 있는 양

이 둘중에서 크기가 작은 양에 맞춰서 보내야됨

- flow control을 통해 리시버가 받아드릴수 있는 양은 정확히 알수가 있음

- 하지만 네트워크는 무형이기 때문에 어느정도 받아드릴수 있는지 알수 없음

- 그걸 해결하는것이 congetion control

 

- tcp의 경우 네트워크 상황을 고려하지 않고 전송을 하면 점점 악화됨:

네크워크 과부하가 걸리면 패킷이 더많이 유실됨, 그럼 센더는 패킷이 계속 유실되니까 계속 재전송할수밖에 없음 -> 그러면 더 많은 과부하가 걸림

tcp를 그대로 놔두면 이런 악순환이 반복되니, 어떻게든 네트워크 상황에 맞게 전송하는 양을 줄여야됨

 

- congetion control 가능 하는 방법 2가지

1. Network-assisted congetion control: 네트워크가 직접 네트워크 상황을 알려준다

2. End-end congetion control: 양 끝의 엣지(서버와 클라이언트)가 알아서 네트워크 상황을 유추해서 보내는 속도를 조절한다

- 라우터는 아무런 기능을 가지고 있지 않기 때문에 1번은 구현이 불가능하기 때문에 2번 방법을 사용함

 

- 리시버의 피드백을 통해 네트워크 상황을 유추하고, 속도를 조절하는데 사용되는 3 main phases:

1. Slow Start: 처음에는 네트워크 상황을 모르기 때문에 맨 처음에는 아주 조금씩만 보냄, 하지만 증가폭은 크게(2배씩)

2. Additive increase: 일정 부분을 지나면 증가폭을 줄임, 처음에는 아주 작게 시작했기 때문에 증가폭을 크게 가져가도 되지만 너무 커지면 네트워크 과부화를 불러 일으킬수있기 때문에 일정 부분 지나고 나서는 증가폭을 조금씩만 가져감

3. Multiplicative decrease: 이렇게 증가폭을 늘리다가 데이터 유실이 발행하면 데이터 전송량을 반으로 줄임, 그리고 다시 1번부터 시작함

 

- 이때 전송하는 세그먼크 크기를 MSS라고 함

- MSS (Maximum Segment Size) = 500 Byte

 

TCP에서 사용하는 방식:

x축: 시간 y축: 보내는 패킷양

1) TCP Series1 Tahoe 방식(하늘색, 예전버전)
- 처음에 1개의 패킷만을 보냄(slow start)

- 성공시마다 2배로 증가

- Threshold 지점을 만나면 증가폭을 줄임(Additive increase)

- 데이터 유실이 발생되면 다시 slow start부터 시작(Multiplicative decrease)

- Threshold 지점을 데이터 유실이 발생한 지점 윈도우 사이즈 절반지점으로 옮김

- 다시 Additive increase 시작(리니어 인크리즈라고도 함)

 

2) TCP Series2 Reno 방식(검은색, 최신버전)

- slow start, threshold는 같음, 데이터 유실때 대처가 다름

- 데이터 유실에는 1.타임아웃, 2. 3개 중복된 ACK 받음이 있음

1. 타임아웃은 네트워크 과부화가 걸려 전체 패킷이 안간상태

2. 3개 중복된 ACK는 다른건 잘갔는데 하나의 패킷만 전송이 안된 상태

- 이때 TCP는 1번일 경우 Tahoe 방식과 똑같이 처음부터 시작함(엄중한 상태)

- 2번일 경우 Threshold는 낮추고 그 지점부터 시작함(덜 엄중한 상태)

 

 

 

TCP fair


- 각 엣지는 데이터 전송을 위해 네트워크 자원을 공유하고 있는데, 이 네트워크 자원이 공평하게 분배될까?

하나의 네트워크에 2개의 커낵션이 연결되어있을때

- x축은 커넥션1의 사용량

- y축은 커넥션2의 사용량

- 이때 두 선이 만나는 지점이 가장 공평한 지점임

- 여기서 tcp방식 그대로 증가하다가 줄이고를 반복하면 저절로 가운데 지점 근처에서 왔다갔다함