전송 계층 서비스 : multiplexing(다중화), demultiplexing(역다중화) / reliable data transfer / flow control / congestion control
전송 계층 프로토콜 : UDP(User Datagram Protocol), TCP(Transmission Control Protocol)
: 서로 다른 호스트들의 실행중인 앱 프로세스 간의 logical communication을 제공한다
Transport protocols actions in end systems
- Sender : 메시지를 부분(segments)로 잘라서 header를 붙여서 network layer(IP)에게 넘겨줌
- Receiver : 흩어져있는 조각들을 모아 메시지로 만들어서 application layer에 넘겨줌(demultiplexes message up to application via socket)
* Transport layer : communication between process
Network layer : communication between hostsInternet Transport-Layer Protocols
TCP
- Reliable(신뢰성 높음), in-order delivery
- 혼잡 제어 (Congestion control)
- 흐름 제어 (Flow control)
- 연결 지향(Connecition setup 필요)
- UDP보다 속도가 느리다(handshaking 과정 필요)
- 신뢰성 있는 전송에 사용
UDP
- Unreliable(신뢰성 낮음), unordered delivery
- connectionless protocol(비연결 지향)
- TCP보다 속도가 빠르다(handshaking 과정 필요 없어서)
- 연속성이 중요한 서비스(실시간 스트리밍)에 사용
공통점
- 지연에 대한 보장 X (No delay guarantees)
- 대역폭 보장 X (No bandwidth guarantees)
Multiplexing at sender
: 여러 소켓에서 data를 모으고, transport header을 추가한다 == segment (이때 추가한 헤더를 receiver에서 demultiplexing 하는데 사용)
Demultiplexing at receiver
: 전송 받은 세그먼트의 데이터를 헤더의 정보를 활용해서 적절한 소켓으로 segments를 전달한다.
Demultiplexing 의 작동 방법
- 호스트는 IP datagrams(== IP packet)을 받는다.
- 각 datagram은 source IP와 dest IP 주소, 포트넘버를 가지고 있다
- 또 그들은 하나의 transport-layer segment를 가지고 있다- 호스트는 IP address와 port numbers를 이용해서 이 segment를 적절한 소켓으로 보내준다.
Connectionless Demultiplexing(UDP)
- host-local port #를 지정해서 소켓을 생성.
- UDP socket은 목적지의 IP와 port number만 알면 식별 가능
- segment의 도착지 port number를 체크해서, UDP segment를 적절한 socket으로 전달.
-> 만약 UDP segment는 출발지 IP나 port number가 같지않아도 동일한 목적지 IP와 port number를 갖는다면 동일한 socket을 통해 process에 전달.- 소켓이 줄어 들어서 시스템의 리소스 점유가 적음
- server의 제작자가 client도 배포 해야 함.(DP와 IP를 알아야 하기 때문에) ex) 게임이나 메신저등의 특정 프로그램
Connection-Oriented Demultiplexing(TCP)
- TCP socket은 4개의 요소(source IP, source port number, destination IP, destination port number)로 식별
- host는 도착한 segment를 적절한 socket으로 전송하기 위해 4개의 요소를 전부 사용
- server host는 동시에 여러 개의 TCP socket을 지원하며 4개의 요소로 구별
- web server는 각각의 client의 접속에 대해 서로 다른 socket을 이용
- non-persistent HTTP의 경우 모든 요청마다 다른 socket을 이용
- 각각의 object마다 새로운 TCP connection을 이용
1. Protocol
- 꾸밈 없이 그저 맨 뼈(No frills, bare bones)
- 쓸데 없는 기능 싹 빼고 필요한 것만 있는 Internet Transport Protocol- "Best effort"service (최선을 다하는 서비스)
- 그러나 정보가 손실될 수 있고, 잘못 전달될 수 있음
Connectionless
- sender와 receiver간의 Handshaking 과정이 없음. 각 UDP segment는 서로서로에게 독립적으로 관리된다.
- 사용하는 것들 : Streaming multimedia apps (손실 허용,속도에 민감) , DNS, SNMP, HTTP/3
* UDP로 신뢰성 있는 전송을 하고싶다면?
- application layer에서 신뢰성을 줄 수 있다.(congestion control add)
- length는 header 포함 길이2. Checksum : for detect "error" in transmitted segment
- Sender
- header fields를 포함한 모든 segment content를 16-bit 정수로 취급한다
- Checksum : segment contents를 더한 값(1의 보수 합)
- sender는 이 checksum 값을 UDP checksum field에 넣어서 보낸다.- Receiver
- 받은 segment의 checksum을 계산을 한다
- 계산한 checksum이 받은 checksum field 값과 같은지를 확인한다.
- 같다면 오류가 없다, 다르다면 오류가 있다. (물론 같다고 에러가 100퍼센트 없는건 아님)
- application layer는 reliable channel로 서비스를 제공하지만, transport layer는 unreliable channel임. 따라서 이 갭을 함수들로 채워줘야함
- 이렇게 채널이 unreliable하다는 특성이 reliable data transfer protocol(rdt)의 복잡성을 결정하게 됨.
Sender
1. rdt_send() : app에 의해 불려진다. data를 전송하기 위해 아래로 넘겨준다.
2. udt_send() : rdt에 의해 불려진다. unreliable channel을 통해 패킷을 receiver한테 보낸다.
Receiver
1. rdt_rcv() : 패킷이 rcv-side에 도착했을 때 불려진다
2. deliver_data() : rdt에 의해서 불려진다. 데이터를 위 계층로 올리려 한다.
- reliable data transfer protocol (rdt)는 sender와 receiver 양 쪽을 점차 발전시켜 나감
- 단방향 데이터 전송만 생각한다. but control info는 양쪽 방향으로 흐름
- sender와 receiver를 명시하기 위해서 finite state machines (FSM)을 사용
(어떤 액션이 있을 때 state가 변하거나 유지되거나 함)1) rdt1.0: reliable transfer over a reliable channel(No error, No Packet Loss)
- 이 channel은 완벽하게 reliable 할 것을 가정한다. (No bit errors, no loss of packets)
1. sender는 계속 기다리다가 rdt_send(data)가 불리면 packet을 만들어서 udt_send(packet)으로 receiver한테 패킷을 보낸다.
2. receiver는 계속 기다리다가 rdt_rcv(packet)이 불리면 패킷이 도착했다는 것이므로 packet을 분해해서 data를 뽑아서 deliver_data(data)로 상위 계층에게 전달한다.2) rdt2.0: Channel with Bit errors
- 이 channel은 패킷의 bits가 뒤집힐 수 있는 곳(이 bit errors을 찾기 위해 checksum을 씀)
ERROR를 recover하는 방법?
- Acknowledgements (ACKs) : sender에게 pkt 잘 받았다고 대답해줌
- Negative acknowledgements (NAKs) : sender에게 pkt에 문제가 있다고 말해줌
- sender는 NAK를 받으면 다시 보낸다
- sender는 위에서의 call을 기다리다가 rdt_send(data)가 호출되면 udt_send(sndpkt)을 보낸다.
- 그리고 ACK 또는 NCK를 기다리는 상태로 전환된다.
- receiver는 rdt_rcv(rcvpkt)으로 패킷을 받고 notcorrupt(rcvpkt)으로 패킷에 이상이 없는지 확인한다.
- 이상이 있다면 udt_send로 NAK를 반환하고, 이상이 없다면 data를 deliver_data(data)로 위로 올린다음에 ACK를 보낸다.
- sender는 rdt_rcv(rcvpkt)으로 어떤 패킷이 왔음을 확인하고 만약 이 패킷이 NAK이면 문제가 있는거니까 다시 udt_send(sndpkt)해준다.
- 만약 NAK가 아니라 ACK라면 정상적으로 간거니까 다시 대기 상태로 전환된다.
3) rdt2.1: sender, handling garbled ACK/NAKs
"rdt2.0의 치명적 결함, 만약 ACK/NAK가 중간에 사라진다면?"
- sender는 대체 이 receiver한테 무슨 일이 벌어진 건지 알 수 없음. 그냥 다시 보내면 receiver가 처음 보낸 것과 다시 보낸 것 두개를 다 받으면 이게 재전송된 패킷인지, 아니면 동일한 내용을 가진 새로운 패킷인지 알 수가 없음.
-> 중복 위험성 때문에 무조건 retransmit 할 수 없음
- 송신 측에서 0번 패킷을 보내고 ACK 0 혹은 NAK 0 신호를 기다린다.
- 0번 패킷이 수신 측에서 에러가 발생했다면 NAK 0 을 받을 것이고 수신 측으로 0번 패킷을 재전송할 것이다.
- 0번 패킷이 정상적으로 전송되었다면 ACK 0을 받을 것이고 다음 패킷인 1번 패킷을 전송한다.
- 마찬가지로 ACK 1 혹은 NAK 1 신호를 기다리고 위와 같은 과정을 모든 패킷을 보낼 때까지 반복한다.
따라서 sequence number는 0, 1 두개면 충분하다. (중복 여부만 판단하면 되기 때문)4) rdt2.2 : a NAK-free Protocol
- 기능적으로는 2.1과 같은데 이건 NAK 없이 ACK만 사용함
- NAK 대신에, receiver는 마지막 패킷이 잘 도착했는지에 대한 ACK 응답만 받음(ACK 패킷 안에는 seq# 포함)
- Sender에게 ACK가 중복되면 NAK와 동일한 결과가 나온다.
Sender는 현재 패킷을 다시 재전송한다.
1. 중복되는 ACK 신호를 받으면 패킷을 재전송한다.
2. 송신측에서 0번 패킷을 전송하고 ACK 0번을 받고
3. 1번 패킷을 보내고 수신측에 오류를 확인하면 ACK 1이 아닌 ACK 0을 다시 보낸다
4. 송신측은 ACK0을 받고 오류가 있음을 알고 다시 1번 패킷 보냄5) rdt3.0 : Channel with error and "loss"
New Assumption : 채널에서 data와 ACKs를 담는 패킷도 실종된다고 가정
- Sender/receiver는 ACK나 패킷 받을걸 기다리는데 아무것도 못 받을수도 있다.(예를 들면 버퍼 오버플로우로 인한 손실)
Approach : sender는 패킷을 보내고 ACK를 "reasonable" 시간동안 기다려본다!
- 만약 ACK가 그시간 안에 안오면 retransmits
- 이 시간을 세줄 countdown timer가 필요- ACK나 패킷이 분실된게 아니라 단순히 지연된 걸 수도 있는데,
- sender은 timeout에 의해서 중복되는 패킷을 retransmit 하지만 receiver는 seq.#로 중복을 방지할 수 있다!
- 따라서 Receiver는 무조건 ACKed를 받을 패킷의 seq.# 을 지정해서 보내야 한다.
Stop-and-Wait Operation- 패킷의 첫 번째 bit 가 전송 시작되는 시간 t = 0
마지막 t = L/R- 마지막 bit까지 receiver에 도착하면 ACK를 전송함
- 이 때 마지막 bit를 보내고 ACK를 받을 때 까지의 시간 = RTT (Round Trip Time)
- ACK가 도착하고 다음 패킷을 전송할 때까지의 시간 t = RTT + L/R
rdt 3.0 은 정확한 대신 성능이 안좋다.Packet pipelining for high utiliztaion
1) Go-Back-N
2) Selective Repeat
Go-Back-N은 한 번에 N개씩 보내는 프로토콜, Receiver는 여러 개의 ack를 축적해서 보냄. 만약 순서를 지키지 않고 중간에 다른 패킷이 오면 그 패킷은 받지 않고 ack를 보내지 않는다. sender는 가장 오래된 unacked packet에 대한 타이머를 가지고 있다. 만약 타이머가 끝나면 그 패킷부터 N개를 다시 다 보낸다.
Selective Repeat은 N개를 보내는 것은 같지만 Receiver은 각 패킷에 대해 개별적인 ack를 보냄. 그리고 sender 역시 unacked packet에 대해 모든 timer를 유지한다. 만약 타이머가 끝나면 오직 unacked 된 패킷에 대해서만 재전송을 한다. 즉 잘못된 것만 다시 보내는 것
이 글을 읽고 많이 배웠습니다.