애플리케이션 레이어에서 전송하는 데이터 단위

메세지 (Message)


트랜스포트 레이어에서 전송하는 데이터 단위

세그먼트 (Segment)


네트워크 레이어에서 전송하는 데이터 단위

패킷 (Packet)


TCP 에서 SendBuffer & ReceiveBuffer

TCP 는 각각의 엔드포인트가 센더이면서 리시버, 그렇기 때문에 각각의 엔드포인트에는 버퍼가 두 개씩 존재한다. (Send Buffer / Receive Buffer) 

Send Buffer

- 애플리케이션 계층에서 내려온 메세지가 담긴다.

- 세그먼트를 통해서 보낸 데이터가 유실되었을 경우를 대비하여 보관하고 있다. 만약 패킷 유실이 판단되었을 경우에는 재전송을 실시한다. 이후에 데이터가 정상적으로 전송되면 해당 데이터는 삭제한다.

- TCP 자체는 하나씩 데이터를 보내기 때문에 비효율적이다. 따라서 Pipelined 통신을 실시하고 이렇게 한번에 데이터를 보낼 수 있는 것은 window size가 작용하기 때문이다. 그리고 해당 window size 만큼의 데이터는 피드백 없이 한번에 전송한다.


Receive Buffer

- send Buffer 에서 받은 데이터의 순서를 맞추기 위한 용도로 버퍼가 필요하다. 그리고 이런 순서를 맞추기 위해서는 sequence number 를 사용한다. (센더가 데이터를 보내는 패킷에는 바이트 데이터에 대한 sequence number 가 부여되어 있기 때문이다.)

- 패킷유실의 유무는 타이머를 통해서 알 수 있으며, 타이머가 만료될때까지 피드백이 오지 않는다면 패킷유실이라고 판단한다. 하지만 타이머의 만료시간을 기다릴때까지는 효율성이 떨어지기에 같은 ACKs 의 sequence number 를 중복해서 3번 받으면 패킷을 재전송한다. 이 중복된 내용을 3-duplicate ACKs라 하고 재전송하는 것을 Fast Re-Transmit 이라고 말한다.

  • Re-Transmit

    • 3 - Dupliated ACKs (Fast Re-Transmit)

    • Timeout

TCP 에서 제공하는 세가지 주요한 기능

(1) Reliable Data Transfer (패킷 재전송을 통한 신뢰성있는 통신)

(2) Flow Control (리시버의 가용 능력)

(3) Congestion Control (중간 네트워크 혼잡 유무)


window size 를 조절하는 것이 결국 속도를 조절하는 것이다. 센더의 window size 는 아래의 내용을 따른다.


Send Window = min ( flow control window, congestion control window )

Send Window = min ( cwnd, rwnd )


cwnd :: congestion window 의 줄임말

rwnd :: receiving window 의 줄임말


하지만 하드웨어 스펙이 높아져서 대부분의 window size 는 네트워크의 상황을 반영한다.


Silly WIndow Syndrome

센더측의 애플리케이션이 데이터를 늦게 생성하거나 혹은 리시버측의 처리가 늦어져서 window 크기를 작게하여 센더측은 데이터를 전송한다. 아래의 그림처럼 1byte 의 데이터만 전송한다. 그리고 리시버측의 버퍼가 가득차고 이후 리시버측은 처리가 또 늦어지고 작은 데이터만을 처리하게 된다. 이 과정이 계속 반복된다면 잦은 낭비가 발생하고 리시버측에서도 데이터를 기다리기에 불완전한 상황이 된다. 이런 현상을 silly window syndrome 이라고 말한다. 



Nagle's Algorithm

처음 TCP 는 데이터가 있으면 1Byte 라도 전송한다. 그 이후 세그먼트를 만들고 데이터를 버퍼에 채우면서 보낼 준비를 한다. 여기서 보내는 센더는 데이터를 전송하는 가짓수를 두가지로 나눌 수 있다. 버퍼에 최대 사이즈만큼 가득 찬 경우 혹은 앞에서 보낸 세그먼트의 ACKs 를 받은 경우이다.

  • 세그먼트가 다 채워지기 이전에 ACKs 가 도착 → 네트워크의 상태가 좋음

  • 세그먼트가 다 채워질 때 까지 ACKs 가 미도착 → 데이터 전송 (세그먼트가 가득 찼기 때문에)

