컴퓨터가 다른 컴퓨터와 통신을 하기 위한 규약(프로토콜)의 일종이다. OSI 모형에서 4번째 계층인 전송 계층(Transport Layer)에서 사용하는 규약으로 보통 하위 계층에서 사용하는 IP와 엮어서 TCP/IP로 표현하는 경우가 많다. 동일 계층에서 사용하는 또 다른 프로토콜로는 UDP가 있다.
TCP의 연결은 3번 내지 4번의 패킷이 오고 가야 성립한다. 이를 TCP 3-way Handshake & TCP 4-way Handshake라고 한다.
1. 클라이언트는 서버에 접속을 요청하는 SYN(a) 패킷을 보낸다.
2. 서버는 클라이언트의 요청인 SYN(a)를 받고 클라이언트에게 요청을 수락한다는 ACK(a+1)와 SYN(b)이 설정된 패킷을 보낸다.
3. 클라이언트는 서버의 수락 응답인 ACK(a+1)와 SYN(b) 패킷을 받고 ACK(b+1)를 서버로 보내게 된다. 이 과정까지 끝나면 연결이 성립한다.
(ACK는 a신호를 받았을 때 그 신호를 잘 받았다는 확인 메세지와 같은 개념으로 ACK(a+1)의 형태로 보내는 패킷이다.)
연결을 성립시키기 위해서는 이렇게 3번의 패킷 교환이 일어나야 한다.
1. 클라이언트가 연결을 종료하겠다는 FIN 플래그를 서버에 보낸다.
2. 서버는 클라이언트의 요청(FIN)을 받고 확인 메세지로 ACK를 보낸다.
(데이터를 모두 보낼 때까지 잠시 TIME_OUT 상태가 된다.)
3. 데이터를 모두 보내고 통신이 끝나면 연결이 종료되었다고 클라이언트에게 FIN 플래그를 보낸다.
4. 클라이언트는 FIN 패킷을 확인했다는 ACK를 서버에 보낸다.
5. 클라이언트의 ACK를 받은 서버는 소켓 연결을 Close한다.
6. 클라이언트는 서버로부터 아직 받지 못한 데이터가 있을 것을 대비해 일정 시간동안 세션을 남겨놓고 잉여 패킷을 기다리는 과정을 거친다. (TIME_WAIT)
연결을 해제하기 위해서는 이렇게 4번의 패킷 교환이 일어나야 한다. 이렇게 TCP의 연결과 해제를 보면 두 과정 모두 어떤 패킷을 받았을 때에 ACK 패킷을 다시 보내줘야 하고 연결, 해제를 한쪽 마음대로 할 수 없다는 것을 알 수 있다.
TCP Header에는 Code Bit(Flag Bit)가 존재한다. Code Bit는 6Bit로 이뤄져 있고, 각 Bit마다 의미를 가지고 있다.
Urg - Ack - Psh - Rst - Syn - Fin
SYN 패킷은 synchronize sequence number의 약자이다. SYN Packet의 TCP Header는 000010
이다.
ACK 패킷은 acknowledgement의 약자로 어떤 패킷을 받았을 때 그 패킷을 성공적으로 받았다는 의미에서 보내는 패킷이다. TCP Header는 010000
이다.
TCP에서의 연결과 연결 해제에는 2가지 타입의 패킷이 필요하다. 그 이유는 간단하다. 이 과정에서는 서로 통신이 가능한지, 혹은 해제가 가능한지를 먼저 파악하기 위해 패킷을 주고 받는다고 생각하면 쉽게 이해할 수 있다. 이에 따라서 요청과 응답에 대한 패킷을 주고 받아야 하기 때문에 2가지의 타입의 패킷이 필요하다.
요청과 응답에 대한 패킷이 필요하다고 바로 전에 설명을 했다. 그렇다면 왜 2번이 아닌 3번의 패킷 교환이 일어나야 하는 것일까? 이에 대한 답으로는 "TCP connection은 양방향성 connection이기 때문"
이라고 답할 수 있다. 클라이언트에서 서버에게 존재를 알리고 패킷을 보낼 수 있다는 것을 알리는 것처럼 서버에서도 클라이언트에게 존재를 알리고 패킷을 보낼 수 있다는 것을 알려야한다. 쉽게 설명하면 클라이언트가 서버에게 연결 요청을 보냈을 때 서버가 클라이언트에게 연결을 허가한다는 패킷과 함께 "너의 요청을 잘 받았어"라는 ACK를 같이 보내게 되고, 클라이언트는 허가 패킷을 받으면 "너의 허가 패킷을 잘 받았어"라는 ACK를 서버에게 보내줘야 하기 때문에 3번의 패킷 교환이 필요하다.
클라이언트가 서버에게 연결 요청을 보낼 때 SYN 패킷을 보낸다. 이때 SYN 패킷에는 Sequence number가 부여되는데 연결 요청과 같은 첫 패킷에 부여되는 초기 Sequence number를 ISN이라고 한다. 이때의 ISN은 난수로 지정된다. 연결을 맺을 때 사용하는 포트는 유한 범위 내에서 사용하고 시간이 지남에 따라 재사용된다. 그렇기 때문에 두 통신 호스트가 과거에 사용된 포트 번호를 쌍을 사용하게 되는 경우가 발생할 수 있다. 서버 측에서는 패킷의 SYN을 보고 패킷을 구분하는데 난수가 아닌 순차적인 수가 전송된다면 이전의 연결에서 오는 패킷을 인식하게 될 수도 있다. 이 때문에 ISN은 난수로 설정된다.