이번 포스팅에서는 TCP의 주된 기능인 Flow control과 3 / 4 Way-Handshake에 대해서 살펴보겠습니다.
1. 흐름 제어(Flow Control)
데이터를 전송할 때, 짧은 시간에 많은 데이터를 보낼 수록 좋을 것만 같지만, 실제로는 그렇지 않습니다. 송신자에서 많은 데이터를 보내도, 수신자에서 그것을 처리할 수 없다면 많은 데이터들이 버려지게 됩니다.
그래서 수신자가 처리할 수 있는 용량을 송신자에게 피드백을 해주어야 합니다. 이를 위해 recv 버퍼의 크기를 기록해 전송하게 됩니다.
다시 TCP 세그먼트 구조를 살펴보겠습니다. 그림을 보면 4번째 줄에 Receive window가 있는 것을 볼 수 있습니다. 이것이 바로 현재 남은 recv버퍼의 크기를 가르킵니다.
만약 수신자의 recv 버퍼가 꽉 찼다면 송신자는 데이터를 전송하지 않습니다. 송신자는 수신자의 recv 버퍼를 보고 남은 공간 만큼 데이터를 맞춰 보냅니다.
이렇게 전송자의 데이터 양을 조절하여, 수신자의 버퍼가 넘치지 않게 조절하는 것을 흐름 제어(Flow Control)이라고 합니다.
그런데 만약 receiver가 보내온 recv 버퍼 값이 0 이라면 어떻게 될까요?
송신자는 상대에게 공간이 생길 때까지 기다려야할 것입니다. 그런데 마냥 대기만 하고 있는다면, 빈 공간이 생겼어도 송신자는 그 상황을 알 방법이 없습니다.
따라서 TCP는 이런 상황에 주기적으로 segment를 수신자로 보내는 대신, data 부분은 없거나 아주 적은 양(1바이트)으로 보내게 됩니다. 이렇게 세그먼트를 전송해야 receiver에게 공간이 생겼을 때 피드백을 받을 수 있기 때문입니다.
결국 흐름 제어(Flow control)는 수신자가 얼마나 공간이 남았는지를 직접 알려주기 때문에 구현이 단순합니다.
2. TCP 3 / 4 - Way Handshake
(1) 연결 설정(Connection management)
TCP 통신 과정에서는 세그먼트의 순서가 중요합니다. 그래서 Seq #(Sequence number; 시퀀스 번호)가 필요합니다.
이전 포스팅에서 TCP는 기본적으로 양방향 통신이라는 것을 다루었습니다.
만약 A의 send 버퍼에서 데이터를 전송하면 B의 recv 버퍼가 데이터를 받습니다. 따라서 A의 send 버퍼의 Seq #는 B의 recv 버퍼의 Seq #와 같습니다.
반대로 B의 send 버퍼에서 데이터를 전송하면 A의 recv 버퍼가 받습니다. 따라서 B의 send 버퍼의 Seq #는 A의 recv 버퍼의 Seq #와 같습니다.
네트워크 통신에서 이러한 과정이 이루어지기 위해서는 데이터를 회선을 따라 보내기만 하면 되는 것이 아니라, 버퍼(send buf, recv buf)를 만들어주고 서로 상대에게 Seq #를 알려주는 작업이 필요합니다.
이러한 사전 준비 작업이 이루어져야만 Network edge 간에 통신이 정상적으로 이루어집니다. 이러한 준비 작업을 하는 것을 연결 설정(Connection management)이라고 합니다.
TCP에서도 송신자와 수신자는 데이터 세그먼트를 주고받기전에 연결 설정을 진행해야합니다. 여기서 TCP 3/4 Way-handshake 개념이 등장합니다.
(2) TCP 3 - Way Handshake (연결)
TCP 에서는 클라이언트와 서버 간의 연결을 구축하기 위해 3 Way-handshake 방법을 사용합니다. 3 Way-handshake는 논리적으로 연결이 된 것을 확인하는 것입니다.
우선 이론적인 설명 이전에, 그림으로 쉽게 이해를 해보겠습니다.
두 컴퓨터가 서로 연결을 하기 위해서는 A에서 B에게 보내는 연결 요청과 그에 대한 응답. 그리고 B가 A에게 보내는 연결 요청과 그에 대한 응답으로 구성되는 것을 볼 수 있습니다. 서로 간에 요청과 피드백을 받으면 논리적으로 연결되었다는 것이 확인이 되는 것입니다. 이것을 세번 악수하는 과정으로 생각하는 것입니다.
여기서 요청과 응답에 해당하는 비트는 다시 세그먼트 헤더에서 찾을 수 있습니다.
세그먼트 헤더의 4번째 줄을 보면 U, A, P, R, S, F를 볼 수 있습니다. 여기서 A는 ACK, S는 SYN, F는 FIN 비트를 의미하는 것입니다. 이 비트를 통해 상태를 주고 받습니다.
이제 위 그림을 이론적으로 살펴보겠습니다.
이제 연결 요청은 SYN, 확인 피드백은 ACK로 대입한다면 위 그림을 쉽게 이해할 수 있습니다. 왼쪽의 컴퓨터가 클라이언트, 오른쪽의 컴퓨터가 서버입니다.
(1) SYN
클라이언트는 1비트의 SYN 메시지와 클라이언트의 Seq#을 서버에 알려줍니다. 이때 보내는 패킷에는 데이터가 없습니다. 클라이언트는 SYNACK의 응답을 대기하는 SYN_SENT 상태가 됩니다.
(2) SYN / ACK
서버가 성공적으로 SYN 요청을 받았다면 요청을 수락한다는 ACK와 SYN 플래그가 존재하는 패킷을 클라이언트에게 다시 보냅니다. 이때 서버는 SYN_RECEIVED 상태가 됩니다.
(3) ACK
클라이언트는 서버가 보낸 SYN에 대한 ACK을 패킷에 담아 서버에 전송합니다. 이제부터 SYN 필드는 1비트가 아니라 0을 보내고, 연결이 이루어져 데이터가 오갈 수있기 때문에 ACK를 전송하면서 Application data도 함께 전송할 수 있습니다.
(3) TCP 4 - Way Handshake (연결 종료)
4 - way handshake는 연결한 상태를 해제하기 위해 필요한 과정입니다.
이 과정도 먼저 그림으로 쉽게 살펴보면 아래와 같습니다.
여기서의 연결 종료 요청은 FIN, 그리고 확인은 ACK로 이루어집니다.
추가로 TCP의 연결 종료 과정이 연결 설정 때보다 한 단계 더 필요한 이유는 TCP가 전이중(Full-Duplex), 점대점(Point-to-Point) 통신을 제공하기 때문입니다. 즉, 각 방향의 데이터 전송이 독립적으로 종료될 수 있게 하기 위해서입니다.
한 쪽에서 데이터 전송이 완료되어 연결을 종료하고자 할 때, 다른 쪽은 아직 데이터를 전송 중일 수 있습니다. 따라서, 연결 종료 요청과 수락 과정이 각 방향마다 독립적으로 이루어져야 하기 때문에 4 Way-Handshake가 필요한 것입니다.
다시 이론적인 그림으로 살펴보면 아래와 같습니다.
4 Way-Handshake는 다음과 같은 과정을 통해서 이루어 집니다.
(1) FIN
클라이언트가 연결을 종료하겠다는 TCP FIN을 서버로 전송합니다.
(2) ACK
서버가 FIN을 확인하고, 피드백으로 ACK를 보냅니다.
(3) FIN
서버도 통신을 끝낼 준비가 되면 FIN을 클라이언트로 전송합니다. 그러면 클라이언트가 FIN을 받고 이에 대한 ACK를 서버로 전송합니다.
(4) ACK
서버가 ACK를 받게되면, TCP 연결이 종료됩니다.
여기서 클라이언트의 Timed wait 상태인 동안에는 연결 종료(FIN)을 받고도 어느 정도 시간 동안은 종료를 하지 않습니다.
왜냐하면 클라이언트에서 보낸 ACK가 유실되는 상황이 생길 수 있기 때문입니다. 클라이언트가 보낸 ACK가 유실되면 서버는 다시 FIN을 보내는 데, 만약 클라이언트가 닫혀있으면 서버는 닫지 못하는 상황이 발생할 수 있습니다. 이를 방지하기 위해, 클라이언트는 뒤늦게 도착하는 패킷을 기다리는 Timed-wait을 가지고 있습니다.
참고자료
[컴퓨터 네트워크 - 한양대학교 이석복 교수님]
http://www.kocw.net/home/cview.do?cid=6166c077e545b736
https://the-square-of-y.tistory.com/215
TCP 3way handshake, 4way handshake - 예술하는 개발자
https://www.youtube.com/watch?v=gPsSLwaFhYo
https://dev-nicitis.tistory.com/26
Computer Networking _ A Top Down Approach, 7th
'CS > Network' 카테고리의 다른 글
[네트워크] 네트워크 계층 : Internet Protocol(IP) (0) | 2024.02.19 |
---|---|
[네트워크] TCP Congestion Control (0) | 2024.02.17 |
[네트워크] 전송 계층 : TCP (0) | 2024.02.15 |
[네트워크] Pipelined Protocol (0) | 2024.02.12 |
[네트워크] RDT(Reliable Data Transfer) (0) | 2024.02.11 |