*본문에서 트랜스포트 = 전송 혼동해서 사용
*chapter 1,2를 하고보니 너무 많은 볼륨을 다루는 것 같아서 앞으론 핵심적인 내용을 더 간추려 정리할 예정
3.1 트랜스포트 계층 서비스 및 개요
전송 계층 프로토콜: 어플 프로세스 간의 논리적 통신 제공. 네트워크 라우터가 아닌 종단 시스템에서 구현됨.
송신측 전송계층은 송신 어플 프로세스부터 수신한 메시지를 전송 계층 세그먼트인 전송 계층 패킷으로 변환.
메시지들을 세그먼트로 만들기 위해 작은 조각으로 분할하여 각 조각에 전송 계층 헤더를 추가함.
송신 종단 네트워크 계층으로 세그먼트를 전달하고, 거기서 세그먼트가 네트워크 계층패킷(데이터그램)안에
캡슐화되어 목적지로 전달됨.
라우터는 데이터그램의 필드에 대해 동작하기 때문에 캡슐화된 전송 계층 세그먼트 필드는 검사x.
수신측은 반대의 과정을 수행(데이터그램 -> 세그먼트)
전송 계층 vs 네트워크 계층 프로토콜 비교
전송 계층 프로토콜= 서로 다른 호스트에서 동작하는 프로세스들 사이의 논리적 통신
네트워크 계층 프로토콜 = 서로 다른 호스트들 사이의 논리적 통신
비유
메시지 = 봉투안 편지 / 프로세스 = 사촌형제 / 호스트 = 집 / 전송계층 프로토콜 = 우편담당 멤버
네트워크 계층 프로토콜 = 우편 서비스(우편 집배원 등,,,)
전송 계층이 제공할 수 있는 서비슨느 하위 계층인 네트워크 계층 서비스 모델에 의해서 제약받음
(우체국에서 늦게 소포를 배달하면 우편담당 멤버가 어떻게 형제자매들한테 빨리 소포를 전해주겠어..)
그럼에도, 하위 *네트워크 프로토콜이 비신뢰적이거나 패킷을 분실하고 복사본을 만들 때도,
어플에게 신뢰적인 데이터 전송 서비스를 제공할 수 있다(암호화 등)
*네트워크 계층 프로토콜 IP는 호스트들 간에 논리적 통신을 제공하는 최선형 전달 서비스로,
최대한 노력은 하지만 어떠한 보장도 하지않음..(세그먼트 전달 및 순서, 무결성 등 보장 x)
UDP와 TCP는 종단시스템 사이의 IP전달 서비스를 종단 시스템에서 동작하는 두 프로세스 간 전달 서비스로 확장.
(호스트-호스트 간에서 프로세스-프로세스 간으로 확장하는것, 트랜스포트 다중화와 역다중화)
둘 다 헤더에 오류 검출 필드를 포함해서 무결성을 제공.
딱 다중화 및 무결성까지가 UDP가 제공하는 서비스로,
UDP는 그 이상의 데이터 손상방지나 목적지 프로세스 도착 보장 등의 서비스를 제공하지 않음 = 비신뢰적 서비스.
TCP는 추가적으로 신뢰적 데이터 전달, 흐름제어, 순서번호, 확인응답, 타이머, 혼잡제어 등 제공
혼잡제어: 어플리케이션이 제공하는 서비스가 아닌 전체를 위한 일반 서비스로, 각 송신측 TCP가 각 링크의 대역폭을
공평하게 공유하도록하여 TCP 연결이 과도한 양의 트래픽으로 모든 통신하는 호스트들 사이의 스위치와 링크를
폭주되게 하는 것을 방지함.
3.2 다중화와 역다중화
모든 컴퓨터 네트워크에서 필요로 함. 목적지 호스트에서의 전송 계층이 바로 아래의 네트워크 계층에서 세그먼트 수신
이 세그먼트를 바로 위의 어플 프로세스로 전달해야됨.
자 네트워크와 프로세스 사이의 출입구 역할을 하던 소켓을 chapter2에서 공부했는데 다시 떠올려 보자.
호스트가 하나 이상의 소켓을 가질 수 있으니 각 소켓은 식별자를 가지는데, UDP소켓인지 TCP소켓인지에 따라
소켓의 식별자 포맷이 달라진다.
각 전송 계층 세그먼트는 필드 집합을 가지고 있는데,
송신측 전송계층에서 소켓으로부터 데이터를 받아서 세그먼트를 생성할 때 각 데이터에 헤더 정보를 달아서
캡슐화하고 이를 네트워크 계층으로 전달해준다. = 다중화
수신측 전송계층에서 필드 집합을 검사하여 적절한 소켓으로 해당 세그먼트를 보낸다 = 역다중화
(다중화와 역다중화는 다른 계층에서도 한 프로토콜이 상위 계층의 여러 프로토콜에 의해 사용될 때마다 관련됨)
다중화 요구사항
1. 소켓은 유일한 식별자를 가짐.
2. 각 세그먼트는 전달될 적절한 소켓을 가리키는 특별한 필드를 가짐(필드 = 출발지 *포트 필드 + 목적지 *포트 필드)
*(0~1023까지의 포트는 잘 알려진 포트 번호라고 하여 사용을 엄격히 제한)
UDP 소켓은 목적지 IP주소와 목적지 포트번호로 구성된 두 요소의 집합에 의해 식별됨.
근데 출발지 포트번호는 왜 넣지? -> 복귀 주소의 한 부분으로 사용하기 때문
목적지 출발지로 세그먼트를 다시보낼 때 복귀 주소(출발지 포트번호 + 출발지 IP)를 사용
*chapter2의 2.7 코드 예시에서 recvfrom()함수를 써서 출발지 포트번호를 추출한 걸 떠올려..
TCP 소켓은 UDP 소켓과 달리 출발지 IP, 포트번호 및 목적지 IP, 포트번호 이 4가지 요소의 집합에 의해 식별됨.
chapter2에서 TCP연결 자체가 끊어지지 않으면 각 포트에 대한 연결은 끊어져도 새로운 연결 소켓을 연결하면
해당 TCP 연결을 사용할 수 있었던 걸 기억하면 서버 호스트는 동시에 *많은 TCP 소켓을 지원할 수 있다.
*다른 IP를 가진 호스트에서 같은 포트를 쓰더라도 식별 당시 IP와 포트번호를 다 확인하기 때문에 여전히
서로 다른 연결을 올바르게 사용할 수 있는 것이다.
클라이언트와 서버가 지속적인 HTTP를 사용한다면 그 연결동안 동일한 서버 소켓을 통해 메시지를 교환하겠지만
비지속적인 HTTP를 사용한다면 모든 요청/응답마다 새로운 TCP 연결을 생성하고 종료해야하는 부담을 가질 것..
3.3 비연결형 트랜스포트: UDP
UDP 통신은 다중화/역다중화 및 간단한 오류검출 기능을 제외하곤 추가 기능이 없다고 했는데,
이는 곧 IP에 거의 기능을 추가하지 않은 셈이라 IP와 직접 통신하는 셈이다.
어플 계층 메시지 →전송 계층 세그먼트 다중화 → 네트워크 계층 세그먼트를 IP 데이터그램으로 캡슐화하여 송신
→ 수신 호스트에게 최선형 전달 서비스로 전달
UDP 장점
무슨 데이터를 언제 보낼지에 대해 어플 레벨에서 더 정교한 제어: 어플 계층에서 데이터를 받자마자 즉시 UDP는
데이터를 세그먼트로 바꾸어 네트워크 계층으로 보내기 때문에 혼잡제어, 신뢰적 테스트 등을 하지 않아서 빠름.
연결 설정 없음 : 핸드 셰이킹을 하지 않기 때문에 빠름.
연결 상태 없음: 연결 상태를 유지하려면 수신 버퍼, 송신 버퍼, 혼잡제어 파라미터, 순서번호, 확인 번호 등
많은 상태정보를 필요로 하기 때문에 이런 파라미터가 없으면 UDP에서 좀 더 많은 클라이언트를 수용할 수 있다.
패킷 헤더 오버헤드가 작음: TCP는 세그먼트마다 20바이트, UDP는 8바이트의 헤더 오버헤드를 가짐.
- 네트워크 관리 데이터 전달에 자주 사용: 네트워크가 혼잡할 때 동작해야하기 때문
- 실시간 어플, 멀티 미디어 어플에서 사용: 적은 양의 패킷 손실은 허용
- UDP 송신자에 의해 발생된 손실율은 그 손실율을 줄이기 위해 TCP송신자들까지도 속도를 줄이도록 요구하기 때문에
TCP 세션까지 줄여버릴 수 있어서 UDP 연결만 너무 많으면 안됨.
- UDP에서도 어플리케이션 자체에서 디버깅도 해주고 관리도 해주면 신뢰적 데이터 전송이 가능은 함.
UDP 세그먼트 구조
UDP 헤더: 2바이트씩 구성된 4개의 필드(출발지포트/ 목적지포트/ 길이/ *체크섬)
*체크섬: 세그먼트에 오류가 발생했는지를 검사하기 위해 수신호스트에 의해서 사용됨.
ex) 기존 3개의 16비트 워드가 있다면 그 셋을 더해서 1의 보수를 취한 16비트까지 더해주면 수신자측에선 1이 16개인
비트를 받을 것이고, 한 비트라도 0이 있다면 패킷에 오류가 있음을 알 수 있다.
UDP는 오류 검사는 제공해도 오류 방지 및 오류 회복은 제공하지 않음. 가끔은 손상된 세그먼트를 그냥 버리기도 함.
종단간의 데이터 전송 서비스가 오류 검사를 제공하면 UDP는 종단간의 전송 계층에서 오류 검사를 제공해야 함
= 종단간의 원리(종단 기반으로 구현된 기능이 있으면 하위 레벨에 위치한 기능들은 상위 레벨에서 제공하는 비용과
비교햇을 때 중복되거나 거의 유용하지 않을 수 있다.)
3.4 신뢰성 있는 데이터 전송의 원리
데이터가 손상되지 않으며 전송된 순서대로 도착- TCP가 제공
하위 채널은 패킷의 순서를 바꾸지 않음.
단방향 데이터 전송만 생각하더라도 송신측과 수신측이 양방향으로 패킷 주고받음.
신뢰적인 데이터 전송 프로토콜의 하위 계층이 신뢰적이지 않으면 어려워짐..
유한상태 머신(FSM)으로 송수신자의 동작을 정의
평행선 위 = 변화를 일으키는 이벤트
평행선 밑 = 변화에 의해 취해지는 액션 이벤트
이벤트 발생 시 행동이 없거나 이벤트 발생 없이 행동이 있을 땐 각각 ∧ 기호를 사용.
완벽하게 신뢰적인 하위 채널 위에서의 신뢰적인 데이터 전송: rdt 1.0
완전히 신뢰적인 채널 위에선 오류가 생길 수 없으므로 수신측이 송신측에 피드백을 별도로 하지 않음
비트 오류가 있는 채널 상에서의 신뢰적인 데이터 전송: rdt 2.0
손상된 비트를 수신하더라도, 전송된 모든 패킷은 송신된 순서대로 수신된다.
긍정 확인응답과 부정 확인응답을 사용해서 반복이 필요한지를 수신자가 송신자에게 알림.
자동 재전송 요구(ARK): 오류검출(체크섬 필드 사용), 수신자 피드백, 재전송
수신자 피드백은 ACK나 NAK 둘중 하나인 1비트로 판단 가능.
rdt_rcv(rcvpkt) && isNAK(rcvpck)이면 마지막 패킷을 재전송하고, isACK(rcvpck)이면 추가 행동 x
이때 ACK나 NAK 기다리는 동안 다른 새로운 패킷을 받을 수 없어 = 전송 후 대기 프로토콜
- ACK나 NAK 패킷이 손상되면? -> 이 패킷들도 체크섬 비트 추가 필요
- 오류 복구는? -> 비트 오류 회복까지 가능하게 충분한 체크섬 비트를 추가
- 왜곡된 ACK나 NAK 받으면? -> 무조건 단순히 현재 데이터 패킷을 재송신하도록 함. (대신 중복 패킷 전송 가능..)
So, 데이터 패킷에 새로운 필드를 추가해 이 필드에 순서 번호를 송신자가 삽입한다.
동일한 순서번호 가진 패킷을 받으면 재전송된 패킷이겠거니 아는거고 수신된 ACK와 NAK 패킷이 가장 최근에
전송된 패킷에 대한 응답임을 알 수 있다.
프로토콜 rdt 2.1에서 손상된 패킷 수신 시 NAK를 송신하거나 가장 최근에 정확하게 수신된 패킷에 대해
ACK를 또 보내서 중복 ACK를 받은 송신자가 중복 ACK 패킷의 다음 패킷이 문제가 있구나~ 를 알 수 있다.
[ex. 1번 호출을 기다리는데 충돌이 났어 -> 야야.. NAK 보낼게 ~
0번 호출은 가지고있는데 충돌이 안났어 -> 음 ㅇㅋ 이거 1번호출이네 ACK보낼게 ~]
프로토콜 rdt 2.2에서 수신자가 반드시 ACK 메세지에 의해서 확인응답을 하는 패킷의 순서번호를 포함하고
송신자는 수신한 ACK 메시지에 의해 확인 응답된 패킷의 순서번호를 점검함.
[ex. isACK(rcvpck,0) 이렇게 0번 호출에 대한 ACK인지를 확인. 수신자는 make_pkt() 할 때 (ACK,0)과 (ACK,1)
등을 구분해서 보내준다.]
비트 오류와 손실 있는 채널 상(하위채널의 패킷 손실)에서의 신뢰적 데이터 전송: rdt 3.0
1. 패킷 손실을 어떻게 검출할래? 2. 패킷 손실 발생시 어떻게 대처할래?(이건 rdt 2.2로 가능)
송신자에게 손실 패킷 검출 & 회복 두 책임을 모두 줘보자
송신자가 수신자의 패킷에 대한 ACK 또는 패킷을 손실했다고 가정 -> 응답이 없겠지
그럼 패킷을 잃어버렸다는 것을 *확신할 정도로 충분히 기다리면 -> 재전송 해버림
*얼마나 기다릴까? - 송신자와 수신자 사이의 왕복시간 지연 + 수신 측 패킷 처리 시간까지 고려한 충분한 시간
손실이 안났는데 패킷 크기가 커서 응답이 느렸던거면 중복 패킷을 받게 되겠지만 rdt 2.2에서 순서번호를 가진
패킷을 처리해주기 때문에 걱정안해도 됨.
이렇게 충분한 시간을 기다리다가 인터럽트를 해버리는 메커니즘을 수행해주는 카운트다운 타이머 필요
1. 매 패킷 송신된 시간에 타이머 동작 시작
2. 타이머 인터럽트에 반응
3. 타이머 멈춤(정상적 종료 시)
패킷의 순서번호가 0과 1이 번갈아 일어나므로 얼터네이팅 비트 프로토콜이라고도 부름
==========================================================
파이프라인된 신뢰적 데이터 전송 프로토콜
전송 후 대기 방식은 패킷을 실제로 전송하는데는 작은 시간이 필요한데, 패킷이 먼 거리를 횡단하는 시간인 RTT가
훨씬 크기 때문에 송신자의 이용률이 낮아진다.
파이프라이닝: 확인응답을 기다리기 전에 송신자가 여러 패킷을 파이프라인에 채워넣는 것
1. 순서번호의 범위가 커져야 됨.
2. 한 패킷 이상을 버퍼에 담아서 버퍼링 해야 함.
3. 필요한 순서번호의 범위와 버퍼링 조건은 '손실 패킷과 상당히 지연된 패킷들에 대해 응답하는 방법'에 의존.
N부터 반복(Go-back -N, GBN)과 선택적 반복(SR) 등이 있음.
GBN 프로토콜
여러 패킷을 전송할 수 있지만 확인응답이 안된 패킷의 최대 허용 수 N보다 크지 않아야 한다.
확인응답 안된 가장 오래된 패킷 순서번호 = base
사용되지 않은 가장 작은 순서번호 = nextseqnum
윈도우 크기 = N
0~base-1 까진 이미 전송되고 확인응답된 패킷
base~ base+ N -1까진 송신은 됐는데 확인응답은 못받은 패킷
base+N 이상은 파이프라인에서 확인응답이 안된 패킷의 확인 응답이 도착할 때까지 사용불가
GBN은 슬라이딩 윈도우 프로토콜로, 혼잡제어 및 흐름제어 때문에 유한한 길이를 가진 N에 영향을 받음.
패킷의 순서번호는 패킷 헤더 안의 고정된 길이 필드에 포함됨.
순서번호 필드의 비트 수가 k면 [0, 2^k-1] 범위의 순서번호를 가질 수 있음. TCP은 32비트 순서번호 필드를 가짐.
GBN 송신자
상위로부터의 호출: 첫 번째 윈도우가 가득 찼는지 = N개의 확인응답 되지 않은 패킷이 있는지 확인.
가득 차 있다면 데이터를 상위 계층으로 반환해서 윈도우가 가득 차 있다는 것을 가리킴.
보통은 윈도우가 가득하지 않을 때만 rdt_send()를 호출(세마포어 또는 플래그)
ACK의 수신: 순서번호 n을 가진 패킷에 대한 확인응답은 누적 확인응답으로 인식
올바르게 수신된 n을 포함하여 n까지의 순서번호를 가진 모든 패킷들에 대한 확인응답.
타임아웃 이벤트: 타이머는 손실된 데이터 또는 손실된 확인응답 패킷으로부터 회복에 사용됨.
타임아웃 발생하면 '이전에 전송되었지만 아직 확인응답 안된 모든 패킷'을 다시 송신.
가장 오래된 '전송됐지만 아직 확인응답 안된 패킷'에 대한 타이머를 단일 타이머로 사용
GBN 수신자
순서번호 n을 가진 패킷이 오류 없이 수신되면 수신자는 n에 대한 ACK까지는 송신하고, 그 패킷을 상위 계층으로 전달.
패킷 k가 수신되고 상위 계층으로 전달됐으면 k-1까지는 싹다 전달 된거겠네.
수신자는 순서가 잘못된 패킷을 버림 -> 잘못된 패킷에 대해 버퍼링할 필요가 없어짐.
송신자는 윈도우 상위, 하위 경계값이랑 윈도우 안에 있는 nextseqnum까지 유지해야 하는 반면,
수신자는 그냥 다음 순서 패킷의 순서번호만 가진채로 유지한다.
이벤트-기반 프로그래밍에서의 다양한 프로시저들은 프로토콜 스택에서 다른 프로시저에 의해서 야기되거나
인터럽트의 결과로 요청됨.( rdt_send()를 호출하기 위한 상위 계체로부터의 호출, 타이머 인터럽트, 패킷 도착 시에
rdt_rcv()를 호출하기 위한 하위 계층으로부터의 호출..)
정리
수신자는 내가 정상적으로 받은 마지막 순서번호에 대한 ACK를 계속 보냄.
송신자는 순서 잘못된 패킷이 타임아웃되면 '이전에 전송되었지만 아직 확인응답 안된 모든 패킷'을 다 다시 보내줌.
그래서 수신자는 따로 순서 틀리게 온 패킷들은 버퍼에 저장해놓을 필요가 없음.
선택적 반복 SR
GBN에서 윈도우 크기와 밴드폭 지연 곱의 결과가 모두 클 때 많은 패킷이 파이프라인에 존재하게 되는데,
패킷 하나가 오류나면 많은 패킷이 재전송 돼야하는 문제..
선택적 반복: 수신자에게서 오류가 발생했다고 의심되는 패킷만 송신자가 다시 전송
SR 송신자
상위로부터 받음: 패킷의 다음 순서번호를 검사하여 그 번호가 송신자 윈도우 내에 있으면 데이터를 전송하고
없으면 버퍼에 저장되거나 상위 계층으로 돌려보냄.
ACK 수신: 그 ACK가 윈도우에 있으면 수신된 것으로 표시하고, 순서번호가 send_base와 같다면 윈도우 베이스는
가장 작은 순서번호를 가진 아직 확인응답 되지 않은 패킷으로 옮겨짐.
윈도우가 이동하고 윈도우 내의 순서번호를 가진 미전송 패킷이 있으면 해당 패킷 전송.
타임아웃: 손실된 패킷을 보호하기 위해 타이머 다시 사용. 오직 한 패킷만이 타임아웃에 전송되기 때문에
각 패킷은 자신의 논리 타이머를 가져야 됨
SR 수신자
1. [rcv_base, rcv_base+ N -1] 범위 내의 순서번호를 가진 패킷은 손상 없이 수신됨.
순서가 틀린 패킷은 버퍼에 저장됐다가 손실된 패킷(아직 도착하지 않은 더 낮은 순서번호를 가진 패킷)이 수신된 후,
즉 rcv_base인 윈도우 베이스와 같은 순서번호를 가진 패킷이 오고나면
이전에 버퍼에 저장된 연속된 순서패킷들을 상위 계층으로 전달
2. [rcv_base-N, rcv_base -1]내의 순서번호를 가진 패킷이 수신되면 이전에 확인응답한 것이라도 ACK 생성돼야 함.
3. 나머지 경우는 패킷을 무시함.
수신측 윈도우가 순서번호 공간의 크기보다 1만 작다고 가정해보자. 수신자가 보낸 ACK가 손실 났을 때
송신자가 타임아웃된 패킷을 재전송한건지, 아니면 ACK 손실없이 새로운 패킷을 보낸 건지 알 길이 없다.
그래서 윈도우 크기는 SR프로토콜에 대한 순서번호 공간 크기의 절반보다 작거나 같아야 한다.
(전체 ACK가 다 손실나더라도 한 바퀴 돌아서 윈도우 순서번호를 사용하는 불상사를 막을 수 있다,)
정리
각 패킷들이 타이머를 가지고,
송신자는 내가 보낸 패킷에 대해 ACK가 도착하지 않으면 타임아웃을 발생시키고 그 패킷을 다시 보냄.
수신자는 정상 순서의 패킷(즉 손실됐던 윈도우 베이스와 같은 순서번호를 가진 패킷)이 도착하면
그간 버퍼에 모아놨던 패킷들이랑 한번에 상위계층으로 보내고 윈도우를 올려보낸 패킷 수만큼 이동.
송신자는 내가 보낸 패킷 중 아직 ACK 못받았던 가장 작은 순서번호의 ACK가 도착하면 윈도우 한칸이동.
단 window 사이즈 유의.
**버퍼에 모아놨던 패킷들을 한번에 상위계층으로 보낼 때
손실됐었던 패킷에 대한 ACK만 보내는건지 아니면 버퍼에 있던 모든 순서번호에 대해 ACK 보내는건지
헷갈리는데 아마 손실됐던 패킷에 대한 ACK만 보내어서 송신측의 윈도우가 한칸만 이동해도
그 다음 패킷부터 정상 송신되고 수신측에서도 어차피 윈도우를 올려보낸 패킷 수만큼 이동해놨기 때문에
그 다음 패킷을 잘 받을 것이다...(확인 필요)**
**10/14 복습: SR 프로토콜은 개별 패킷에 대해 송신자에게 ACK 보내니까 송신자는 수신 측의 윈도우 안에
있는 각 패킷에 대한 수신 여부를 개별적으로 파악가능 -> 따라서 손실됐던 특정 패킷에 대한 ACK만 보냄**
chapter3 전까진 송신자와 수신자가 단일한 물리적 선으로 연결돼있다는 가정하에 패킷들의 순서가 바뀔 수 없었다.
그러나 둘을 연결하는 '채널'이 네트워크면 순서 바뀜이 일어날 수 있고 순서번호가 재사용될 수 있으므로
중복된 패킷들을 막을 수 있는 조치가 있어야 한다. 송신자가 순서번호 x를 가진 이전에 송신된 패킷들이
더 이상은 네트워크에 없다는 것을 확신할 때까지 순서번호가 재사용되지 않음을 확실히 한다.
대략 3분의 최대 패킷 수명 시간이 TCP확장에 가정되어있다.
3.5 연결지향형 트랜스포트: TCP
TCP: 두 프로세스가 서로 핸드셰이크를 먼저 해야하는 연결지향형 연결
데이터 전송을 보장하는 파라미터들을 각자 설정하기 위한 사전 세그먼트들을 보내야 함.
TCP "연결" 은 회선교환 네트워크에서의 TDM, FDM이나 가상회선 네트워크 같이 종단 시스템 사이에서의 연결이 아닌,
종단 시스템에서만 동작하고 중간의 네트워크 요소(라우터, 브리지 등)에선 동작하지 않는 연결이다.
전이중 서비스 제공, 단일 송신자와 단일 수신자 사이의 point to point 연결
클라이언트가 먼저 특별한 TCP 세그먼트를 보내면 서버는 두번째 특별한 TCP 세그먼트로 응답하고,
클라이언트가 세번째 특별한 세그먼트로 다시 응답 => 세 방향 핸드셰이크
(처음 두개의 세그먼트 - 페이로드x(어플리케이션 계층 데이터x), 세번째 세그먼트는 페이로드 포함 가능)
#TCP 연결 설정 - 클라이언트 프로세스에서 소켓으로 데이터 스트림 전달 - 송신 버퍼로 데이터 저장-
*최대 세그먼트 크기(MSS)로 데이터 전송 가능(이 때 크기는 최대 전송단위, TCP 세그먼트, TCP/IP 헤더길이가
단일 링크 계층 프레임에 딱 맞게 정해짐)
*MSS는 TCP 세그먼트의 최대 크기가 아닌 세그먼트에서의 어플 계층 데이터에 대한 최대 크기
TCP헤더 + 클라이언트 데이터 = TCP 세그먼트
#세그먼트는 네트워크 계층으로 전달 - 네트워크 계층 IP 데이터그램에 캡슐화 됨 - 세그먼트 수신받은 수신측은
수신 버퍼에 저장 - 이 버퍼에서 수신측이 데이터 스트림을 읽음.
TCP 세그먼트 구조
헤더 + 데이터 필드(MSS로 크기제한)
헤더: 출발지/목적지 포트 번호, 순서번호 필드, 확인응답번호 필드, 수신 윈도우(for 흐름제어), 헤더길이 필드,
옵션필드(선택적, 가변적 = MSS를 협상하거나 윈도우 확장 요소로 이용), 플래그 필드, 긴급 데이터 포인터 필드
플래그 필드: ACK(확인응답 필드 유용성판단), CWR/ECE(명시적 혼합 표시), RST/SYN/FIN(연결 설정과 해제),
PSH(데이터를 상위 계층에 즉시전달), URG(긴급으로 표시하는 데이터)
순서번호 & 확인응답번호
순서번호: 일련의 전송된 세그먼트에 대해서가 아닌 전송도나 바이트 스트림에 대한 번호.
500,000 바이트 파일에 대해 MSS가 1000바이트면 500개의 세그먼트로 나뉨.
첫번째 세그먼트 순서번호가 0이면 두번째 세그먼트 순서번호는 1000 이런식으로 할당.
확인번호: 호스트A 확인응답 번호는 A가 호스트 B로부터 기대하는 다음 바이트의 순서번호.
ex) 0~535 바이트를 포함하는 세그먼트와 900~1000바이트를 포함하는 세그먼트를 수신한다면
A는 536을 확인응답번호 필드에 넣고 대기중이기 때문에 900~1000 세그먼트 다음으로 536 바이트를 기다린다.
TCP는 스트림에서 첫번째 잃어버린 바이트까지의 바이트들까지만 확인응답하기 때문에 TCP는 누적 확인응답.
위의 예시처럼 세그먼트 순서가 틀리게 도착하면 TCP는 개발자에게 선택을 맡긴다.
1. 순서가 틀린 세그먼트를 즉시 버리거나
2. 순서가 틀린 데이터를 보유하고 있다가 빈 공간 데이터를 채우고나면 저장한 데이터를 다시 사용
클라이언트에서 서버로 쏘는 첫번째 세그먼트와 서버에서 클라이언트로 쏘는 두번째 세그먼트는
데이터필드에 데이터를 가지는 반면 클라이언트에서 서버로 쏘는 (두번째 세그먼트에 대한)ACK는 데이터 필드가 빔.
서버와 클라이언트 간에서 데이터를 운반하는 세그먼트 안에서 확인응답을 주고받기 때문에 이를 피기백 된다고 말함.
==========================================================
왕복시간(RTT) 예측과 타임아웃
타이머는 얼마나 커야할까? 첫 RTT는 어떻게 측정할까? 수신되지 않은 세그먼트는 타이머와 연관되어야 하나?
왕복시간 예측(RTT)
sampleRTT: 세그먼트가 송신된 시간 ~ 긍정 ACK가 도착한 시간 길이
이 샘플은 모든 세그먼트에 대해 측정하지 않고 한번에 하나의 샘플만을 측정.
즉 왕복마다 sampleRTT를 새로 얻고 재전송한 세그먼트에 대해선 계산x
그래서 sampleRTT들의 가중 평균값(EstimatedRTT)를 측정하고 사용.
EstimatedRTT = 0.875*EstimatedRTT + 0.125sampleRTT
RTT변화율인 DevRTT는 sampleRTT와 EstimatedRTT 값 차이의 EWMA이다.
타임아웃
TCP 타임아웃 주기는 EstimatedRTT보단 커야 불필요한 재전송을 줄이겠지..
근데 너무 크면 세그먼트를 잃었을 때 즉각적인 재전송을 하지 않겠지..
그래서 DevRTT까지 참고해서 EstimatedRTT보다 약간만 크거나(DevRTT작으면) 적당히 크게(DevRTT 크면) 만든다.
TimeoutInterval = EstimatedRTT + 4*DevRTT. (타임아웃 발생시 두배로 갱신)
==========================================================
신뢰적인 데이터 전달 서비스
자신의 수신 버퍼로부터 읽은 데이터 스트림이 손상되지 않고 순서유지를 보장해주는 것
개별적인 타이머가 전송됐지만 확인응답 못받은 각 세그먼트와 한쌍이 되어 동작한다고 했는데,
이는 상당한 오버헤드를 요구할 수 있어서 TCP 타이머 관리 절차에선 오직 단일 재전송 타이머를 사용한다.
1. 타임아웃만을 사용하는 TCP 2. 중복확인응답까지 사용하는 TCP
송신자
1. TCP가 어플로부터 데이터 받아서 세그먼트로 캡슐화하고 IP에게 넘기면 타이머 시작
2. 타임아웃 이벤트를 일으킨 세그먼트는 재전송하고 타이머 재시작
3. 수신자로부터 ACK받으면 변수 SendBase랑 ACK값을 비교.
SendBase는 수신 확인응답이 안된 가장 오래된 바이트 순서번호이기 때문에
ACK > SendBase면 ACK는 이전에 확인응답 안된 하나 이상의 세그먼트를 확인해줘야 함.
송신자는 확인응답받고 나서 자기의 SendBase 변수를 ACK 받은 값으로 갱신한다.
아직도 확인응답 안된 세그먼트 있으면 타이머를 다시 킴
흥미로운 시나리오
1. 호스트 A가 보낸 세그먼트가 B에 잘 도착했는데, B가 보낸 ACK가 손실돼서 A가 타임아웃된 세그먼트를 다시 보내면
B는 순서번호를 읽어보니 이미 받은 세그먼트네? 하고 버려버림.
2. 호스트 A가 두 세그먼트를 보냄. 첫 세그먼트는 ACK못받아서 다시 보냈는데,
그후 다시 보낸 세그먼트의 타임아웃 간격동안에 두번째 세그먼트에 대한 ACK는 받았으면 두번째 세그먼트는 다시 안보냄.
3. 호스트 A가 두 세그먼트를 보냄. 첫 세그먼트는 2처럼 ACK 못받아서 다시 보냈는데,
근데 첫번째 세그먼트의 타임아웃도 전에 첫번째 세그먼트의 ACK는 못받았지만 두번째 세그먼트의 ACK를 받으면
어..? 잘 도착했나보네 이렇게 알게되어서 더 이상 세그먼트 재전송x
타임아웃 발생 시 타임아웃 주기 두배로 설정
어느정도의 혼잡제어를 제공함. 타이머 만료는 보통 네트워크 혼잡에 의해 발생하기 때문에..
가뜩이나 혼잡한 네트워크에 계속 패킷 재전송하면 더 복잡해지겠지?
그래서 송신자가 더 긴 간격을 두고 재전송하게 하고, 늘어난 타임아웃 주기 동안 손실되지 않은 그 다음 패킷들이
위의 흥미로운 시나리오 2번, 3번처럼 생길수도 있으니 시간을 두고 지켜보도록 하는 것.
빠른 재전송
타임아웃 주기가 너무 길어버리면 잃어버린 패킷을 다시 보내기 전에 송신자를 오랫동안 기다리게 해서 지연시간 커짐..
근데 중복 ACK에 의한 타임아웃이 일어나기 전에 패킷 손실을 발견하면 TCP는
세그먼트의 타이머가 다 만료되지 전에 그냥 재전송해버림.
*중복 ACK: TCP는 NAK를 보내지 않기 때문에 수신자는 마지막으로 수신된 순서적인 데이터를 기준으로
다시 ACK를 쏴버리기 때문에 생기는 중복 ACK.
중복 ACK를 여러개 수신하는 경우 그냥 그 ACK에 대한 세그먼트를 빠른 재전송 해버리는 것.
TCP는 GBN인가? SR인가? => 결론: 둘을 혼합한 것이다.
송신되고 확인응답 안된 바이트의 가장 작은 순서번호를 유지하는 측면에서 GBN과 유사.
그러나 올바르게 수신되었지만 순서가 바뀐 세그먼트들을 버퍼링하기에 SR과 유사.
n < N인 긍정 확인응답이 손실되고, 나머지 N-1 응답은 타임아웃 전에 송신측에 잘 도달했다고 가정하면
GBN은 패킷 n뿐만 아니라 n, n+1, n+2... N까지를 싹 다 재전송하지만
TCP는 n만 재전송하기 때문에 GBN과 차이가 있음.
(심지어 n의 타임아웃 전에 n+1에 대한 긍정확인을 받게되면 n조차 안쏴버리는 똑똑한 놈임.
위의 흥미로운 시나리오 3번 케이스)
선택적 확인응답: TCP 수신자가 마지막으로 올바르게 수신된 순서가 맞는 세그먼트에 대해
누적 확인응답을 하기보다 순서가 틀린 세그먼트에 대해 선택적으로 확인응답을 하게 하여
선택적 재전송과 결합하면 SR프로토콜과 유사
흐름제어
흐름제어 서비스: 수신자의 버퍼를 오버플로 시키는 것 방지.
수신자가 읽는 속도와 송신자가 전송하는 속도를 맞춰줌.
(혼잡제어는 IP네트워크에서 억제될 수 있는 송신쪽을 컨트롤하는 것으로 흐름제어완 다름, 3.6에서 다룸)
송신자가 수신 윈도우라는 변수를 유지하여 수신 측에서 가용한 버퍼공간이 얼마나 되는지를 파악한 후 흐름제어 제공.
수신측에서 자기 버퍼 크기를 송신측에 보내준다.
LastByteRead: 수신 호스트의 어플 프로세스에 의해 버퍼로부터 읽힌 데이터 스트림의 마지막 바이트의 수
LastByteRcvd: 수신 호스트에서 네트워크로부터 도착하여 수신 버퍼에 저장된 데이터 스트림의 마지막 바이트의 수
LastByteRcvd - LastByteRead <= RcvBuffer
rwnd = 수신 윈도우 = 버퍼의 여유 공간 = RcvBuffer -[LastByteRcvd - LastByteRead]
시간에 따라 여유공간은 변하므로 rwnd는 동적이다.
수신 호스트는 rwnd = RcvBuffer로 초기 세팅을 하고,
송신 호스트는 [LastByteRcvd - LastByteRead]를 유지하여 자기가 보냈는데 확인응답을 못받은 데이터 양을
rwnd보다 작게 유지함으로써 오버플로우를 방지한다.
근데, B의 수신 버퍼가 rwnd=0으로 가득 차면 나중에 버퍼를 비우더라도 B에서 A로 먼저 보낼 게 없는 이상,
A는 B가 버퍼 공간이 생기더라도 알 수가 없는 문제 발생..
이를 해결하기 위해 호스트 A가 호스트 B의 rwnd가 0이면 1바이트 데이터로 세그먼트를 계속 쏘도록 요구해서
버퍼가 비워지는지 확인한다.
TCP 연결 관리
- 클라이언트 TCP는 서버 TCP에게 특별한 세그먼트(어플 계층 데이터 x, 헤더에 SYN비트 포함)를 송신.
- 이 SYN 세그먼트의 순서번호 필드에 최초의 순서번호를 넣음.
- IP 데이터그램 안에서 캡슐화되고 서버로 송신됨.
- 서버에 도착하면 서버는 TCP SYN 세그먼트를 뽑아냄
- 그리고 연결에 TCP 버퍼와 변수들을 할당한 후 클라이언트 TCP로 *연결 승인 세그먼트를 쏨
*연결 승인 세그먼트(SYNACK 세그먼트)도 어플계층 데이터 안가진 상태로 다른 3개의 중요한 정보를 포함.
1. SYN 비트는 1
2. TCP 세그먼트 헤더의 확인응답 필드 = client_isn + 1
3. 서버는 자신의 최초의 순서번호를 선택하고 TCP 세그먼트 헤더의 순서번호에 넣음.
- 위 세 단계가 완료되면 클라이언트와 서버 호스트들은 각각 서로에게 데이터를 포함하는 세그먼트를 보낼 수 있으며
이 데이터를 포함하는 세그먼트들의 SYN 비트는 0
TCP 연결 종료
TCP 연결이 끝날 땐 호스트의 자원(변수와 버퍼들)은 회수됨.
FIN 비트를 1로 설정한 세그먼트를 서버가 받으면 서버는 확인 세그먼트를 보낸 후 FIN 비트 1로 설정된
자신의 세그먼트를 송신. 이 종료 세그먼트에 클라이언트가 확인응답하면 연결 종료.
#클라이언트 TCP
- SYN 보내고 나면 SYN_SENT 상태
- SYN과 ACK 수신 후 ACK 쏘고 나면 ESTABLISHED 상태(페이로드 데이터 포함한 TCP 세그먼트 주고받기 가능)
- FIN 전송 후 FIN_WAIT_1 상태, ACK 받고나면 FIN_WAIT_2 상태
- 이제 FIN 받고 ACK 보내면 TIME_WAIT 후 30초뒤 CLOSED
#서버 TCP
- CLOSED 상태에서 listen socket 생성하고 LISTEN 상태
- SYN 수신한 뒤 SYN과 ACK 송신하고 SYN_RCVD 상태
- ACK 받고 나서 추가 송신 없이 ESTABLISHED
- FIN 받고 ACK 보내면 CLOSED_WAIT 상태
- FIN 보내고 LAST_ACK 상태
- ACK 받으면 CLOSED
+ 호스트가 호스트 내부에서 소켓과 관계없는 포트번호와 출발지 IP 주소 가진 세그먼트 수신한다는 가정을 하면
출발지로 리셋 세그먼트를 보냄(RST 플래그비트가 1)
3.6 혼잡제어의 원리
네트워크 혼잡 원일을 처리하기 위해선 송신자에서부터 억제하는 메커니즘 필요
시나리오1: 2개의 송신자와 무한 버퍼를 갖는 하나의 라우터
연결당 처리량(수신자 측에서의 초당 바이트 수) // 공유 출력 링크 용량 = R
0~ R/2 사이의 전송률에서 수신자 처리량 = 송신자 전송률
R/2 이상일 때 처리량 = R/2 // 즉, 처리량은 R/2로 상한
근데 지연률 측면에서 전송률이 R/2에 가까워질수록 라우터 안에 큐잉된 패킷의 평균 지연이 무제한이 됨..
(=패킷 도착률이 링크 용량에 근접함에 따라 큐잉 지연이 커짐)
시나리오2: 2개의 송신자, 유한 버퍼를 가진 하나의 라우터
버퍼가 가득 찰 땐 패킷이 버려지고 신뢰적 연결에선 이 버려진 패킷들을 재전송해야 함.
원래 데이터 + 재전송 데이터까지 전송하는 송신율 = 제공된 부하
1. 송신 호스트가 어떻게든 버퍼가 비어있는지 알 수 있고 비어있을 때만 보낸다고 가정하면
패킷 손실이 일어나지 않고 평균 호스트 송신율은 최대 R/2이다.
2. 위의 가정 없이, 패킷이 손실된 것을 앎으로써만 송신자가 재전송하는 경우,
제공된 부하 값이 R/2라면 수신자 어플로 전달되는 데이터 전송률은 R/3이다.
3. 거기다가 커다란 지연으로 인해 송신자가 불필요한 재전송을 하는 경우,
각 패킷이 라우터에 두 번식 전달된다는 가정하에 제공된 부하가 R/2이면 처리량은 R/4이다.
시나리오3: 4개의 송신자와 유한 버퍼를 가지는 라우터, 그리고 멀티홉 경로
한 라우터를 지나는 링크가 2개 있을 때, 두 링크의 트래픽은 해당 라우터의 버퍼 공간에서 경쟁하여 나눠가지기 때문에,
한 링크에서 제공된 부하가 크면 나머지 링크에서 트래픽 양이 줄어들고, 극단적으론 한 링크의 제공된 부하가 무한대라면
나머지 링크의 처리량은 0까지 떨어진다.(=제공된 부하와 처리량 간의 Trade-off 발생)
혼잡 때문에 패킷을 버려야 하는 경우, 버려지는 지점까지 패킷을 전송하는데 사용된 상위 라우터에서 사용된 전송량이
헛된 노력이 된다,,
혼잡제어 접근법
종단간의 혼잡제어: 네트워크 계층은 혼잡제어를 위한 지원을 전송 계층에게 지원 x
네트워크에서 혼잡은 종단 시스템이 알아서 추측, TCP가 혼잡제어를 위한 종단간의 접근을 수행.
TCP는 윈도우 크기를 줄임.
네트워크 지원 혼잡제어: 네트워크 계층 구성요소가 혼잡상태와 관련하여 송신자에게 직접적 피드백을 제공.
ATM안에서 ABR(available bir-rate)혼잡제어로 사용.
라우터 자신이 출력 링크에 제공할 수 있는 전송률을 송신자에게 알려줌( 나 혼잡해~ 라고 말함)
이 전송률을 라우터가 송신자에게 바로 초크 패킷의 형태로 말할 수도 있고,
수신자가 송신자에게 패킷 보낼 때 특정 필드에 내용 담아서 보낼 수도 있음.
3.7 TCP 혼잡제어
TCP는 IP계층에서 피드백을 안주기 때문에 네트워크 지원 혼잡제어보단 종단간의 혼잡제어를 사용해야 한다.
TCP: 네트워크 혼잡에 따라 연결에 트래픽을 보내는 전송률을 각 송신자가 제한하도록 함.
1. 송신자는 트래픽 전송률을 어떻게 제한하는가?
- 송신측에서 TCP 메커니즘은 수신 버퍼, 송신 버퍼, LstByteRead 등의 변수 + 혼잡 위도우(cwnd)
*혼잡 윈도우 - 트래픽을 전송할 수 있는 비율을 제한. 송신쪽에서 확인응답안된 데이터 양 < min(cwnd, rwnd)
수신 버퍼가 매우 크고 혼잡 윈도우 안에 있는 모든 세그먼트는 송신된다고 가정할 때,'
송신자의 확인응답 안된 데이터 크기는 제한되고, 그에 따라 송신율을 간접 제한한다.
2. 송신자는 자신과 목적지 사이의 혼잡 정도를 어떻게 감지하는가?
- 타임아웃 또는 수신자로부터 중복된 3개의 ACK를 받았을 때 송신자 측에 손실 이벤트가 발생했다고 가정
(라우터의 오버플로 때문에 데이터그램이 버려짐) 송신자는 손실이벤트를 통해 경로상의 혼잡을 알게되고,
TCP는 확인응답을 혼잡 윈도우 크기를 증가시키는 트리거 또는 clock으로 사용하므로
(확인응답이 늦으면 혼잡 윈도우를 천천히 증가시키고 빨리 도착하면 혼잡윈도우를 빨리 증가시킴)
TCP는 자체 클로킹(self- clocking)이라 불림.
3. 송신자는 송신율을 변화시키기 위해 어떤 알고리즘을 쓰는가?
- cwnd 값을 조정하는 메커니즘이 주어지면, 어떻게 TCP 송신자가 송신속도를 결정할까.
손실된 세그먼트가 있으면 혼잡, 손실없이 확인응답된 세그먼트가 잘 도착하면 혼잡x로 판단.
그럼 ACK가 도착함에 따라 전송률을 조금씩 늘리다가 손실 이벤트 발생하면 다시 좀 줄이고를 반복
TCP 혼잡제어 알고리즘(1. 슬로우 스타트, 2. 혼잡 회피, 3. 빠른 회복) (1과 2는 TCP의 필수요소)
슬로 스타트: TCP 연결 시 cwnd값은 일반적으로 1MSS로 초기화 되고 초기 전송률은 대략 MSS/RTT이다.
TCP 송신자에게 가용 팬드폭은 이보다 훨씬 클 것이므로 확인응답을 받을 때마다 1MSS씩 cwnd값을 늘리면서
가용 밴드폭 양을 찾는다. 1MSS만큼 cwnd를 증가시키고 2개의 "최대-크기" 세그먼트를 보내기 때문에
2의 지수승만큼 지수적으로 TCP 전송률이 증가한다. 그러다가 이제
1. 타임아웃에 의한 손실 이벤트를 만나거나 - cwnd를 1로 하고 새로운 슬로 스타트 시작
2. ssthresh값(혼잡이 마지막으로 검출된 시점에서의 cwnd의 절반)이 cwnd과 같으면 -
슬로스타트를 종류한 후 혼잡 회피모드로 변경- 혼잡 회피모드에선 전송률이 2배씩이 아니라 더 천천히 증가.
3. 3개의 중복 ACK 검출 - 빠른 재전송을 수행하여 빠른 회복 상태로 돌입.
혼잡 회피: 혼잡회피 시점에서 cwnd값은 혼잡 마지막 발생 시점의 절반정도이다.
저때부터 ACK 마다 1/10 MSS만큼씩 증가시키는 등, 2배보다 적은 양으로 속도를 줄인다.
혼잡 회피의 RTT 당 1MSS 증가는 타임아웃이 발생했을 때처럼, cwnd값을 1로 바꾸고 ssthresh값이
cwnd의 절반이 되면서 증가를 멈추고 천천히 증가하는 모드로 바뀐다.
빠른 회복: 빠른 회복 모드에서 cwnd값은 잃었던 세그먼트에 대한 매 중복된 ACK를 수신할 때마다 1MSS씩 증가.
타임아웃 발생하면 마찬가지로 cwnd를 1MSS로 바꾸고 ssthresh값은 손실 이벤트 발생 때의 cwnd 절반으로 바꾼 후
슬로우 스타트 모드로 바꿈.
==========================================================
공평성
Rbps의 전송률인 병목 링크를 지나는 K개의 TCP 연결이 있을 때 각 연결의 평균 전송률이 R/K에 가까울수록
혼잡제어 메커니즘이 공평하다고 말한다.
두개의 연결이 링크 대역폭을 같이 공유한다는 가정을 할 때, 두 연결은 같이 윈도우 크기가 점점 작아지고
손실이벤트 발생 시 같이 윈도우를 감소시키는 식으로 나란히 수렴하도록 움직인다.
*UDP는 다른 연결과 협력하지도 않고, 전송률을 조절하지도 않으며 일정한 속도로 전송률을 차지한다,
(UDP 트래픽이 커지면 TCP 트래픽까지 침범하여 밀어낼 수도 있다,,)
다중 병렬 연결 TCP
원래 각 어플은 하나의 TCP 연결을 사용하여 10개의 어플이 있으면 전송률 R인 링크를 R/10씩 나눠가지는데,
어떤 어플이 11개의 병렬 TCP연결을 사용한다면 그 어플은 R/2보다도 많은 불공평한 할당을 얻게 된다..
명시적 혼잡 표시(ECN)
TCP는 네트워크 계층으로부턴 어떠한 명시적 혼잡표시를 받지 않고 패킷의 손실로부터 혼잡을 추측했다.
최근에는 네트워크가 명시적으로 TCP 송수신자에게 혼잡을 알리는 IP와 TCP의 확장도 제안되고 구현되고 있다.
네트워크 계층에선 IP 데이터그램 헤더의 서비스형식 필드 내의 두 비트가 ECN에 사용된다.
첫 비트는 라우터가 경험하는 혼잡을 표시하는데, IP 데이터그램에 의해 목적지 호스트로 전송되어
혼잡을 알리고, 이 목적지 호스트가 송신호스트에게 혼잡을 전달한다.(TCP ACK 세그먼트에 담아서 보내고
이를 받은 송신 TCP는 cwnd를 반으로 줄인다.)
두 번째 비트 세팅은 송신 호스트에서 사용하여 라우터에게 송신자와 수신자가 ECN-가용하다는 것을 알려서
(TCP 세그먼트 헤더 중 CWR 비트에 세팅한다.) ECN-표시된 네트워크 혼잡에 대응할 수 있음을 알린다.
기타
DCCP(데이터 혼잡제어 프로토콜) - 낮은 오버헤드, 메시지 지향형, 비신뢰성 서비스, TCP와 호환,
semi 신뢰적인 데이터 전송 기능 제공 (데이터 전달의 적시성과 신뢰성간의 Trade-off를 이용할 수 있게 한다.)
QUIC(구글) - 재전송, 오류수정, 빠른 연결 설정, 속도기반 혼잡제어 등 제공
SCTP(스트림 제어 전송 프로토콜) - 서로 다른 여러 개의 어플레벨 스트림을 하나의 SCTP 연결로 다중화되게
하는 신뢰적, 메시지 지향적 프로토콜.
'CS > Computer Network' 카테고리의 다른 글
[컴퓨터 네트워크 하향식 접근] Chapter06 링크 계층 (0) | 2024.08.06 |
---|---|
[컴퓨터 네트워크 하향식 접근] Chapter05 네트워크 계층: 제어 평면 (0) | 2024.08.04 |
[컴퓨터 네트워크 하향식 접근] Chapter04 네트워크 계층: 데이터 평면 (0) | 2024.08.03 |
[컴퓨터 네트워크 하향식 접근] Chapter02 애플리케이션 계층 (0) | 2024.07.26 |
[컴퓨터 네트워크 하향식 접근] Chapter01 컴퓨터 네트워크와 인터넷 (1) | 2024.07.21 |