TCP 통신과정에서 데이터를 전송하기 위해서는 먼저 연결상태, 가상의 통신로를 확보해야 한다.
그 가상의 통신로를 확보하기 위해서 3-way-handshake 라는 과정을 거치게 된다
TCP 헤더중 6비트로 구성된 코드비트가 있는데
3way ,4way handshake, 비정상 종료 등등
TCP의 연결 확립 과정과 연결 종료 과정에서 TCP 헤더의 플래그(코드비트) 가 중요한 역할을 한다.
해당 플래그를 확대해서 보면 URG, ACK, PSH, RST, SYN, FIN 이라는 비트들이 각각 1비트로 구성된다
각각 Urgent, Acknowledgement, Push, Reset, Synchronize, Finish 의 약자이다.
해당 비트에 대한 설명은 아래와 같다.
URG | Urgent Pointer(긴급 포인터) 필드에 값이 채워져 있음을 알리는 플래그. 이 포인터가 가리키는 긴급한 데이터는 높게 처리되어 먼저 처리된다 |
ACK | Acknowledgment(승인 번호) 필드에 값이 채워져 있음을 알리는 플래그. 이 플래그가 0이라면 승인 번호 필드 자체가 무시된다. |
PSH | Push 플래그. 수신 측에게 이 데이터를 최대한 빠르게 응용프로그램에게 전달해달라는 플래그. 이 플래그가 0이라면 수신 측은 자신의 버퍼가 다 채워질 때까지 기다린다. 즉, 이 플래그가 1이라면 이 세그먼트 이후에 더 이상 연결된 세그먼트가 없음을 의미하기도 한다. |
RST | Reset 플래그. 이미 연결이 확립되어 ESTABLISHED 상태인 상대방에게 연결을 강제로 RESET 해달라는 요청의 의미이다. |
SYN | Synchronize 플래그. 상대방과 연결을 생성할 때, 시퀀스 번호의 동기화를 맞추기 위한 세그먼트임을 의미한다. |
FIN | Finish 플래그. 상대방과 연결을 종료하고 싶다는 요청인 세그먼트임을 의미한다. |
3way ,4way handshake 에서 이 코드비트가 활용이 된다.
초기값은 0인 비트들이 각 과정에서 활성화 되면서 값이 바뀌어 전송이 된다.
TCP 연결을 시작하기 위해서는 3-way handshake 기법이 필요하다.
아래와 같이 TCP 연결 요청을 하는 client 측과 응답을 해주는 Server 측이 있다고 가정해보자.
양측은 TCP 통신을 위해서 연결을 확립하는 과정이 필요하다.
1. SYN(seq = x)
클라이언트는 서버와 연결하기 위해 SYN 을 보낸다.
송신자가 최초로 데이터를 전송할 때 Sequence Number를 임의의 숫자로 지정한 뒤에
SYN 플래그 비트를 1로 설정한 세그먼트를 보내준다.
송신자 측이 세그먼트를 보내준 순간부터 해당 세그먼트에 대한 응답을 기다리는 상태가 된다.
2. SYN(seq = y), ACK(seq = x + 1)
서버측에서는 클라이언트에서 보내준 세그먼트를 받고
응답의 의미로 송신된 세그먼트 seq 값의 1을 더해준 ACK 를 송신지 측으로 전해준다.
또한, 서버측도 연결을 의미하는 요청으로 SYN 을 보내준다.
이때도 마찬가지로 Sequence Number를 임의의 숫자로 지정한 뒤에
SYN 플래그 비트를 1로 설정한 세그먼트를 보내준다.
또한 서버측에서는 송신자 측이 해당 응답에 대한 요청을 보낼 때까지 대기하는 상태가 된다.
3. ACK(seq = y + 1)
클라이언트에서 서버에서 보내준 세그먼트의 정보를 읽고
마지막으로 서버에 연결 요청에 대한 수락확인으로 해당 세그먼트 SYN seq
값에 1을 더해줘서 ACK 즉 응답데이터를 보내준다.
이로써 클라이언트 측에서는 서버와 연결이 되었다고 받아 들인다.
또한 해당 ACK 세그먼트를 서버측에서 문제 없이 받았다면
서버도 클라이언트와 연결이 되었다고 받아들인다.
TCP 연결을 시작하기 위해 3-way handshake 기법을 사용하였다면,
TCP 연결을 해제하기 위해서는 4-way handshake 기법이 필요하다.
1. FIN (Client -> Server)
클라이언트와 서버가 연결된 상태에서 클라이언트가 close() 를 호출하여 접속을 끊을 준비를 한다.
이때 클라이언트는 서버측에게 접속을 끝는다는 의미의 Flag 인 FIN 을 보내준다.
또한, FIN 에 대한 응답을 대기하는 상태가 된다. => FIN_WAIT 상태
2. ACK (Server -> Client)
서버는 FIN Flag 를 받고 확인했다는 ACK Flag 가 포함된 세그먼트를 클라이언트에게 보내준다.
해당 응답을 보내고 서버는 CLOSE_WAIT 상태에 들어가게 된다.
그리고 아직 남은 데이터가 있다면 마저 전송을 끝마치고 close()를 호출하여
서버도 클라이언트와 마찬가지로 접속을 끊을 준비를 한다.
3. FIN (Sever -> Client)
서버측에서 남은 모든 데이터 처리를 전송 완료 하였다면,
서버는 연결 종료한다는 의미로 FIN Flag 가 포함된 세그먼트를 클라이언트에게 보내준다.
그리고 해당 세그먼트에 대한 응답을 대기하는 LAST_ACK 상태가 된다.
4. ACK (Client -> Server)
클라이언트는 서버로 부터 송신된 FIN 을 받고 확인했다는 ACK 를 서버로 다시 보내준다.
아직 서버로부터 받지 못한 데이터가 있을 수 있으므로 TIME_WAIT 상태에 들어간다.
이때 TIME_WAIT 상태는 의도하지 않은 에러로 인해 연결이 데드락으로 빠지는 것을
방지하는 역할을 수행한다.
에러가 발생하여 종료가 지연되더라도 일정 시간이 초과되면 자연스럽게
Closed 상태로 변경된다.
그리고 서버는 클라이언트 측에서 보내준 ACK 신호를 받고 소켓을 닫아준다. (Closed)
TIME_WAIT 시간이 끝나게 되면 클라이언트 측도 소켓을 닫아준다.(Closed)
'네트워크' 카테고리의 다른 글
[네트워크] TCP 흐름제어 - Sliding window (0) | 2022.10.06 |
---|---|
[네트워크] ARQ (0) | 2022.10.05 |
[네트워크] TCP header (0) | 2022.10.03 |
[네트워크] 전송계층의 정의 (0) | 2022.10.02 |
[네트워크] ICMP (0) | 2022.10.01 |