- TCP 통신을 이용해 데이터를 전송하기 위해 3-way Handshake로 네트워크 연결을 설정(Connection Establish)하는 과정
- 클라이언트와 서버 모두 데이터를 전송할 준비가 되었다는 것을 보장하고, 실제 데이터 통신이 이루어지기 전에 한 쪽이 다른 쪽에 준비되었다는 것을 알 수 있도록 함(신뢰성)
- 즉, TCP/IP 프로토콜을 이용해 통신을 하는 응용 프로그램이 데이터를 전송하기 전에 정확한 전송(신뢰성)을 보장하기 위해 상대방 컴퓨터와 사전에 세션을 수립하는 과정
- 클라이언트와 서버 모두 상대편에 대한 초기의 순차 일련번호를 얻을 수 있음
- 클라이언트가 서버에게 접속을 요청하는 SYN 패킷을 전송
- SYN 플래그 비트를 1로 설정하고 메시지를 서버로 전송
- 클라이언트는 SYN을 보내고 서버로부터 SYN/ACK 응답을 기다리는 SYN_SENT 상태
- 서버는 클라이언트로부터 SYN요청을 받고 클라이언트에게 요청을 수락한다는 ACK와 SYN flag가 설정된 패킷을 발송한 후 클라이언트가 다시 ACK응답을 보내기를 기다림
- 서버는 SYN과 ACK 플래그 비트를 1로 설정하고 메시지를 클라이언트에게 전송
- 서버는 SYN/ACK을 보내고 SYN_RCV 상태
- 클라이언트는 다시 서버에게 ACK을 보낸 후 연결이 이루어지고 데이터의 통신이 이루어짐
- ACK 플래그를 1로 설정하고 SYN 플래그는 0으로 유지
- 이때 서버의 상태는 ESTABLISHED
- 위와 같이 클라이언트와 서버가 통신을 하기 전 신뢰성있는 연결을 맺어 준다는 것이 TCP의 3-way Handshake
- 3-way Handshake는 TCP의 연결을 초기화 할 때 사용한다면, 4-way Handshake는 세션을 종료하기 위해 수행하는 절차
- 클라이언트가 서버로 FIN 플래그를 전송
- FIN 플래그를 1로 설정하고, 임의의 시퀀스 번호와 함께 메시지를 서버로 전송
- ACK는 0으로 설정
- 서버는 클라이언트로부터 FIN을 받고 응답 패킷인 ACK을 보냄
- 클라이언트의 종료 요청을 수신한 후 ACK 플래그를 1로 설정하여 승인 메시지를 클라이언트에게 전송
- ACK의 acknowledgement number을 수신한 sequence number + 1로 지정
- 서버가 연결을 종료하려면 FIN 플래그를 1로 설정하고 클라이언트에게 전송
- 클라이언트는 서버에서 FIN을 수신한 후 ACK 플래그를 1로 설정하고 서버의 sequence number + 1로 ACK의 acknowledgement number을 설정한 후 서버로 전송
- 위 단계를 완료한 후 서버에서도 클라이언트측으로의 연결이 종료
* TIME_WAIT: Server에서 FIN을 전송하기 전에 전송했던 패킷이 Routing 지연이나 패킷 유실로 인한 재전송 등으로 인해
FIN 패킷보다 늦게 도착하는 데이터 유실을 막기 위해 Client는 Server로부터 FIN을 수신하더라도 일정시간(디폴트 240초)
동안 세션을 남겨놓고 잉여 패킷을 기다리는 과정(즉, 데이터의 유실 방지)
// TCP Header 안 플래그 정보
* SYN(Synchronization): 상대에 대한 접속 요청
* ACK(Acknowledgement): 상대의 통신 응답
* FIN(Finish): 연결 해제, 세션 연결을 종료시킬 때 사용, 더 이상 전송할 데이터가 없음을 의미함
* SYN_SENT: 클라이언트가 직접 서버에게 시퀀스 번호을 생성하여 SYN 패킷에 담아 보냄
- SYN(seq = m)
* SYN_RCV: 클라이언트로부터 SYN패킷을 받은 서버는 자신만의 시퀀스 번호를 생성하고 SYN 패킷에 담아 클라이언트의 SYN 패킷에 있는 시퀀스 번호에 +1을 더한 후 ACK 패킷에 담아서 같이 보냄
- SYN(seq = n), ACK(ack = m+1)
* (Client) ESTABLISHED: 서버로부터 SYN + ACK 패킷을 받은 클라이언트는 ACK 패킷의 시퀀스 번호를 보고 자신이 보낸 시퀀스 번호와 차이가 1임을 확인함
차이가 1이라면 제대로 연결되었다고 판단하고, 서버의 SYN 패킷에 있는 시퀀스 번호에 +1을 더한 후 ACK 패킷에 담아 보냄
- SYN(ack = n+1)
* (Server) ESTABLISHED: 클라이언트의 ACK 패킷을 받고 패킷에 존재하는 시퀀스 번호가 이전에 보낸 SYN 패킷의 시퀀스 번호 + 1과 동일하다면 연결이 되었다고 판단함
- ACK(ack = n+1)
// 포트(PORT) 상태 정보
* CLOSED: 포트가 닫힌 상태
* LISTEN: 포트가 열린 상태로 연결 요청 대기 중
* ESTABLISHED: 포트 연결 상태
- https://mindnet.tistory.com/entry/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EC%89%BD%EA%B2%8C-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-22%ED%8E%B8-TCP-3-WayHandshake-4-WayHandshake
- https://afteracademy.com/blog/what-is-a-tcp-3-way-handshake-process
- https://gmlwjd9405.github.io/2018/09/19/tcp-connection.html