이 포스트는 널널한 개발자님 강의를 참조하여 작성한 포스트입니다.
TCP 연결 절차에 대해 이야기할 때 3-way-handshaking이 늘 등장한다. 연결이라는 것이 결론이라면 그 연결의 과정으로 등장하는 것이 3-way-handshaking이다.
위 그림처럼 어떤 client가 있다면 접속 대기중인 서버에 접속을 할 것이다. 위 그림의 세로 선을 timeline이라고 하고 어느 시점에 클라이언트가 192.168.0.20:80번의 서버와 연결을 하고자 한다. 여기서 클라이언트가 서버에 갔다가 돌아오는 시간을 RTT라고 하는데 50ms정도 걸린다고 하면 서버까지 가는 시간을 25ms, 돌아오는 시간을 25ms라고 가정하자. 이때 통신되는 단위가 Segment인데 일반적으로 Segment는 payload와 TCP-header로 구성되어 있지만 3-way-handshaking은 TCP-header만 존재한다. 즉, 이런 형태의 관리목적 Segment가 왔다갔다 한다.
연결을 하려는 클라이언트 측에서 서버와 연결을 하고자 먼저 Sequence Number를 생성한다. 이 번호는 랜덤으로 생성이 되는데 예를들어 1000번이 생성이 되었다면 연결하는 서버한데 SYN(1000)을 보낸다. 즉, 클라이언트는 SYN_SENT를 한다. 그러면 서버는 연결가능 상태이면 Sequence Number를 랜덤생성하고 그게 4000이라고 하면 SYN(4000) + ACK(1001)을 클라이언트에 보낸다. 이걸 보내기 전에 소켓으 listening 상태로 변해야 한다. 그러면 클라이언트가 잘 받았다고 서버한테 ACK(4001)을 보낸다. 중요한것은 여기서 시간차가 존재하는데 이 시간차가 무엇이냐면 클라이언트가 연결을 시도해서 ACK를 받는 순간 클라이언트는 서버와 연결되었다고 판단한다. 하지만 이 시점 서버는 클라이언트와 연결이 안되었다고 생각한다. 단방향 RTT에 25ms가 지나면 ACK(4001)을 클라이언트가 보낸다. 이 ACK를 서버가 받은 시점에 서버는 드디어 클라이언트와 연결되었다고 생각한다.
여기서 연결과정에 중요한것은 정책을 교환한다는것인데 정책중에는 위에서 언급한 Sequence Number가 존재하고 더 중요한 것은 MSS가 어느정도인지를 알려준다. 여기서 클라이언트와 서버의 MSS가 같으면 문제 없지만 클라이언트 MSS보다 서버 MSS가 작을때는 클라이언트의 MSS를 서버의 MSS의 맞춘다.
결론으로 연결이라는 것은 이런 관리적 정보, 프로토콜이 규정하는 정보를 교환하는 것이다.