전송 계층 (2) - TCP(1)

이정인·2022년 3월 1일
0

컴퓨터 네트워크

목록 보기
4/11

TCP

reliable data transfer (RDT)

받는 쪽에서 데이터가 유실되지 않고 전송됨
네트워크 계층은 unreliable channel이지만 전송 계층에서는 reliable channel 처럼 보여야 한다.

RDT의 디자인

단순한 RDT 프로토콜을 구성한다고 생각할 때, 하나의 데이터를 보내고 목적지에 정확하게 도착했을 때만 다음 데이터를 보낸다고 생각해보자
RDT를 위해서는 네트워크 계층에서 발생할 수 있는 문제를 해결하면 될 것이다.

네트워크 계층에서 발생할 수 있는 문제와 해결

아래 사항들이 header에 들어가야할 것이다.

  • packet error

    rdt 2.1

    • Error 감지 (checksum)

    • Feeback

      • ACK (acknowledgements):
        🙆‍♂️: 에러 없이 받았다
      • NAK (negative acknowledgements):
        🙅‍♂️: 에러 생겼다
    • sequence numbering

      => ACK / NAK이 제대로 전송되지 않을 경우 ?

      sender가 제대로된 피드백을 받지 못해서 재전송 할 경우 receiver에서는 이게 재 전송된 데이터인지 전에 받은 데이터인지 구분할 필요가 있다.

      이를 위해서 sender는 sequence number를 보내서 새로운 메시지인지 중복된 메시지인지 트랙킹할 수 있도록 한다.

      receiver는 중복에 상관 없이 피드백은 항상 보낸다.

      단순한 RDT의 경우 한 개씩 제대로 보냈는지 확인하고 다시 보내기 때문에 1 bit만 있어도 충분할 것임

    rdt 2.2

    ​ Nak-free : ack만 이용해서 성공했을 경우 ack와 다음으로 받을 시퀀스 넘버를 돌려 보냄

  • packet error, Loss 가 발생하는 경우

    rdt 3.0

    Loss 란 보내는 상황에서 패킷이 유실되거나 피드백이 유실되거나의 상황이다. sender 입장에서는 둘 다 똑같다. 둘 다 어차피 피드백이 안 오기 때문에 ..

    • 타이머
      메시지를 던져 놓고 피드백이 일정 시간 동안 오지 않으면 재전송한다.

실제 TCP는 데이터를 한번에 여러개 보내고 sender와 receiver가 정해지지 않는 등 더욱 복잡함

연결 지향적 전송 TCP

TCP Overview

  • point - to - point
    소켓과 소켓이 1:1 관계

  • Reliable, in-order byte stream
    메시지가 유실되지 않고
    메시지가 내려온 순서대로 전송됨

  • pipelined
    한 꺼번에 메시지 여러개를 보냄

  • full duplex data
    sender와 receiver가 정해진 게 아님
    sender가 receiver가 될 수도 있음

  • Connection-oriented

  • Flow controlled
    상대방 머신의 성능 에 맞게 보내는 속도를 조절해줌

  • congestion control

TCP segment structure

sequence number

TCP는 byte 단위로 시퀀스 넘버를 붙인다. 각 세그먼트의 바이트 중에서 가장 첫 번째 바이트의 시퀀스 넘버가 그 세그먼트의 시퀀스 넘버가 됨

	  [ ] [ ] [ ]
byte  250 150 100
seq   250 100  0 

cumulative ACK

Ack #100 일 경우 99번까지 완벽하게 받았고 100번을 기다린다는 뜻

timer

갔다가 오는 시간에 마진을 붙이면 넉넉할 것이다. ( RTT + margin )

이를 위해서 매번 세그먼트를 보내고 피드백을 받을 때 마다 sample rtt를 측정한다.

sample rtt : 세그먼트를 나갈 때 시간부터 피드백이 올 때까지 시간을 측정. 재전송한 세그먼트는 포함하지 않음

sample rtt는 라우터의 큐잉 상태에 따라 변화 무쌍하므로 평균 트렌드를 구함

매번 sample rtt를 측정할 때마다 최근 측정한 것이 가중치가 높게 적용되도록 estimatedRTT를 매번 갱신함

EstimatedRTT : (1 - a ) * EstimatedRTT + a * SampleRTT

따라서 TimeoutInterval = EstimatedRTT + 4 * DevRTT 로 정할 수 있다.

즉 타이머의 시간은 매번 갱신 되기 때문에 유연하게 적용될 수 있다.

TCP reliable data

각 소켓 쌍 마다 send buffer, receive buffer가 존재한다.

send buffer

애플리케이션 프로세스가 소켓을 통해서 하위 계층으로 전송하는 속도와 실제 TCP에서 전송하는 속도가 다르기 때문에 그 차이를 처리하기 위해서 send buffer가 필요하다.

애플리케이션 프로세스에서 온 메시지는 send buffer에 담긴다.

TCP는 window size 만큼만 한꺼번에 메시지를 보낼 수 있는데, 예를 들어 1000byte인 경우 0부터 999번까지만 처음에 나갈 수 있다. 이 세그먼트들은 다른쪽의 receive buffer로 들어가게 된다.

receive buffer에서는 받은 세그먼트를 저장해놓고 ack 를 보낸다. 제대로 도착했을 경우 해당 세그먼트를 애플리케이션 계층의 R/W에 맞춰서 올려보낸다.

send buffer에서는 ack를 확인하고 제대로 전송 됐을 경우 timersender base를 제대로 전송된 시퀀스 번호 만큼 다음으로 이동시킨다. 윈도우 크기 만큼 이동하는 것이기 때문에 남는 크기 만큼 다시 segment를 보낼 수 있다.

세그먼트가 유실될 경우 receive buffer는 해당 순서의 ack을 계속 보낸다. send buffer에서는 타이머가 울리면 해당하는 세그먼트를 재 전송한다. 해당 순서의 세그먼트가 제대로 왔을 때만 어플리케이션 계층으로 보낸다.

즉,

  • send buffer : 재전송을 위한 buffer
  • receive buffer : in-order를 위한 buffer

실제로는 send buffer가 동작하는 동시에 receive buffer도 따로 동작한다.

Fast retransmission

타이머가 터지기 전에 유실을 빨리 판단할 수 있는 방법이 있을까?
중복된 ACK가 3번 들어왔을 때 (실제로는 4번) 유실로 판단하고 전송하는 방법이 있다.

참고
http://www.kocw.net/home/search/kemView.do?kemId=1312397
http://www.kocw.net/home/cview.do?mty=p&kemId=1169634

0개의 댓글