인터넷 프로토콜, 즉 인터넷 규약이라는 의미다.
CS를 공부하다보면 프로토콜이라는 용어가 자주 등장하는데 약속, 규약 정도로 생각하면 된다.
비유하자면 대한민국의 주소 프로토콜은 '충청북도 청주시 복대동..'이지만
미국의 주소 프로토콜은 '21 Main ST., Carson City, Nevada'이라 할 수 있다.
이게 다르면 한국인이 미국 주소를 보고 집을 찾아가기 힘들 것이다.
그런데 우리는 힘들 뿐이지 찾아갈 수 있는 반면
융통성 없는 컴퓨터는 찾아갈 수조차 없는 문제가 생긴다.
이 문제를 해결하기 위해 인터넷 주소에 대해 만든 규약이 IP인 것이다.
IP에는 v4, v6가 있는데 보통은 IPv4가 널리 쓰인다.
IPv4의 일반적인 형태는 아래와 같다.
IPv4 양식
255.255.255.255
한 구간에 0부터 255까지의 숫자가 들어갈 수 있다고 하는데
이 주소가 꽉 차버려서 만든 주소 양식이 IPv6다.
IPv6 양식
2001:0db8:3c4d:0015:0000:0000:1a2f:1a2b
v4와 v6에는 주요한 차이가 있긴 한데
여기서는 이렇게 생긴 게 IP라는 것만 정리하고 넘어간다.
IP가 주소 규약이라면 TCP는 택배 규약(?)이다.
비유하자면 A 주소에서 B 주소로 택배를 발송할 때 어떻게 택배를 주고받을 것인가에 대한 규약 정도?
현실에서 와닿지는 않지만 우리는 택배를 주고 받을 때
특히 택배를 받는 한국인 입장에서는
정도의 과정을 거쳐 택배를 받게 된다.
와닿지는 않지만 굳~이 비유하자면 이런 과정을 정해놓은 것인데..
그냥 이런 규약이 있다는 것 정도로만 이해한 후 TCP/IP를 사용하여 네트워크 안에서 어떻게 데이터가 오고가는지 과정을 이해하는 것이 더 중요하다.
Client와 Server가 데이터를 주고 받기 위해서는 먼저 입을 맞춰야 한다.
Client가 데이터를 주기 전에 데이터를 주겠다고 Server 측에 말해야 하고,
Client가 더 줄 데이터가 없다면 Server에게 이제 연결을 끊겠다고 말해야 한다.
이때 Handshaking 절차를 밟는다.
Client가 데이터를 주겠노라 Server에게 말하는 절차는 3단계로 이루어진다.
이걸 3-Way Handshaking이라 한다.
편의상 Client와 Server를 C와 S라 칭하겠다.
C가 S에게 접속을 요청하는 SYN 패킷을 보낸다.
이때 C는 SYN를 보낸 후 SYN_SENT 상태로 변경된다.
S는 SYN를 받고 C에게 요청을 수락하는 ACK와 SYN 패킷을 발송한다.
이때 S는 다시 C의 ACK를 기다리는 SYN_RECEIVED 상태로 변경된다.
C는 S에게 ACK를 보내고 연결이 완료된다.
C가 ACK를 보내면서 ESTABLISHED,
S가 ACK를 받으면서 ESTABLISHED 상태로 변경된다.
데이터를 주고 받을 수 있게 된다.
이제 C는 S에게 모든 데이터를 전송했다.
S에게 볼 일이 없어진 C는 이제 연결을 해제해야 한다.
이 절차는 4단계로 이루어지고 이 과정을 4-Way Handshaking이라 한다.
C가 연결을 종료하겠다는 FIN 플래그를 S에게 보낸다.
이때 C는 FIN_WAIT1 상태로 변경된다.
S는 FIN 플래그를 받고 일단 ACK를 보낸다.
그리고 자신의 통신이 끝날 때까지 기다리는데 CLOSE_WAIT 상태가 된다.
S는 자신의 통신이 정리되면 정리되었다는 FIN 플래그를 S에게 보낸다.
그리고 LASK_ACK 상태가 된다.
C는 FIN 플래그를 받고 해지 준비가 되었다는 ACK를 S에게 보낸다.
이때 C는 마지막으로 TIME_WAIT 상태가 되고,
S는 ACK를 받은 후 CLOSED 된다.
C는 ACK를 보낸 후 바로 CLOSED 되지 않고 TIME_WAIT로 잠시 대기했다가 CLOSED된다.
그런데 정말 자세히 따져보면 의문점이 몇개 생긴다.
적어도 두 개 정도는 상식적인 의문인데..
초급 의문:
왜 연결 설정 과정과 연결 종료 과정이 각각 3단계, 4단계로 다른가?
고급 의문:
만약 Server에서 FIN 플래그를 전송하기 전에 전송한 패킷이 어떤 이유로 FIN 패킷보다 늦게 도착한다면 어떻게 되는가?
그에 대한 답변은 이렇다.
Client가 데이터 전송을 마쳤다고 해도 Server는 아직 보낼 데이터가 남아있을 수 있다.
그래서 FIN에 대한 ACK만 보내고
(헤어지자고? 알았어. 잠시만 마음의 정리를 할 시간이 필요해.)
데이터를 모두 전송한 후 자신도 FIN 플래그을 보내는 것이다.
(OK. 헤어지자.)
가능한 상황이다.
그래서 Client는 FIN 플래그를 수신하더라도
일정시간 동안 세션을 남겨놓고 잉여 패킷을 기다리는 상태를 거친다.
이것이 TIME_WAIT 상태다.
(헤어졌다.. 근데 혹시 내가 준 선물을 돌려주지 않을까? <- 개쓰레기)
상당히 이론적인 내용이다.
그런데 유저 입장에서 중요한 건 C와 S가 어떻게 통신하건 그건 알 바가 아니고
결국 Client와 Server가 어떤 상태인지 아는 게 더 중요하다.
4-Way에 상태가 더 있긴 한데 결국 여기서도 중요한 상태는..
CLOSED, LISTEN, ESTABLISHED가 가장 중요하다.
bash 명령어의 netstat으로 해당 상태를 확인할 수 있으니 적극 애용하자.
이상으로 TCP/IP에 대한 이론적인 설명은 끝.