3-way handshake & 4-way handshake

TCP Header

Source Port : 출발지 포트번호
Destination Port: 목적지 포트번호
Sequence Number: byte 단위로 순서화되는 번호
Acknowledgment Number: 수신되길 기대하는 다음 byte 번호 (마지막으로 수신에 성공한 번호 x + 1)
Offset : 헤더 길이 필드
Window: 자신의 수신 버퍼 여유용량 크기를 통보해 얼마만큼의 데이터를 받을 수 있는지 알려주어 흐름제어를 수행할 수 있는 필드
TCP Flag
URG - ACK - PSH - RST - SYN - FIN
해당 위치의 bit가 1이면 해당 패킷이 어떠한 내용을 담고 있는 패킷인지 나타낸다.
SYN (Synchronize Sequence Number) - 000010
연결 설정 - Sequence Number를 랜덤으로 설정하여 세션을 연결하는 데 사용
ACK (Acknowledgement) - 010000
응답확인 - Acknowledgement Number필드가 유효한지 확인
FIN (Finish) - 000001
연결 해제 - 세션 종료 시 사용하며 더 이상 전송할 데이터가 없음을 의미

3-way handshake

TCP 통신을 이용하여 데이터를 전송하기 위해 네트워크 연결을 설정(Connection Establish) 하는 과정
정확한 전송을 보장하기 위해 사전에 세션을 수립하여 양쪽 모두 데이터 전송이 준비되었다는 것을 확인 ⇒ 신뢰성 보장

매커니즘

클라이언트는 ACK를 받을 때까지 데이터 유닛을 전송한다.
→ 서버는 checksum을 사용하여 세그먼트의 손상 여부를 확인하고 손상이 되었다면 해당 세그먼트를 없앤다.
→ 클라이언트는 positive ACK이 오지 않은 세그먼트를 다시 재전송한다.

1. SYN

클라이언트(프로세스 A)에서 서버(프로세스 B)로 연결 요청 (seq: x)
프로세스 A가 최초로 데이터를 전송할 때 Sequence Number를 임의의 랜덤 숫자로 지정
TCP Flag의 SYN 비트를 1로 설정한 세그먼트를 전송한다.

2. ACK + SYN

SYN(seq: x)를 받은 서버는 클라이언트로 받았다는 신호로 ACK(x + 1)와 SYN(seq: y) 패킷을 전송
서버(프로세스 B)가 요청을 수락하고 클라이언트(프로세스 A)도 포트를 열어달라는 메세지를 전송해야함.
ACK Number필드는 SYN(seq: x)를 받았다는 의미로 x + 1로 지정
TCP Flag의 SYN, ACK 비트를 1로 설정한 세그먼트를 전송한다.

3. ACK

클라이언트는 해당 패킷을 받고 ACK(y + 1)를 서버로 전송하여 수락 확인을 보내 연결을 맺음
ACK Number필드는 SYN(seq: y)를 받았다는 의미로 y + 1로 지정
전송할 데이터가 있다면 이 단계에서 데이터를 전송할 수 있음

4-way handshake

TCP 통신 연결을 해제 (Connecntion Termination)하는 과정

1. FIN

클라이언트와 서버가 연결된 상태에서 클라이언트가 close()를 호출하여 접속을 끊으려함
클라이언트는 서버에 연결을 종료한다는 FIN( + ACK) 비트를 1로 설정한 세그먼트를 전송한다.

2. ACK

서버는 FIN을 받고 확인했다는 ACK를 클라이언트에게 전송한 뒤 자신의 통신이 끝날 때까지 기다림 ⇒ TIME_WAIT
서버는 클라이언트에게 응답을 보내고 CLOSE_WAIT 상태에 들어가고, 아직 남은 데이터가 있다면 마저 전송을 마친 후에 close( )를 호출
클라이언트는 ACK를 받은 후, 서버가 남은 데이터 처리를 끝내고 FIN 패킷을 보낼때까지 기다림 ⇒ FIN_WAIT_2

3. FIN

데이터를 모두 보냈다면 서버가 연결 종료에 합의한다는 의미로 FIN 패킷을 전송 후, 승인 번호를 보내줄 때까지 기다림 ⇒ LAST_ACK

4. ACK

클라이언트는 FIN을 받고 확인했다는 ACK를 서버에게 보냄
클라이언트는 아직 서버로부터 받지 못한 데이터가 있을 수 있으므로 TIME_WAIT를 통해 기다림
TIME_WAIT는 의도치 않은 에러로 인해 연결이 데드락으로 빠지는 것을 방지하기 위함.
타임 초과되면 클라이언트도 CLOSED로 들어감
서버는 ACK를 받은 이후 소켓을 닫는다.