KOCW 컴퓨터네트워크-이석복 강의를 수강하며, 해당 내용을 바탕으로 배운 점들을 정리하였다.
Application 5 계층 중 Transport layer의 작동 방식을 알아본다.
Application layer에서 Socket을 통해 Transport layer와 데이터를 주고 받는다.
Transport layer에서 Application layer에 제공하는 기능은 다음과 같다.
한 Host에는 여러개의 Socket이 존재한다. 각 Process마다 가지고 있는 Socket을 구분하기 위해서 Port번호를 부여한다.
많은 Socket이 Network를 이용해 데이터를 전송할 때, 이것들에 대한 분류 작업을 해주는 것이 Multiplexing 이다. Muliplexing은 Transport layer에서 일어난다.
즉 다수의 Socket으로 부터 전송을 요청받은 여러 데이터에 대해서 구분할 수 있는 정보를 추가하고 하나로 합쳐서 Network layer에 넘겨주는 작업이다.
마찬가지로 한 Host는 여러 데이터를 다른 Socket들로부터 받는다. 이렇게 한 번에 들어온 데이터를 알맞은 Socket에 전달하는 과정이 demultiplexing이다.
출발 IP
, 도착 IP
, 출발 Port
, 도착 Port
를 확인하고 이에 따라서 최종 목적지가 되는 Socket에 데이터를 전달한다.
특징만 보면 이딴 걸 왜 쓰나 싶지만, 저러한 작업을 수행하지 않기 때문에 TCP보다 훨씬 빠르다.
또 헤더 정보가 적기 때문에 전송하는 패킷의 크기도 작아진다.
따라서 빠른 전송을 요구하는 실시간 데이터 전송 애플리케이션에서 사용된다.
UDP는 신뢰성 없이 빠른 데이터 전송을 위한 프로토콜이다.
반대로 TCP는 신뢰성을 보장한다.
네트워크 통신에서 신뢰성이란, 보낸 데이터가 제대로 목적지에 도착하는 것을 보장하는 것이다. 즉 전송 과정에서 문제가 발생했다면 재전송을 통해 결과적으로 데이터를 목적지에 보낸다.
신뢰성을 깨트리는 요소는 두가지가 있다.
Data 자체에 error가 존재하는 경우, receiver는 error
발생 여부를 sender에게 알린다.
이러한 feedback을 통해 error를 인지한 sender는 데이터를 재전송하면 된다.
만약 feedback 자체가 유실된 경우, sender측에서는 timeout 주기를 정해두고 해당 주기 안에 feedback이 없을 경우 같은 데이터를 재전송한다.
sequence number는 각 데이터를 구분하기 위한 번호이다. 특정 패킷이 현재 보내려는 데이터의 몇번째 순서인지를 구분할 수 있게 한다. 따라서 데이터의 순서를 보장하며, 어떤 데이터를 받았고 받아야하는지를 구분할 수 있게 해준다.
Sender는 설정된 Time-Out 시간동안 ACK
응답을 기다린다.
응답이 오지 않은 경우는 세가지이다.
ACK
가 Sender에게 도달하지 못하고 유실된 경우이 모든 경우에 Sender는 데이터를 재전송한다.
신뢰성을 보장하면서 네트워크 통신을 하기 위해서는 각 전송 데이터마다 feedback을 받아야한다. 이때 여러 데이터를 보내야하는 상황에서 이전 데이터의 ACK를 받을 때까지 아무 작업도 하지 않는다면 매우 비효율적이다.
따라서 여러개의 데이터를 한 번에 보내고 feedback도 동시에 받는 Pipelined protocols이 등장한다.
작동방식은 다음과 같다.
N
개의 패킷을 동시에 전송한다.
receiver는 정상적으로 도착한 패킷에 대한 feedback으로 ACK(n)을 전송한다. 여기서 n
은 n
번째 패킷까지 정상적으로 도착했다는 것을 의미한다. 이러한 방식을 cumulative ACK라고 부른다.
각 패킷마다 timer가 존재한다. 특정 패킷에서 time-out이 발생한 경우 해당 패킷부터 다시 재전송한다.
즉 N
개의 패킷을 보내는 도중에 i
번째 패킷에 time-out이 발생한 경우 i
번째부터 N
개의 패킷을 다시 재전송하는 방식이다. (가장첫번째 패킷이 먼저 time-out이 됐을 것이기 때문)
한 패킷이 도착하지 않은 경우에도 N개의 데이터를 재전송하기 때문에 비효율적이다.
또 각 패킷마다 타이머가 존재하는 것도 상당한 자원 낭비이다.
go-Back-N의 단점을 보완한 방식이다.
receiver는 buffer에 받은 패킷들을 임시로 저장한다.
sender는 ACK를 받지 못 한 패킷만 재전송한다.
Receive window
receive buffer의 여유공간에 대한 정보.
이를 통해 flow control을 하여 쓸데없이 네트워크 자원을 낭비하지 않는다.
checksum
데이터의 에러 유무.
TCP 통신에서는 세그먼트가 유실됐을 경우와 ACK가 유실됐을 경우를 방지하기 위해서 send buffer, receive buffer를 사용한다.
receive buffer에 이미 받은 세그먼트를 저장해두고 다른 세그먼트 전송과정에서 문제가 발생했을 때, 이미 받은 것들에 대해서는 새로운 요청을 하지 않음으로써 네트워크 자원을 절약할 수 있다.
하지만 만약 receive buffer가 가득 찬 상태에서 새로운 세그먼트가 도착한다면 이것을 저장할 수 없기 때문에, receive buffer의 여유 공간과 receive host의 세그먼트 처리 속도에 맞춰 전송속도를 조절해야한다.
이를 위해 TCP 헤더 정보에 recieve window 에 대한 정보를 추가하여 이를 바탕으로 전송속도를 조절하도록 한다.
TCP 통신은 세그먼트 전송의 신뢰성을 보장하기 위해 전송 전 연결상태를 확인하는 작업을 한다. 이것이 Three way handshake.
server와 client가 각각 연결상태를 확인하는 SYN message와 정상적으로 SYN을 받았음을 상대에게 알리는 ACK message를 전송하는 과정으로 구성된다.
TCP connection을 닫는 과정은 총 4단계로 이루어진다.
이때 3번째에서 server로부터 TCP connection을 닫을 준비를 마쳤다는 FIN MSG를 받은 후에도 client는 일정 시간동안 connection을 닫지 않고 대기한다.
이는 4번째의 ACK MSG가 유실됐을 경우를 대비한 것이다.
만약 마지막 ACK MSG가 유실돼어 server로부터 다시 FIN MSG가 재전송되었을 때, client가 이미 connection을 해지한 상태라면 server는 영원히 ACK MSG를 받을 수 없게 된다. 따라서 일정 시간동안은 TCP 연결에 대한 정보를 유지한 후 최종적으로 connection을 해지한다.
TCP 통신을 하는 두 Host 사이에는 복잡한 네트워크가 존재한다.
Flow Control을 통해 receiver의 데이터 처리속도는 고려해주었지만, 두 Host사이에 존재하는 네트워크의 상황은 고려하지 않았다.
만약 Network가 포화상태이고 Queuing delay로 인해서 계속 패킷이 유실되는 상황이 발생한다면, 점점 네트워크 상황은 악화될 것이다.
이를 방지하기 위해 네트워크 상황을 고려해 sender는 패킷 전송 속도를 조절하는데, 이것이 Congestion control이다.
Congestion control이 작동하는 원리는 패킷의 유실 여부이다.
sender는 전송한 패킷이 유실된 경우, 즉 ACK를 받지 못 하고 time-out이 발생한 경우 Network가 포화상태라고 여기고 전송속도를 조절한다.
신기하게도 여러개의 TCP connection이 존재하는 Network에서 자원을 각 연결이 공정하게 배분해서 사용한다.