컴퓨터 네트워크 - Transport 계층
K-MOOC에서 부산대학교 유영환 교수님의 “컴퓨터 네트워킹” 강의를 수강하며 적은 노트
Transport Layer Services
프로그램(program): 하드 디스크에 저장되어 어떤 specific한 일을 하기 위한 명령어들을 모아 둔 실행 파일
프로세스(process): 프로그램이 메모리에 올라와 동작하는 instance. 하나의 프로그램으로 여러 개의 프로세스 가능
전송 계층: 프로세스들 간의 논리적인 연결.
- 네트워크 레이어는 IP 프로토콜을 사용하는데, 각각의 컴퓨터에 할당된 IP주소만으로는 어느 프로세스에 전달하는지 알 수 없기 때문에 전송 계층이 이를 컨트롤
- 보내는 쪽: 애플리케이션의 메시지를 분할해서 segment에 담아 네트워크 레이어를 통해 전송
- 받는 쪽: 분할되어 온 segment들을 합쳐 원래의 메시지를 만들어 애플리케이션에게 전달
TCP(Transmission Control Protocol), UDP(User Datagram Protocol)의 차이
- TCP
- 신뢰성 있는(reliable) 전송. 보낸 순서 그대로 송신자에게 도착(in-order delivery). 실제로 순서대로 도착하는 건 아니고 애플리케이션 입장에서 그렇게 보이게 함
- Connection-oriented service
- 서킷 스위칭: 대표적으로 전화망, 자원이 두 송신자와 수신자에게 할당되어 끼어들지 못함, 신뢰성 있는 서비스.
- TCP: 인터넷 프로토콜은 패킷 교환 방식이지만, 서킷 스위칭처럼 안정적인 서비스를 제공하기 위해 connection 개념 도입
- connection: 둘 사이의 통신 전에 connection을 설정해 에러와 흐름 제어
- UDP
- 에러가 섞이거나 패킷 손실이 있거나 순서가 어긋날 수 있음
- Connectionless service
- connection 없이 그냥 아래 레벨의 인터넷 프로토콜의 능력에 맡김
- 전송 계층의 기본적 서비스만 제공하여 더 빠른 속도
Multiplexing and Socket
멀티플렉싱(Multuplexing): 전송 계층의 기본적 기능
- 하나의 컴퓨터에 여러 개의 프로그램, 프로세스가 동작하지만 하나의 공통 링크로 통신이 됨
- 동시에 내려오는 데이터들을 동일한 하나의 공유하고 있는 회선을 통해서 전달
- demultiplexing: 수신자의 입장에서 공유된 링크로 들어온 데이터들을 각각의 프로세스에게 전달
포트 넘버(port number): 애플리케이션마다 서로 다른 포트 넘버를 할당
- TCP, UDP 공통으로 세그먼트에 포트 넘버 필드 가짐
- 애플리케이션 레이어가 트랜스포트 레이어에 소켓(socket)을 사용해 포트 넘버를 지시 내림
- 소켓(socket): OS가 전송 계층과 응용 계층 사이 제공한 API(Application Program Interface)들의 집합. 프로세스들은 소켓 인터페이스를 통해서 데이터를 주고받음
- localhost에서 서버와 통신하기 위해 우선 커넥트를 설립해야 함
- 서버의 주소를 가진 컴퓨터의 프로세스들 중 해당 포트 번호로 연결
- 서버는 connection request를 보고 주소와 포트 번호를 확인 후 accept하여 연결 수립
- 포트 번호가 같은 경우
- 데이터를 보내기 전 커넥션을 설정하는 connection-oriented 프로토콜(TCP)에서만 생기는 문제
- 포트 번호 80번: 웹 서버가 사용하는 포트
- 커넥션은 수신자의 IP와 포트 번호 외에도 송신자의 IP와 포트 번호로도 구분
User Datagram Protocol
UDP(User Datagram Protocol)
- 부가적인 기능 없이 전송 계층 프로토콜의 가장 기본인 multiflexing, demultiflexing 기능만 제공되는 비 신뢰적 서비스
- 인터넷 프로토콜이 제공하는 완전히 신뢰성이 있지 않은 정도의 서비스를 그대로 애플리케이션 레이어에 전달
- connectionless service: 특별한 커넥션을 설정해서 데이터를 보내는 형태가 아니기 때문에, 각각의 UDP segment들은 독립적으로 취급
- 속도가 중요한 멀티미디어 응용, 도메인 네임 시스템, Simple Network Management Protocol에 사용
- UDP를 사용하는 애플리케이션에서 신뢰성 부분 직접 구현. UDP는 세그먼트에 에러 유무 정보 제공
UDP 세그먼트
- 헤더
- 4 byte(32 bit) = 한 워드(word) 단위
- source 포트 번호 16 bit
- dest 포트 번호 16 bit
- length 16 bit. 헤더를 포함한 길이 정보 = 헤더(4byte+4byte) + 데이터 길이
- checksum: 세그먼트의 에러 포함 유무를 판단할 수 있는 필드, 16 bit
- 어떤 필드의 비트에 에러가 있는지는 알 수 없음
- 송신자가 segment로 checksum을 만들고, 수신자도 수신한 segment로 checksum을 생성해 다르면 에러 O
- 송신자는 16 bit 단위로 세그먼트를 자름
- 첫 16 bit와 다음 16 bit를 겹쳐 합산
- 최상위 비트에서 carry 발생 시 밑으로 내려 1을 더함
- 그 다음 16 bit를 다시 sum 반복
- 최종 결과에 1의 보수 취함
- 체크썸 생성 전 그 자리는 0000으로 비어 있었으므로, 1의 보수를 취해주어야 수신자가 똑같은 방식으로 계산하면 16 bit가 모두 1이 됨
- 데이터
UDP의 장점
- UDP의 헤더는 TCP의 헤더보다 훨씬 간단하여 속도가 빠름. TCP 헤더의 40% 미만으로 네트워크 부담도 적음
- 커넥션 설립이 없고 지연 시간도 없어 세그먼트 각각 처리가 간단
- TCP의 congestion control이 없어 보내고 싶은 데이터는 원하는 만큼 보낼 수 있음
Reliable Data Transfer Principles
신뢰성 있는 서비스: 하위 레벨에서 발생한 에러를 트랜스포트 레이어의 서비스가 응용 프로그램에 보이지 않도록 감춰주어야 함
에러의 발생 형태
- 비트 에러(bit error)
- checksum으로 비트 에러가 없다면 ACK(Acknowledgement message) 전송
- 패킷 로스(packet loss)
- 타임아웃(timeout): 송신자가 데이터 전송 후 ACK가 올만 한 시간이 지났는데도 안 오면 패킷을 재전송함
- 만약 패킷이 제대로 왔는데 수신자가 보낸 ACK가 분실되어 송신자가 재전송한 경우
- 수신자는 해당 패킷이 아까 패킷의 재전송인지 내용이 같은 새로운 패킷인지 판단할 수 없음
- 따라서 패킷마다 일련 번호(sequence number) 부여하여 혼란 없앰
- 멀티미디어 데이터의 경우 패킷 도착 순서가 다를 수도 있지만, 시퀀스 넘버로 순서대로 조합
ARQ(Automatic Repeat reQuest): 신뢰성 있는 데이터 전송을 위해서 제안됨
stop-and-wait: 한 번에 하나의 세그먼트를 보내고 확인을 받고 다음을 보냄
- 만약 패킷이 분실된 경우 송신자는 타임 아웃까지 ACK가 안 오면 재전송
- 만약 ACK가 분실된 경우 송신자는 재전송, 수신자는 0, 1, 0, 1 순서대로 안 오고 같은 번호가 또 왔으므로 중복임을 알고 ACK만 재전송
- 타임 아웃 시간
- 타임 아웃이 길면 전체 전송 속도가 낮아짐
- 너무 짧으면 ACK가 좀 늦게 와도 이미 재전송해버려서 전체 네트워크 자원 낭비
- sender와 receiver 간의 왕복 시간인 round trip time을 고려해야 함
- ex) 한국과 미국 사이의 통신, 링크의 밴드위스 = 1 Gbps, 전파 지연 시간 = 15 ms, 패킷 하나 사이즈 = 8000 bit(1 kB)
- 1 kB 전송 시간(transmission delay) = L/R = 8000 bit / 1 Gbps = 8μs
- RTT = 전파 지연 시간 * 2 = 30ms
- utilization = (전송 시간) / (RTT + 전송 시간) = 0.008 / 30.008 = 0.00027. 즉 실제 걸리는 시간은 30.008 ms인데 실제 데이터가 전달되기 위한 전송 지연 시간은 8 μs 뿐으로, 전체 네트워크 자원 중 0.027%만 사용함
Pipelining method
- stop-and-wait 방식을 발전
- 하나의 패킷이 아닌 연달아 데이터를 보내 전체 utilization을 높임
- 같은 30.008 ms라도 패킷 3개를 보내면 24μs를 데이터 전송에 사용해 0.081%가 됨
- go-back-N
- 쭉 보내다가 수신자가 잘못된 부분을 응답하면 송신자는 그 부분부터 다시 보냄
- cumulative ack: 모든 패킷에 ack를 보내지 않고 n번째까지 잘 도착했다는 의미로 n번째에 패킷을 보냄
- 패킷마다 개별적인 타이머 필요 없이, 가장 먼저 보낸 패킷에만 타이머 설정
- 패킷 헤더에 시퀀스 넘버 있음, ack를 받지 않아도 한 번에 보낼 수 있는 데이터 사이즈인 윈도우(window) 정의
- 꼭 윈도우 사이즈만큼을 받고 ack를 보내지는 않음, ack를 받으면 잘 갔다고 확보된 부분 이후로 타이머를 옮겨 다시 설정
- sliding window: 윈도우 사이즈 변동됨
- 클수록 throughput 높음, 그러나 에러 발생하면 그만큼 다 재전송해야 함
- 네트워크의 혼잡이나 receiver 버퍼가 수용 가능한 선에서 최대한의 스루풋이 가능한 적절한 크기를 시스템이 조절 1. window size = 4로, 0, 1, 2, 3 네 개의 패킷 전송, 패킷 2 loss 2. 수신자는 0, 1은 받았으므로 거기에 대해 ACK 보냄. ACK0, 1을 따로 보냄 3. 송신자는 ACK0을 수신, W=4인데 0은 도착했으니 4번 패킷 보낼 수 있음 4. 송신자가 ACK1을 수신, 따라서 5번 패킷을 보내 현재 전송했으나 ACK가 없는 패킷 수를 4 이하로 유지 5. 그런데 수신자는 패킷 3을 수신함, 순서에 맞지 않으므로 버리고 ACK1을 다시 보냄 6. 패킷 4, 5가 와도 다 버리고 계속 ACK1만 보냄 7. 송신자는 패킷 2의 타임 아웃까지 기다리고 ACK2가 안 오면 패킷 2부터 재전송
- selective repeat
- 쭉 보내다가 수신자가 잘못된 부분을 응답하면 송신자는 그 부분만 다시 보냄
- individual ack: 어느 부분이 잘못되어 그 부분만 재전송 받기 위해 개별 ack
- 모든 패킷이 별도의 타이머
- window size = 4로, 0, 1, 2, 3 네 개의 패킷 전송, 패킷 2 loss
- ACK0, ACK1 보냄, 송신자는 패킷 4, 5번 전송
- 패킷 2번 재전송, 3, 4, 5는 재전송 X
- 수신자는 3, 4, 5를 버퍼에 넣어뒀다가 2가 오면 같이 애플리케이션에 보냄(in-order delivery)
- ACK3, 4, 5, 2를 순서대로 받으면 이제 패킷 6, 7, 8, 9를 한 번에 보냄
- sequence number의 크기는 제약이 있음
- ex) 윈도우 사이즈 = 3, 시퀀스 넘버 = 0, 1, 2, 3
- 성공
- 송신자가 패킷 0, 1, 2 전송, 수신자가 잘 받아서 ACK 보냄
- ACK0을 받으면 패킷 3 전송, 패킷 3 에러
- ACK1을 받으면 패킷 0 전송, 수신자는 패킷 3 없이 패킷 0 수신하지만 그래도 잘 알아들음
- 실패
- 수신자가 패킷 0, 1, 2를 받고 ACK 0, 1, 2를 보냈는데 전부 도달 X
- 송신자는 패킷 0 재전송, 수신자는 패킷 3 다음의 새로운 0번으로 착각
- 성공
- 따라서 윈도우 사이즈는 sequence number의 절반 이하여야 함
- ex) 윈도우 사이즈 = 3, 시퀀스 넘버 = 0, 1, 2, 3
댓글남기기