결과적으로 세그먼트 사이즈를 어떻게 해서 보낼 것인가는 데이터 전송 사이즈를 최대로 해서 보낼 것인가 혹은 덜 채워서 보낼 것인가로 나뉘게 된다. 그래서 같은 양의 데이터를 전송하더라도 데이터의 전송횟수를 줄이는 효과를 가져온다. 

여기서 의문은 실시간성 게임의 경우에 해당 네이글 알고리즘의 사용에 대해 생각해보자. 반응이 즉각적으로 필요한 게임에서 네이글 알고리즘이 과연 필요한 것인지에 대해.


Connection Management : 3-Way HandShaking

three-way handshaking 은 TCP Connection 을 맺기위해 사용하는 절차이다. 이 절차는 하나의 TCP 에서 시작되어 또다른 TCP에 의해서 응답된다. 




위의 그림이 두 TCP 장비가 통신하기 위한 절차를 표로 나타낸것이다. TCP A가 생성한 ISN (Initial Sequence Number) 를 TCP B 로 전송하고, SYN FLAG 는 1로 설정되어서 보내진다. 그림에서는 100번이 부여된 패킷을 전송한다. 


이후에 TCP B 는 SYN-RECEIVED 가 되며, TCP A가 보낸 SYN에 반응하여 ACKnum을 수신한 SEQ + 1로 만든다. 이후 잘 받았음을 ACK FLAG 를 1로 설정된 패킷을 보낸다. 그리고 TCP B가 ISN을 SYN FLAG 를 1로 설정하여 패킷을 전송한다.


위 그림에서 빨간 점선 테두리만큼은 가장 기본적은 3-way handshaking 방식이다. 


결국 TCP A 와 TCP B 사이에 ISN 을 주고 받는 것이다.


(1) 송신측에서 수신측으로 연결 요청을 하기 위해 SYN Flag 가 1 로 설정된 패킷을 전송한다.


(2) 수신측에서 특정 포트는 LISTEN 상태가 되어있으며 SYN Flag 가 1인 데이터를 받고 SYN-RECEIVED 상태가 된다. 이후 송신측의 연결 요청을 정상적으로 받았다는 응답으로 ACK 와 함께 송신측의 포트도 같이 열어달라는 SYN Flag 1 로 설정된 패킷을 보낸다.


(3) 송신측에서 ACK 와 함께 SYN 패킷을 받아 ESTABLISHED 상태로 변경하고, 수신측에 다시 정상적으로 받았다는 응답인 ACK 를 다시 전송한다. 수신측은 이를 받고 ESTABLISHED 상태로 변경된다.


TCP Closing a connection

CLOSE 는 사실 " 더 이상 보낼 데이터가 없음 " 을 의미한다. 그래서 통신을 끝내고 네트워크를 끊는 절차이다. 



가장 초기에는 서로 통신을 하고 있는 상태이기 때문에 ESTABLISHED 이다.


간단히 클라이언트와 서버라고 칭하자. 표현에 따라서는 Active Close 와 Passive Close 라고 구분짓기도 한다. 참고링크


(1) close 를 실행한 클라이언트가 FIN 을 보내고 FIN-WAIT-1 상태로 대기한다.


(2) 서버는 CLOSE-WAIT 상태로 바꾸고, ACK 를 전달하며 동시에 해당 포트에 연결되어 있는 애플리케이션에게 close 를 요청한다.


(3) ACK 를 받은 클라이언트는 상태를 FIN-WAIT-2 로 변경한다.


(4) close 요청을 받은 서버 애플리케이션은 종료 프로세스를 진행하고, FIN 을 클라이언트에게 보내면서 LAST-ACK 상태로 변경한다.


(5) FIN 을 받은 클라이언트는 ACK 를 서버에게 다시 전송하고 TIME-WAIT 로 상태를 바꾸며 TIME-WAIT 에서 일정시간이 지나면 CLOSED 된다. ACK 를 받은 서버도 포트를 CLOSED 로 닫는다.


추가적으로 알아야할 것들)

- Simultaneous Connection Synchronization

- Recovery from Old Duplicate SYN

- Simultaneous Close Sequence

http://tech.kakao.com/2016/04/21/closewait-timewait/



Posted by doubler
,