💬 TCP
인터넷 상에서 데이터를 메세지의 형태로 보내기 위해 IP와 함께 사용하는 프로토콜이다.
특징
- 신뢰적이고 연결 지향성 서비스를 제공하며 패킷의 추적 및 관리를 하는 역할이다.
- 연결형 서비스로 신뢰적인 전송을 보장하기 위해 handshake를 진행한다.
- 연결 시 : 3-way Handshake를 진행
- 연결 해제 시 : 4-way Handshake를 진행
- 흐름제어와 혼잡제어를 수행하게 되지만 이 때문에 속도 측면에서는 아쉬운 면이 있다
- 전 이중 방식, 점대점 방식이 있다.
TCP-HEADER(With 플래그 정보)
패킷에는 어떤 패킷이 새로운 시도이고 기존 통신에 대한 응답인지 구분해야 했습니다. TCP Header에는 Code bit(Flag bit)라는 부분이 존재한다. 이 부분은 6bit로 구성되어 있고 각 bit는 서로 다른 의미를 가지고 있다
사진에서 빨간색 네모로 그려져있는 부분을 봐야한다. 저것이 플래그들이다.
- 우리가 보낸 패킷이 ACK라면 010000
- 우리가 보낸 패킷이 SYC라면 000010
이런식으로 표시가 되는 것이다. 그럼 각각의 플래그 정보들을 알아보자.
- SYN(Synchronize Sequence Number)
- TCP에서 세션을 성립할 때 가장 먼저 보내는 패킷이다. Sequence Number를 랜덤으로 설정해서 세션을 연결할 때 사용된다. 물론 초기에 번호를 전송하게 된다
- ACK(Acknowledgement)
- 상대방으로 부터 패킷을 받았다는 사실을 알려주는 용도의 패킷이다. 다른 플래그와 같이 출력되는 경우가 많고 받은 사람 시퀀스 번호에 TCP 계층에서 길이 또는 데이터 양을 더한 것과 같은 ACK을 보낸다.
- ACK 응답을 통해 보낸 패킷에 대한 성공, 실패를 판단해서 재전송하거나 다음 패킷을 전송하게 된다.
- RST(Reset)
- 재설정을 하는 과정이며 양방향에서 동시에 일어나는 중단 작업이다. 비정상적인 세션 연결 끊기에 해당한다. 이 패킷을 보내는 곳이 현재 접속하고 있는 곳과 즉시 연결을 끊고자 할때 사용한다.
- PSH(Push)
- 텔넷과 같은 상호작용이 중요한 프로토콜의 경우 빠른 응답이 중요한데, 이때 받은 데이터를 즉시 목적지인 OSI 7 Layer의 Application 계층으로 바로 전송하도록 해준다. 대화형 트래픽에 사용되는 것으로 버퍼가 채워지길 기다리지 않고 데이터를 전달한다. 데이터는 버퍼링 없이 바로 위 계층이 아닌 7계층의 응용프로그램으로 전달된다.
- URG(Urgent)
- Urgent pointer 유효한 것인지를 나타낸다. Urgent pointer란 전송하는 데이터 중에서 긴급히 전달해야 하는 내용이 존재하는 경우에 사용하고, 긴급한 데이터는 다른 데이터에 비해 우선순위가 당연히 높아야 한다.
- FIN(Finish)
- 세션 연결을 종료시킬때 사용한다. 더이상의 데이터는 없다 라는 뜻이다.
💬 3-way-handshake
3-way-handshake는 TCP/IP 프로토콜을 이용해서 통신을 하는 응용프로그램이 데이터를 전송하기 전에 먼저 정확한 전송을 보장하기 위해 상대방 컴퓨터와 사전에 세션을 수립하는 과정을 의미한다.
이때 3번의 패킷 전송을 거치게 되면서 붙은 이름이 3-way-handshake이다
사진을 보면 양쪽 모두 데이터 전송 준비가 완료되었고 실제로 데이터를 전송하기 전에 3-way-handshake를 하는 과정이다.
그렇다면 간단하게 사진에서 나오는 용어를 정리해보자
- CLOSED : 포트가 닫힌 상태
- LISTEN : 포트를 열고 요청을 대기하는 상태
- SYN-SENT : 응답을 기다리는 상태
- SYN-RECEIVED : SYNC 요청을 받고 상대방의 응답을 기다리는 중
- ESTABLISHED : 포트가 연결된 상태
이렇게 적혀있는 내용을 대충 봤고 그럼 과정을 한 번 그려보자
과정
1. Client → Server : TCP SYN
Client가 Server에게 접속을 요청하는 SYN 플래그를 전송한다.
클라이언트는 SYN/ACK을 기다리는 SYN_SENT 상태가 되고 서버는 Wait for Client 상태가 된다.
2. Server → Client : TCP SYN, ACK
server는 Listen 상태에서 SYN이 들어온것을 확인하고 SYN_RECEIVED 상태로 바뀌면서 SYN + ACK 플래그를 Client에게 전송하게 된다. 그 후 server는 다시 ACK 플래스를 받기 위해 대기 상태로 전환한다.
3. Client → Server : TCP ACK
SYN + ACK 을 받은 Client는 서버에게 ACK을 보내고 연결 성립(Established)가 된다
이렇게 총 3번의 핸드쉐이크을 거쳐 연결을 맺는 것을 3-way-handshake라고 한다.
왜 3번 일까?
왜 2번만 해서 확인하면 되는걸 굳이 다시 Client가 응답을 또 하면서 까지 횟수를 늘리게 된걸까 바로 TCP의 양방향성 연결 특성때문이다. 주고받고 마지막에 한번더 클라이언트가 안심하고 서버에게 패킷을 보내는 과정이 필요해지는 것이다.
💬 4-way-handshake
3-way-handshake가 연결을 위해 진행된 과정이라면 4-way-handshake는 연결(세션)을 종료하기 위해 수행하는 과정이다.
여기서 특이한 점은 3-way-handshake와는 다르게 FIN이라는 플래그를 사용한다는 것이다.
과정
1. Client → Server : FIN
클라이언트는 서버에게 연결을 종료하겠다라는 FIN 플래그를 전송한다. 그 후 FIN-WAIT 1 상태로 변경된다.
- 이때 FIN 패킷에는 ACK 또한 포함되어있다.
- 종료할때는 close()를 호출하여 접속을 끊는다.
2. Server → Client : ACK
서버는 FIN을 받고, 확인했다는 ACK을 클라이언트에게 보내고 서버내에서의 통신이 끝날때 까지 기다린다.
- 그 후 서버는 CLOSE-WAIT 상태로 변경되고 똑같이 close()를 호출하는데 만약 남은 데이터가 있다면 마저 전송을 마친 후에 전송한다.
- 클라이언트는 ACK을 받은 후에 서버가 남은 데이터 처리를 끝내고 보내는 FIN 패킷을 기다린다.(FIN-WAIT 2)
3. Server → Client : FIN
남은 데이터를 모두 보냈다면 서버는 연결이 종료에 합의한다는 의미로 FIN 패킷을 클라이언트에게 보낸 후에 승인 번호를 보내줄 때까지 기다리는 LAST_ACK 상태로 들어간다.
4. Client → Server : ACK
클라이언트는 서버에게로 부터 FIN을 받고 확인했다는 마지막 ACK을 보내게 된다.
- 하지만 혹시 못받은 데이터를 위해 TIME_WAIT를 통해 다시 기다린다.
- 이것은 의도치 않은 에러로 인해 연결이 데드락으로 빠지는 것을 방지한다.
- 혹여 에러가 났다고 하더라도 종료가 지연되다가 타임이 초과되면 CLOSED로 들어간다
이렇게 남은 데이터를 모두 전송하는 과정까지 끝내고 또다시 클라이언트에서 마지막 확인작업(ACK)을 보낸 후에 마무리 하게 된다.
💬 추가적인 질문
❓ 질문 1.
TCP의 연결 설정 과정과 연결 종료 과정의 횟수가 차이 나는 이유는 뭘까?
Client가 데이터 전송을 마쳤다 하더라도 Server는 아직 보낼 데이터가 남아있을수 있다 때문에 일단 FIN에 대한 ACK만 보내는 과정이 추가된다. 그 후 데이터를 모두 전송한 후에 자신도 FIN 플래그가 담긴 패킷을 보내게 되는 것이다.
❓ 질문 2.
만약 Server에서 FIN 플래스를 전송하기 전에 전송한 패킷이 Routing 지연이나 패킷 유실로 인한 재전송 등으로 인해 FIN 패킷보다 늦게 도착하는 상황이 발생하면 어떻게 될까?
이것은 클라이언트에서 진행한 TIME_WAIT에서 답이 나온다. TCP는 이러한 현상을 대비해서 클라이언트는 서버로 부터 FIN을 받는다 하더라도 일정시간 동안 문을 닫지 않고 열어놓는다. 그것이 혹여 유실되거나 지연으로 인해 늦게 도착하는 나머지 데이터를 받을 수 있는 방법이다.
❓ 질문 3.
초기에 시퀀스 번호를 0이 아닌 난수로 지정한 이유가 뭘까?
연결을 진행할때 사용하는 포트는 유한 범위 내에서 사용되고 시간이 지나면서 재사용된다. 따라서 두개의 호스트가 과거에 사용된 포트 번호 쌍을 사용하는 가능성이 존재하게 되는데 서버는 패킷의 SYN을 보고 패킷을 구분하게 된다.이때 혹여 겹치는 SYN 번호가 온다면 이미 연결된 상태인 곳으로 부터 오는 요청이라고 착각할 수 있다. 이러한 문제를 줄이기 위해 난수로 지정한다.
'CS > 🖥 네트워크' 카테고리의 다른 글
🖥 TCP 와 UDP의 차이 (0) | 2023.09.16 |
---|---|
🖥 TCP 혼잡 제어(AIMD, Slow Start, Fast Recovery, Fast Retransmit) (1) | 2023.09.16 |
🖥TCP의 흐름제어, 오류제어(Stop-And-Wait, Go-Back-N, Selective Repeat) (0) | 2023.09.16 |
🖥 RESTful API (0) | 2023.08.03 |
🖥 CORS (0) | 2023.08.02 |