트랜스포트 레이어 서비스
트랜스 포트 레이어
서로 다른 호스트들 간에 동작하고 있는 프로세스 들 사이에서 발생하는 논리적인 커뮤니케이션 링크를 만들어 주는 역할
엔드 시스템(호스트)에서 돌아가는 형태
-send side: 앱 메세지를 세그먼트 단위로 나눔-> 헤더를 붙임 -> 네트워크 레이어에 전달
-rcv side: 세그먼트 재조합해 메세지로 만듬 -> app 레이어에 전달
TCP 특징
- 혼잡(congestion) 컨트롤
- 흐름(Flow) 컨트롤
- 커넥션 셋업
- 세그먼트 = 트랜스포트 레이어 패킷
멀티플렉싱과 디멀티플렉싱
- 프로세스는 하나 혹은 여러개의 소켓을 가지고 있음
- 소켓= 네트워크로부터 프로세스로 가는 문
- 각 소켓은 식별자(identifier)있음
전송 방식
- 트랜스포트 레이어는 소켓에 데이터 보냄, 어플리케이션 레이어도 소켓에 데이터 넣어줌.
멀티 플렉싱
프로세스가 네트워크를 이용 -> 소켓을 만듬 ->프로세스들은 하나 이상 소켓 있음 -> 소켓에 할당된 identifier로 헤더를 만듬 + 소켓에는 하나의 포트번호가 할당 => 1024~65535까지 랜덤하게.
디멀티 플렉싱
데이터들이 Transport 레이어에 전달이 될됨 -> 각 헤더를 보고 어플리케이션 레이어에 관련된 소켓으로 위로 올려줌
멀티플렉싱 필요 요건
- 소켓은 각 아이덴티파이어를 갖고 있음. 각 세그먼트들이 이 아이덴티파이어를 포함하도록 트랜스포트 레이어에서 헤더를 붙여줌.
따라서 소켓 헤더의 source, dest port에 이 아이덴티 파이어 정보가 담겨.
UDP 멀티&디멀티 플렉싱 통신 방법
호스트가 보낼때
- UDP 소켓에서는 dst 포트, dst IP주소로 소켓 식별. 같으면 패킷이 포워딩.
서버가 보낼때
- 자신이 받은 세그먼트에서 소스포트 번호 뺴낸 후에 이를 dst 포트번호로 사용하고 소스포트는 내꺼 번호 넣음.
TCP 통신 방법
- src IP,src port, dst IP, dstPort 가 필요
- UDP 와 달리 커넥션관리를 해야하기 때문에 유의미한 식별자가 더 필요
- 4가지 식별자(+소스 IP,Port)를 보고 소켓 식별(-> 웹 서버 트랜스 포트 레이어는 디멀티플렉싱을 수행
UDP
특징
- 혼잡 컨트롤 x
- 커넥션 x => 빨라 but 순서 어긋날 수 있음
- 헤더 사이즈 작음
UDP 세그먼트 구조
- 소스포트, dest 포트, length(app 쪼개진 길이 + 전체 헤더 크기), Checksum(UDP에 에러 있는지 없는지) ,app data(쪼개서)
Checksum 사용이유
- 라우터가 고장나서 링크레이어의 에러 체크 오류날 수 도 있어서
- 네트워크 라우터에서 데이터 오류날 수 있어서
reliable 데이터 트랜스퍼 원칙
rdt 1.0 이상적인 채널
sending side
rdt_send 발생했을때
- 패킷 만들고 -> 네트워크를 통해 unreliable 전송해(이상적 환경이니 잘 전송됨)
receiving side
rdt_rcv 발생했을때
- 에러 없음 -> 패킷에서 데이터 받음 ->데이터를 상위 레이어인 어플리케이션 레이어로 전달
rdt 2.0 에러있는 현실적 채널
- 데이터를 잘 받았으면 ACK 날려줌
- checksum 돌렸는데 에러 있으면 NAK 날려줌
sending side
rdt_send 발생했을때
- 패킷 만들고 -> udt_send를 통해 패킷 전송해-> 끝이 아니라 ACK or NAK 기다림(새 패킷 못받는 상태) -> rdt_rcv 한테 NAK 받으면 재전송 or 리시빙 사이드에게 ACK 받으면 다시 웨이팅 상태로
rdt_rcv 일때
- 패킷을 받은게 오류 있으면 NAK 보냄
-corrupt 되서 NAK 받으면 원래 받았던 패킷 재전송
receiving side
rdt_rcv가 corrupt 일때
- 패킷 문제 있으면 NAK 패킷 만듬 -> 송신자에게 NAK 보내고 기다림
rdt_rcv가 notcorrupt 일때
- 패킷에서 데이터 추출 -> 데이터 상위 레이어(어플레이어)로 보내 -> 송신자에게 ACK 보내줌
rdt 2.1 ACK,NAK도 오염되었을 경우의 대안
- 센더는 현재 패킷이 ACK랑 NAK이 corrupted 됐을때만 재전송해야함
- 각 패킷에 시퀀스 넘버 할당
- 중복 패킷이 전송되었을 경우에는 버림
sending side
- 패킷 A는 0 , 패킷 B는 1로 가정
- 초기 상태는 어플리케이션 레이어에서 패킷 0을 기다리는 상태
rdt_send 일때
- 패킷 0을 만드는데 데이터를 넣고, checksum 값 추가함->udt_send로 패킷 전송->패킷 0에 대한 ACK or NAK 기다리는 상태 -> NAK 받으면 다시 재전송
- 1번 패킷을 어플리케이션 레이어로 부터 받으면 -> 1번 패킷을 만듬(checksum넣고) ->udt_send로 패킷 전송 -> 패킷 1에 대한 ACK or NAK 기다리는 상태 -> NAK 받으면 다시 재전송
rdt_rcv
- 패킷 0 을 잘못받았으면 NAK 보내줌 or ACK라면 1번 패킷을 기다리는 상태로 변환
- 패킷 1 을 잘못받았으면 NAK 보내줌 or ACK라면 다시 0번 패킷을 기다리는 상태로 변환
receiving side
- 초기 상태는 0번 패킷이 왔을 때를 기다리는 상태 -> 오류 있으면 패킷 만들어(NAK 와 checksum 넣어서) -> 응답 보냄 -> 0번 다시 기다림
- 정상 패킷 받으면 데이터를 어플리케이션 레이어로 올림-> ACK 보내고 1번 기다리는 상태 -> 순환
- ACK가 오염되어서 센더가 재전송했을때 -> 0번 패킷 기다리는데 1번패킷 옴 -> 1번패킷 받았다고 ACK 보내줌, 데이터는 이미 받았으니까 버려
rdt 2.2 ACK 만 있는
- 마지막으로 완벽하게 수행한거에만 ACK 보냄
- 보낸 패킷에 대한 ACK 안오면 다시 보내
rdt 3.0
- 2.1, 2.2 와 달리 패킷로스에 대비할 수 있음
-타임 아웃에 의해 중복됨을 알고 있지만 받으면 중복 ack를 보내
- 기능적으로는 좋지만 But, 네트워크 속도가 너무 느림 => stop & wait 떄문
파이프 라인
- 기존 파이프라인은 U(sender) 유효시간동안 패킷을 얼마나 보내는지 = (L/R)/(RTT+L/R)임 = 찐 패킷 보낸시간/총시간.
- 이게 형편없는 경우 많아서 = >파이프 라인프로토콜 등장
그러기 위해서..
- 시퀀스 라인 범위 늘어나야해
- ACK를 기다리는 패킷을 버퍼링 하는 버퍼가 필요해
중간중간 유실된 패킷 retrans 전략
GO-back-N
- 유실된 패킷을 기준으로 다시 한 뭉태기를 보내줌
- 여러개의 패킷을 보내야해서 range 커, TCP 헤더에 seq 넘버도 있어야해
윈도우 내부
- base : 아직 ACK되지 않은 놈 중에 번호 최상단인 애 + base를 기준으로 timer 세팅=> 타이머 차면 base부터 윈도우 크기만큼 전송~
- nextseqnum : 윈도우에서 아직 사용되지 않은 놈 중에 번호 최상단인 애
- ACK(n) : cumulative ack라고 하며, 1~n번까지 ack 완료!
GBN 동작원리
sender
- 타임아웃 되면 base~윈도우 크기만큼 재전송
receiver
- 내가 받은것 중에서 젤 최신놈을 ACK
- 내가 기다리는 놈 안오면 그 위에 놈들 다 버리고 계속 동일 ack
Selective Repeat
- 잃어버린 하나만 따로 보내줌
- gbn과 다르게 리시버에서도 윈도우가 관리됨
sender
- ack 받으면 윈도우 움직여
- timeout 되면 그 놈만 다시 보내
receiver
- send 받으면 ack 보내고 윈도우 한칸씩 밀어
- gbn과 달리 순서대로 안받아도 ack 보내줘
- timeout 되서 send 받으면 받은건 윈도우 껑충 뛰어. 안받은 놈부터 윈도우 base 시작
정리
TCP가 reliable할 수 있는 이유
checksum
Timer
Sequence num
ACK
(NAK)
Window, pipelining
- 윈도우 기반으로 n개의 패킷을 보내는 파이프라인
- 이때 패킷 로스들을 처리하기 위해서 -> GBN,Selective repeat