ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 5. 파이프라인 프로토콜, TCP
    공부/컴퓨터 네트워크 2022. 5. 24. 17:13
    반응형

    이 글은 Computer Networking: A Top-Down Approach 7th를 읽고 정리한 글입니다.


     

     

     

    1. 파이프라인된 신뢰적 데이터 전송 프로토콜


    rdt 3.0의 경우에는 왼쪽 그림과 같이 데이터 패킷을 보내면 패킷을 받기전까지 아무일도 하지 않는다. 그래서 속도가 느리다는 단점이 있는데, 파이프라인 프로토콜은 패킷을 1개만 보내지 않고 한 번 보낼 때 여러개를 보내는 것이다.

     

    왼쪽이 sender이고, 오른쪽이 receiver인데, 송신측에서 한 번에 패킷을 여러개 보낸다. 이후 패킷을 보낸 처음 데이터가 ACK을 sender에게 보내면 두번째 패킷을 한 번에 보내게 된다. 이런 과정을 반복한다.

     

    파이프라인 프로토콜에서도 오류가 생길 수 있는데, 이것을 처리하는 방법에 따라 프로토콜 모델이 Go-Back-N(GBN)과 Selective Repeat(SR)등이 있다.


    1.1 N부터 반복(Go-Back-N, GBN)

    GBN 프로토콜에서 송신자는 확인 응답을 하지 않고, 여러 패킷을 전송할 수 있다.

    이때 패킷의 수는 아직 확인응답을 받지 못한 패킷의 최대 허용 수 N보다 크지 말아야 한다.

     

    1) sender는 아직 ack를 받지 않은 패킷을 최대 N개까지 파이프라인에 가질 수 있다.

    2) receiver는 무조건 누적된 ack만 보낼 수 있다. (ack 5이면 5번 패킷까지는 잘 받았다는 뜻)

    3) sender는 가장 오래된 ack를 받지 않은 패킷에 대해 타이머를 사용한다.

     

    위 사진은 전송을 하는 중간을 포착한 그림이다.

    초록색은 이미 ack를 받은 패킷

    노란색은 전송하였지만, ack를 받지 않은 패킷

    파란색은 윈도우 내부에 있어서 사용할 수 있지만, 아직 전송하지 않은 패킷 (= ack를 받지 않은 패킷)

    흰색은 윈도우 바깥에 있어서 전송할 수 없는 패킷

     

    여기에 있는 윈도우 내부에 있는 것이 아직 ack를 받지 않은 패킷이므로 N값으로 제한을 뒀다.

    왜 제한을 둔 것이라면 나중에 흐름제어와 혼잡제어에서 배우게 된다.

     

    만약 패킷 유실 같은 이유로 순서가 잘못 들어온 패킷이 들어온다면 꼬인 패킷부터 모두 버리게 된다.

    위 그림에서 알다시피 pkt2가 유실을 했으므로 pkt3을 보낸다. 이때 ack의 값이 3으로 나와야 하지만 ack3이전에 ack2가 아닌 ack1이었기 때문에 ack2를 건너뛰었음을 알게된다. 그래서 나머지 pkt4, pkt5도 보낸뒤에 다시 pkt2부터 보낸다.

    이 과정이 비효율적이지만, 상위 계층에 데이터를 전달해야하기 때문에 순서가 잘못되면 패킷을 전부 버릴 수 밖에 없으므로 꼬인 패킷부터 모두 버려서 순서가 꼬이지 않게 한다.

     

    GBN의 큰 단점은 바로 위 내용처럼 패킷 하나의 오류 때문에 많은 패킷을 재전송하므로 너무 불필요한 작업을 많이하게 된다. 그래서 이것을 해결한 것이 SR 모델이다.


    1.2 선택적 반복(Selective Repeat, SR)

    선택적 반복 프로토콜은 수신자에서 오류가 발생한 패킷만을 다시 재전송하므로 불필요한 작업을 피하게 만든다.

    여기서는 GBN 모델과 다르게 ACK 5를 받으면 다른 패킷은 모르겠고, 5번 패킷은 정상적으로 잘 받았다는 뜻이 된다.

     

    만약 패킷 1, 패킷 2, 패킷 3, 패킷 4, 패킷 5를 보냈을 때, ACK 1, ACK 3, ACK 4, ACK 5를 받았다고 해보자

    그러면 중간에 패킷 2이 유실되었으니 패킷 3과 패킷 4, 패킷 5은 버퍼에 저장해둔다.

    이후 패킷 2을 다시 보내고 버퍼에 있던 패킷 3과 패킷 4, 패킷 5를 붙여서 상위 계층에 전달을 하게 된다.

     

    이것을 그림으로 보면 아래와 같다.

    하지만 선택적 반복(SR)에서도 문제점이 있다.

     

    윈도우 크기가 3이고, 패킷 번호가 0, 1, 2, 3만 있는 상황이 있다고 예시를 들어봅시다.

    그러면 처음엔 패킷 0, 패킷 1, 패킷 2를 보냈는데 ACK 0, ACK 1, ACK 2가 모두 유실됐다고 했을 때, 패킷 0부터 다시 보내게 되는데, 여기서 상황이 두가지로 나뉘게 된다.

    1) ACK 0, ACK 1, ACK 2 패킷을 유실해서 패킷 0부터 보내는 것인지?

    2) ACK 0, ACK 1, ACK 2 패킷은 정상적으로 받았지만, ACK 3이 손실된 상태로 다음 번호인 패킷 0을 보내는 것인지?

    그래서 패킷 번호는 윈도우 크기보다 두 배는 넘도록 해야한다고 한다.


     

     

     

    2. 연결지향형 트랜스포트: TCP


    TCP에 대해서는 우리가 2장 애플리케이션 계층에서 특징을 언급한적이 있다.

    (https://hello70825.tistory.com/456)

     

    TCP 특징

    - 신뢰적인 데이터 전송 (데이터 순서가 보장되어 있다)

    - 연결지향형 서비스 (3-way handshaking)

    - full-duplex 서비스 (호스트 A, 호스트 B가 있다면 데이터가 A → B로 흐를 수도 있고, B → A로 흐를 수도 있다.)

    - TCP 연결은 항상 송신자가 1명, 수신자가 1명이다. (1명이 여러명에게 데이터를 보낼 수 없다)

    - TCP에는 흐름제어와 혼잡제어가 있다.


    2.1 TCP 세그먼트 구조

    TCP 세그먼트 구조는 UDP 세그먼트 구조보다 복잡한 편이다.

    1) 출발지 포트 번호, 목적지 포트 번호

    2) 신뢰적인 데이터 전송을 위해 순서번호(sequence number)와 확인응답번호(acknowledgement number filed)가 있다.

    3) 헤더 길이를 나타내는 필드(head len)과 아무것도 사용하지 않는 필드(빈공간, not used)가 있다.

    4) 플래그 필드로 여섯개의 상태에 대해 나타낼 수 있다.

    5) 수신 윈도우(receive window)는 흐름 제어를 할 때 사용된다.

    6) checksum은 패킷에 오류가 있는지 확인할 때 쓰이고, Urg data pointer는 긴급 데이터 포인터로 긴급 데이터가 존재할 때 사용한다.

    7) 옵션 필드는 여러가지 옵션에 대해 설정을 할 수 있다.

    8) 마지막으로 데이터 필드는 실제로 우리가 주고 받는 내용에 관한 것이다.

     

    여기에서 중요한 것은 신뢰적인 데이터를 보장하기 위해 사용하는 순서번호 필드와 확인응답번호 필드이다.

    순서번호는 세그먼트에 있는 첫번째 데이터의 번호이고, 확인응답번호는 상대 호스트로부터 기대하는 다음 데이터의 순서번호를 뜻한다.

    Seq(n) = ACK(n-1)

    ACK(n) = Seq(n-1) + Size of Segment[Seq(n-1)]

    여기서 호스트 A는 클라이언트이고, 호스트 B는 서버이다.

    위 그림을 통해 살펴보면 클라이언트에서 보낸 값이 순서번호(Seq) = 42, 확인응답번호(ACK) = 79이므로, 서버쪽은 Seq = 79가 되고, 한 개의 세그먼트만 가져갔으니 ACK = 42 + 1 = 43이 된다.

    이후 클라리언트도 Seq = 43이 되고, ACK = 79 + 1이 된다.


    2.2 신뢰적인 데이터 전달

    TCP의 신뢰적인 데이터 전달 서비스는 프로세스가 자신의 수신 버퍼로부터 읽은 데이터 스트림이 손상되지 않았으며 손실이나 중복이 없다는 것과 순서가 유지된다는 것을 보장한다.

     

    위 그림은 TCP 송신자의 간소화된 기술을 FSM으로 나타낸 것이다.

    여기서 데이터의 전송/재전송과 관련한 세가지 이벤트가 존재한다.

     

    맨 처음에 패킷이 들어오게 되면 NextSeqNum과 SendBase의 값을 처음 데이터가 전송되는 주소로 저장한다.

    이후 아래 세가지 이벤트중 하나가 발생하게 된다.

     

    첫번째 이벤트는 data received from application above로 애플리케이션으로부터 데이터를 받았을 때다.

    이 경우 세그먼트로 데이터를 캡슐화하고, IP에게 세그먼트를 넘긴다.그래서 순서 번호는 첫번째 데이터의 순서 번호를 뜻하므로 이전 번호 + 데이터의 길이 = 다음 순서번호로 저장한다. 그리고 타이머가 현재 실행되고 있지 않으면 타이머를 실행한다.

     

    두번째 이벤트는 timeout이다.

    이 경우에는 타임아웃을 일으킨 세그먼트를 재전송하도록 한다. 그리고 타이머를 다시 시작한다.

     

    세번째 이벤트는 수신자로부터 ACK를 수신받는 것이다. 여기서 ACK값은 y에 저장을 한다.

    여기서 Sendbase값은 수신 확인응답이 오지 않은 가장 오래된 바이트의 순서로 Sendbase-1까지는 정상적으로 왔다는 뜻이다.

    이후 y값이 변수 SendBase보다 크다면 SendBase값을 y로 변경한다. 그다음 아직 데이터를 받지 못한 세그먼트가 더 이상 없으면 타이머를 작동 중단시킨다.

     

    아래 그림을 통해 더 자세히 알아보자

    이 사진은 ACK 패킷을 유실하였을 때의 상황이다. Host A에서는 ACK 패킷을 받지 못하였으니 타이머가 그대로 작동하게 되어 timeout이 일어나 패킷을 다시 전송하게 된다.

     

    이 사진은 데이터가 나중에 제대로 보내졌지만, 이미 timeout이 일어난 상태이다. 그래서 데이터를 다시 전송하였고, 이후에 ACK 패킷을 받아서 SendBase의 값을 갱신하게 된다.

    여기서는 timeout이 일어나야하는데, ACK=120 때문에 119바이트까지 모든 데이터를 수신했다고 간주하여 timeout이 일어나지 않고 다음 패킷으로 넘어가게 된다.


    2.3 타임아웃 주기의 두 배로 설정과 빠른 재전송

    재전송을 해도 timeout이 생기는 경우가 있을 것이다. 그래서 재전송때마다 이전의 timeout 주기를 두 배로 늘려준다.

    쉽게 말해서 타이머의 시간이 1msec인데 데이터가 들어오지 않으면 2msec → 4msec → 8msec → ... 이런식으로 두배씩 늘려준다는 것이다. 이 방법을 사용할 경우 제한된 형태의 혼잡제어를 제공하게 된다.(혼잡제어는 나중에 설명이 나온다.)

     

    timeout 시간중에 시간이 길게 잡힌 곳이 있을 것이다. 이 경우 재전송이 된다면 굉장히 비효율적일 수 있기 때문에 중복 ACK를 사용하여 이전에 받은 확인응답에 대한 재확인용으로 값을 하나 더 보내게 된다. 이러면 데이터가 유실될 경우 timeout이 일어나기전에 데이터를 재전송할 수 있게 된다.


    2.4 흐름제어

    TCP는 송신자가 수신자의 버퍼를 오버플로 시키는 것을 방지하기 위해 애플리케이션에게 흐름제어 서비스를 제공한다.

    수신자의 버퍼를 오버플로 시키는 경우는 송신자의 데이터 전송 속도가 수신자가 읽어들이는 속도보다 빠른 것인데, 송신자의 속도를 수신자와 같게 만들어준다고 생각하면 된다.

    그래서 송신자가 수신 위도우라는 변수에 수신자에게 남은 버퍼공간이 얼마나 되는지 송신자에게 알려준다.

    (TCP는 full-duplex이므로 수신자가 송신자에게 데이터를 전달할 수 있다.)

     

    호스트 A가 호스트 B에게 큰 파일을 보내려고 할 때, 수신자의 버퍼공간을 상회하는 공간이 필요할 것이다.

    [sender]

    - LastByteSent: 호스트 A가 호스트 B에게 보낸 데이터 스트림의 마지막 바이트 수

    - LastByteAcked: 전송 확인 응답을 받은 데이터 스트림의 마지막 바이트 수

    - in-flight =  LastByteSent - LastByteAcked

     

    [receiver]

    - RcvBuffer:  호스트 B에게 할당된 수신 버퍼

    - LastByteRead: 버퍼에서 읽은 데이터 스트림의 마지막 바이트 수

    - LastByteRcvd: 수신 버퍼에 저장된 데이터 스트림의 마지막 바이트 수

    - 수신 버퍼의 여유공간 rwnd = RcvBuffer - (LastByteRcvd - LastByRead)


    2.5 TCP 연결 관리

    1) three-way handshake

    [1단계] SYN 세그먼트

    클라이언트 TCP는 서버 TCP에 특별한 TCP 세그먼트를 송신하는데, 세그먼트의 헤더에 SYN 비트라고 불리는 플래그 비트를 가진다. 거기다가 클라이언트는 최초의 순서번호(client_isn)를 선택하고 이것을 TCP 세그먼트의 순서번호 필드에 넣어둔다. 이후 이 세그먼트는 IP 데이터그램에 캡슐화되고 서버로 송신된다.

    [2단계] SYNACK 세그먼트

    SYN 세그먼트를 포함하는 IP 데이터그램이 서버에 도착했을 때, 서버는 SYN 세그먼트를 뽑아낸다. 이후 연결에 TCP 버퍼와 변수들을 할당하고, 클라이언트로 보내는 세그먼트 헤더에 3가지 정보를 포함한다.

    - SYN비트는 1로 설정

    - 확인응답 필드의 값이 client_isn+1로 설정

    - 순서번호의 값은 server_isn으로 설정

    [3단계] ACK 세그먼트

    클라이언트가 SYNACK 세그먼트를 수신하면 연결에 버퍼와 변수들을 할당한다. 이후 클라이언트는 서버로 보내는 세그먼트의 확인응답 필드에 server_isn+1로 설정한다. 이후 연결 설정이 됐으므로 SYN 비트는 0으로 설정한다.여기서부터 데이터가 옮겨질 수 있게 된다.

     

    2) four-way handshake

    연결이 끝날 때를 가정해보는데, 클라이언트가 연결 종료를 결정한다고 하자연결이 끝나면 호스트의 자원들은 회수되어야 하는데, 이때 클라이언트 TCP가 서버 프로세스에게 세그먼트를 보내도록 한다.이때 세그먼트의 헤더에는 플래그 비트중 하나인 FIN 비트를 1로 설정해서 송신한다.서버가 해당 세그먼트를 수신하면 서버는 클라이언트에게 확인했다는 ACK 세그먼트를 보내게 되고, 이후 마찬가지로 FIN 비트가 1인 세그먼트를 송신하게 된다.클라이언트가 해당 세그먼트를 수신하면 서버에 ACK 세그먼트를 보내게 되며 이 시점에서 두 호스트의 모든 자원들이 할당 해제가 된다.


     

    반응형

    '공부 > 컴퓨터 네트워크' 카테고리의 다른 글

    7. 네트워크 계층  (0) 2022.05.27
    6. 혼잡 제어  (0) 2022.05.24
    4. 트랜스포트 계층  (0) 2022.05.23
    3. e-mail, DNS  (0) 2022.05.18
    2. 애플리케이션 계층  (0) 2022.05.17

    댓글

Designed by Tistory.