반응형
- 네 번째 쳅터에서는 인터넷의 트랜스포트 계층 프로토콜인 TCP와 UDP에 대해 설명한다.
- 트랜스포트 계층 IP 계층의 도움을 받아 종점간(end-to-end) 호스트에서 실행되는 프로세스들이 안정적으로 메시지를 송수신 하도록 도와주는 역할을 한다.
- 인터넷의 트랜스포트 계층 프로토콜에는 TCP와 UDP가 있다. TCP와 UDP는 각각 연결형과 비연결형 서비스를 제공한다.
- 엡 브라우저는 기본적으로 TCP를 사용하고 비디오 스트리밍에서는 UDP를 사용한다. TCP는 신뢰성 있는 통신 환경을 제공하고 UDP는 TCP보다 간단한 메시지 전달 기능만 제공하는데 이들의 차이는 뒤에서 자세히 설명한다.
- 앞에서 IP 프로토콜을 설명했는데, IP 프로토콜은 OSI 계층 3의 기능을 수행하며 네트워크 주소를 사용하여 패킷을 목적지까지 전달하는 일을 한다.
- 즉, IP 주소만 정확히 써서 IP 패킷을 전송하면 중간의 라우터들이 이 패킷을 잘 전달하여 최종 목적지까지 배달된다고 하였다.
- 그러데 TCP나 UDP가 또 필요한 이유는 무엇인가? 인터넷을 통해서 패킷을 목적지로 보내는데 IP 만으로는 부족한 이유는 무엇인가?
- 우선 IP 프로토콜만으로 패킷이 목적지까지 잘 전달되는지를 확인할 수가 없다. IP주소가 맞으면 라우터들이 목적지로 최선을 다해서 패킷을 전달은 하겠지만 이 패킷이 정말 목적지에 잘 도착했는지를 확인해주는 과정이 없다.
- 편지를 보내는 것을 생각해보자. 내가 편지통에 편지를 넣었다고 해서 상대방이 정말 이 편지를 받았는지는 알 수 없다.
- 나는 우편 시스템을 믿고 보냈을 뿐이다. 우체국의 실수로 편지는 얼마든지 안 갈 수 있다. 실제로 편지가 잘 간 것은 상대방 수신자로부터 답장이 와야만 알 수 있다.
- 즉, 종점 사용자인 수신자가 답장을 보내주지 않으면 나는 편지가 잘 갔는지 안 갔는지 모른다. 이는 우체국에서도 대답해줄 수 없다. 즉, 종점 사용자가 개입해야만 실제로 편지를 받았는지를 알 수 있다.
- TCP와 IP의 관계도 마찬가지이다. IP 패킷은 호스트에서 인접 라우터까지, 그리고 그 라우터에서 다음 라우터까지 릴레이 하듯이 목적지를 향해 패킷을 전달만 하는 것이며 중간 라우터 어디선가 패킷이 사라진다고 해도 이를 어떤 라우터도 송신자에게 알려주지 않는다.
- 패킷이 목적지에 잘 도착한 사실은, 목적지의 TCP 계층이 확인하고 잘 받았따는 사실을 알려주어야만 송신측 TCP는 비로소 패킷이 목적지에 도착한 것을 알 수 있다.
- TCP 프로토콜이 잘 동작하고 있으면, 이제 종점간에 안정적으로 데이터 통신이 이루어지는 환경이 조성되었다고 볼 수 있다.
- 즉, 트랜스포트 계층으로 인해 상위 계층(즉, 이 트랜스포트 이용자)에 해당하는 프로세스들은 이제 마치 하나의 컴퓨터 내의 프로세스 사이의 통신처럼, 거리감 없이 데이터를 송수신할 수 있게 된다.
- 물론 데이터 전달시의 지연은 발생한다.
세그먼트
- TCP 계층이 한 번에 보내고 받는 데이터 단위를 흔히 세그먼트라고 부른다. 하나의 패킷에는 하나의 세그먼트가 실려서 전송된다.
- IP 계층에서는 호스트와 중간 라우터들 간에 세그먼트를 전달하기 위해서 최대한 노력하지만, 어떤 보장도 하지 않는다. IP는 세그먼트의 전달을 보장하지 않을 뿐 아니라, 세그먼트가 순서대로 전달되는 것도 보장하지 않는다.
- 이러한 이유로 IP를 비신뢰적인(unreliable) 서비스라고 부른다. TCP는 이러한 비신뢰적인 상황을 신뢰성있는 통신환경으로 바꾼 것이라고도 볼 수 있다.
- 인터넷의 트랜스포트 계층에는 연결형 서비스를 제공하는 TCP와 비연결형 서비스를 제공하는 UDP가 있다.
- 연결형 서비스인 TCP는 종점간의 연결 개설, 오류 제어, 패키 전달순서 확인, 흐르제어, 등의 기능을 기본적으로 제공하여 신뢰적인 데이터 전달(reliable data transfer)을 제공한다.
- 비연결형 서비스인 UDP는 TCP와 달리 연결 개설, 오류제어, 전달 순서 확인, 흐름제어를 하지 않고, 단순하게 메시지를 ㅎ나씩 송수신하는 기능만 제공한다. 즉 IP처럼 비신뢰적인 메시지 전송만 한다.
- UDP가 필요한 이유는 TCP처럼 신뢰성 있는 통신은 굳이 필요하지 않은 경우인데 자세한 내요은 뒤에서 설명하겠다.
포트번호
- TCP 계층은 호스트에서 실행중인 어떤 프로그램이 인터넷을 통해서 원격에 있는 다른 프로그램과 통신하게 도와주는 기능을 수행한다.
- 이를 위해서 TCP 계층은 IP 계층을 이용하여 패킷을 송수신하고, 상대방과 잘 연결되었는지를 확인하고 종점간의 오류제어나 흐름제어를 한다.
- 한 호스트에서 인터넷을 동시에 이용하는 프로그램은 여러개 실행될 수 있다.
- 예를 들어 검색을 하면서, 비디오를 스트리밍으로 보고, 동시에 다른 창에서 은행 거래를 할 수 있을 것이다. 즉, 한 컴퓨터에서 네트워크 응용 프로그램이 여러개 실행될 때 트랜스포트 계층은 이 여러 프로그램을 구분하는 방법이 필요하다.
- 트랜스포트 계층이 수신한 메시지를 전달할 응용 프로세스를 구분하기 위하여 포트(port) 번호를 사용한다.
- 우편 시스템을 생각해보자. 대학교 연구실로 편지를 보내면 우편배달부가 연구실 방까지 편지를 배달해주지는 않는다.
- 우편배달부는 대학 건물까지만 편지들을 배달하고, 대학 건물에서 연구실까지는 방 호수를 보고 직원이 다시 편지를 전달한다.
- IP와 TCP/UDP도 마찬가지이다. IP 주소를 보고 호스트까지 패킷이 전달되지만 이 호스트에 여러개의 인터넷 응용 프로그램이 실행되고 있다면 이들을 구분하고 각 해당 프로그램에게 패킷에 실려있는 메시지를 전달하기 위해서는 방 호수 처럼 어떤 번호가 배정되어야 하는데 이를 포트번호라고 한다.
- TCP나 UDP는 port 번호로 16비트를 사용하므로 약 65000개의 응용 프세스를 구분할 수 있다.
- IP주소는 목적지 호스트까지 패킷을 전달하기 위해서 IP 계층이 사용되는 주소이고 그 호스트 내에서 이 패킷의 내용(메시지)을 최종적으로 전달할 응용 프로세스를 구분하기 위하여 포트 번호가 사용된다.
- IP 주소는 목적지 호스트까지 패킷을 전달하기 위해서 IP 계층이 사용하는 주소이고 그 호스트 내에서 이 패킷의 내용(메시지)을 최종적으로 전달할 응용 프로세스를 구분하기 위하여 포트 번호가 사용된다.
- IP 주소가 전 세계적으로 유일하게 배정되는 주소인 것과 달리 포트번호는 한 호스트 내에서만 유일하게 정해지면 되는 번호이므로 다른 호스트에서 같은 포트번호들을 사용할 수 있다.
- 마치 여러 건물이 201호 201호 처럼 같은 방번호를 중복하여 사용할 수 있는 것과 같다.
well-known port
- 포트 번호에는 약속에 따라 미리 정해진 번호들도 있고 사용자가 임의로 정해서 사용할 수 있는 영역도 있다.
- 예를 들어 telnet, ftp, http와 같이 널리 사용되는 응용 프로그램은 모든 컴퓨터에서 같은 포트번호를 사용하도록 미리 지정되어 있으며 이런 포트를 well-known 포트라고 한다.
- well-known 포트 번호는 IETF에서 배정하며 1023번 이하가 배정되는데 예를 들어 ftp는 21번, telnet은 23번, 웹 서비스를 위한 http는 80번 포트번호를 사용한다.
- 이렇게 well-known 포트 번호를 미리 지정한 이유는 임의의 클라이언트 호스트가 임의의 서버에서 수행되는 서비스를 쉽게 찾아서 이용하도록 하기 위해서이다.
- TCP/IP를 이용하는 서비스 이름과 각 서비스에 배정된 포트 번호의 관계를 정리한 파일을 서비스 파일이라고 하는데 유닉스에서는 /etc/services에 이 내용이 들어 있다. 아래느 서비스 파일의 예를 나타냈다.
#Newwork services, Internet style
#
#서비스명 포트 번호/프로토콜 별명
echo7/tcp
echo7/udp
ftp21/tcp
telnet23/tcp
smtp25/tcp mail
- 위에서 smtp 25 / tcp mail 라인의 의미는, smtp(simpe mail transfer protocol) 서비스는 25번 포트 번호를 사용하고 tcp 프로토콜로 구현되어 있으며 smtp 서비스의 별명으로 mail을 사용할 수 있다는 것을 나타낸다
TCP
TCP의 기능
- TCP는 종점 프로세스간의 연결 개설, 오류 발생 시 패킷 재전송, 패킷 전달순서 확인, 중복 패킷 제거, 흐름제어, 네트워크 오동작시 보고 등을 제공한다.
- TCP는 이러한 연결형 서비스를 제공함으로써 사용자가 보다 안정적인(신뢰 할 수 있는) 통신 서비스를 제공한다.
- TCP는 스트림(stream) 서비스를 제공한다고도 하는데 스트림이란 연속된 데이터를 순서를 유지하며 전송할 수 있는 환경을 말한다.
- 스트림형 서비스로 인하여 TCP를 이용하면 크기가 큰 파일을 전송하여도 데이터가 중간에 끊어지지 않고 차례로 전송될 수 있는 것이다.
- 이와 같이 TCP는 한 번에 많은 양의 데이터를 전송할 때나 신뢰성 있는 통신이 필요할 때, 또는 데이터의 순서 보장이 필요할 때 사용되며 파일 전송 프로토콜(ftp), 텔넷, mail, http 등에서 TCP를 사용한다.
위에서 부터 5줄이 헤더를 포함하는 크기. 총 20바이트이다.
- Source Port와 Destination Port는 각각 송수신측의 응용 프로세스를 구분하는 포트 번호를 나타낸다.
- 응용 계층 프로그램에서 TCP에게 전송하도록 요구한 데이터를 편의상 "메시지"라고 부르겠다.
- 이 메시지의 크기가 큰 경우에는 TCP 계층에서 이 메시지를 여러 개의 데이터 블록으로 나누어 보내야 하는데 이 나누어 보내는 데이터 블록을 "세그먼트"라고 부른다.
- 즉, TCP에서 하나의 IP 패킷에 실어 보내는 사용자 데이터가 세그먼트인 것이다.
- 응용 계층이 전송하는 메시지를 TCP가 다수의 세그먼트로 나누어 전송하는 관계를 나타냈다.
- TCP는 메시지를 전송할 때에 자신이 전송한 데이터의 양을 바이트 단위로 기록하고 있으며 세그먼트를 전송할 때마다 그 세그먼트가 몇 번째 바이트 위치의 데이터부터 포함하고 있는지를 기록하여 전송하는데 이 때 순서번호(Sequence Number)를 사용한다.
- 즉, 순서번호에는 이 세그먼트의 첫 번째 바이트의 순서 번호가 들어있다. 예를 들어 이 값이 X이고 이 세그먼트에 476 바이트의 사용자 정보가 들어 있었다면 이 세그먼트에 476 바이트의 사용자 정보가 들어 있었다면 이 세그먼트에는 X, X+1, ....,(X +476-1) 바이트 순서에 해당하는 데이터가 들어 있다.
- 다음에 전송되는 TCP 세그먼트의 순서 번호는 X + 476이 된다. 수신측에서는 이 순서 번호를 보고 메시지가 정상적으로 수신되고 있는지를 확인할 수 있다.
- 다음에 전송되는 TCP 세그먼트의 순서 번호는 X + 476이 된다. 수신측에서는 이 순서 번호를 보고 메시지가 정상적으로 수신되고 있는지를 확인할 수 있다.
- 확인번호(Acknowledgement Number)는 내가 상대방으로부터 다음에 받고자 하는 순서 번호를 기록하여 보내는데 사용된다.
- 예를 들어 내가 상대방으로부터 Sequence Number가 Y인 패킷까지 정상적으로 수신하였으면 확인번호에는 Y+1을 기록하여 상대방에게 보낸다.
- 상대방은 이 값을 보고 "Y번까지의 데이터를 정상적으로 상대방에게 전달된 사실"을 알게 된다.
- Header Length는 헤더의 크기를 4바이트 단위로 나타내며 헤더의 크기가 20바이트이면 이 값은 5가 된다.
- Code Bits는 6개의 비트로 구성되어 있는데 URG는 이 세그먼트가 긴급 데이터임을 표시하며 이 때 세그먼트의 첫 부분 바이트부터 Urgent Pointer의 위치 사이에 긴급 데이터가 들어 있다는 것을 나타낸다.
- 긴급 데이터 이후에는 일반 데이터가 따라 올 수도 있다.
- ACK는 현재 Ack Number에 들어 있는 값이 의미 있는 값이라는 것을 나타낸다.
- PSH는 push 기능을 나타내는데 이 비트가 1이면 수신측의 프로세스에게 push 사실을 알리도록 요구하는 명령이 된다.
- RST는 이 연결을 reset하고자 할 때 사용된다.
- SYN은 상대방 TCP와의 연결 설정 과정에 사용되는데, 이 패킷이 SYN패킷임을 나타낸다.
- FIN은 데이터 전송 종료(finish)를 나타낼 때 사용한다.(연결 설정에 대해서는 뒤에서 설명함).
- Window는 흐름제어를 위해서 사용되는데 이에 대해서는 뒤에서 설명한다.
- ChckSum은 TCP PDU 전체, 그리고 IP 헤더의 일부로 구성된 pseudo헤더(송수시진의 IP 주소, Protocol 등 12 바이트)를 대상으로 계산하는 오류검출용 값이다.
- chcksum의 계산법 및 사용법은 UDP의 경우와 같다. UDP에서는 chcksum의 사용이 옵션이었으나 TCP에서는 checksum 필드를 반드시 사용해야 한다.
TCP 연결 설정
- TCP는 연결형 서비스이며 따라서 TCP를 이용하여 데이터를 송수신하기전에 종점간 연결 설정 과정이 필요하다.
- 두 종점 호스트의 TCP 사이에 연결 설정이 되면 통신에 필요한 상태정보가 저장되고 이를 이용하여 흐름제어, 재전송 등을 수행하게 된다.
- 인터넷을 경유하는 종점 호스트간의 연결 설정은 중간에 특성이 다른 여러 종류의 네트워크들을 통과하게 되므로 종점간 연결 특성이 시간에 따라 다르게 변화될 수 있다.
- 즉, 데이터 전달 지연시간, 처리율 등이 시각에 따라 달라질 수 있는 것이다. 따라서 TCP의 종점간 연결은 여러 가지 성능의 네트워들을 경유하여 연결될 수 있으며 어떤 경우에도 안정적으로 동작하는 트랜스포트 서비스를 제공할 수 있어야 한다.
- 예를 들어 효율적인 흐름제어를 위해서 재전송을 위한 타이머 값을 네트워크의 상태에 따라 탄력적으로 바뀔 수 있어야 한다.
- TCP에서 연결 설정을 하면 양방향 통신이 가능한 스트림이 생성된다. 즉, 한 번의 연결설정으로 송수신이 가능하게 된다.
- TCP에서는 연결 설정을 위하여 3-way handshake를 사용하는데 3-way handshake란 연결 요청에 대하여 상대방도 이를 확인하면서 다시 새로운 연결 요청을 하고 이에 대해 처음의 연결 요구측에서 확인을 보내야 비로서 연결이 되는 방식을 말한다.
- 먼저 연결을 요구하는 측(이를 클라이언트라고 한다)에서 SYN 비트를 세트하고 순서 번호를 X로 한 연결 요청(이를 편의상 SYN(X)이라고 표현하겠다)을 상대방(이 상대방이 서버로 동작한다)으로 보낸다.
- 서버는 ACK 비트를 세트하고 Ack Number에 (X+1)을 기록하고, 동시에 SYN 비트도 세트한 다음 자신이 사용할 순서 번호 Y를 지정하여 클라이언트로 보낸다.
- 이것을 편의상 ACK(X + 1)과 SYN(Y)를 보낸다고 하겠다. ACK(x+1)과 SYN(Y)를 받은 클라이언트가 이제 ACK(Y+1)로 응답하면 3-way 연결이 이루어진다.
- TCP에서 3-way handshake를 사용하는 이유는 하위 계층인 인터넷 계층이 비연결형 서비스로 단순히 best-effort의 패킷 전송만 제공하므로 종점 호스트 사이의 안정적인 연결을 신중하게 확인하기 위해서이다.
- 위에서 X나 Y의 값(즉,초기 순서번호)은 랜덤하게 정하는데 초기순서 번호로 일정한 값(예를 들어 0번)을 사용하게 되면 이 번호가 너무 자주 사용하게되어 중복패킷 검출 시에 오류가 발생할 확률이 커지기 때문에 랜덤한 값을 사용하는 것이다.
- 연결설정 동작에는 타이머를 사용하여 그 시간 내에 상대방으로부터 ACK가 오지 않으면 연결요청을 재전송을 한다.
TCP 데이터 송수신
- TCP는 스트림 방식의 데이터 전송을 지원한다고 하였는데, 이것의 의미는 TCP를 사용하여 연결이 이루어지면 두 호스트 사이에 스트림이 형성되어 한 번의 명령으로 임의의 크기의 데이터를 순서를 유지하며 전송할 수 있다는 뜻이다.
- 그러나 UDP에서는 한 번에 전송할 데이터가 UDP 최대 세그먼트 크기(약 65000 바이트)보다 크면 뒷 부분이 전송되지 않는다.
- IP 패킷 길이를 나타내는데 16비트가 사용되므로 IP 패킷은 헤더를 포함해서 최대 65,535 바이트가 될 수 있다.
- 따라서 TCP의 헤더 20 바이트와 IP의 헤더 20 바이트를 제외하면 TCP 계층이 한 번에 전송할 수 있는 세그먼트의 최대 크기는 65,495 바이트가 된다.
- 그러나 실제로는 다음과 같은 이유로 TCP에서는 세그먼트의 크기를 수 백 ~ 1460바이트 정도의 크기로 제한한다.
- TCP가 한 IP 패킷에 실어 전송하는 데이터 블록을 세그먼트라고 하는데 TCP는 세그먼트의 최대 크기 MSS(Maximum Segment Size)를 미리 정하고 이 값을 상대방 TCP에게 미리 알려주어야 한다.
- 즉, TCP에서는 전송할 메시지의 크기가 MSS보다 클 경우에는 메시지를 MSS 단위로 세분화하여 전송한다.
- MSS의 크기는 세그먼트가 목적지까지 전달되는 도중에 중간의 네트워크에서 다시 세분화되지 않을 정도로 충분히 작게 정하되 가능한 크게 하여 전송 효율을 높이도록 정한다.
- MSS를 정하려면 먼저 path MTU(Maximum Transfer Unit)를 알아내야 하는데 path MTU란 두 호스트 사이에 있는 MTU중 가장 작은 값을 말하며 MTU란 어떤 네트워크가 전달할 수 있는 최대 패킷의 크기를 말한다.(가장 작은 값이 보내는 기준이 되어야 한다. 이해가 안가면 더 생각해보자 큰 값이 기준이 되면 무슨 일이 생길까?)
- 이와 같이 path MTU 크기를 미리 알아서 MSS 값을 정해주면 패킷이 전송되는 중간의 네크워크에서 IP 패킷이 다시 세분화되는 것을 피할 수 있기 때문이다.
- 다시 말하면 TCP는 MSS 값을 "path MTU - TCP 헤더크기"로 정하는것이 적절한 선택이 된다.
- 예를 들어, 이더넷들로 연결된 호스트 사이의 path MTU는 1500바이트가 되며 이때는 MSS를 1460바이트로 정해야 네트워크 이용률이 가장 높게 된다.
- TCP에서 전송할 메시지의 MSS보다 큰 경우 메시지를 세그먼트로 나누면서 즉시 전송이 이루어진다.
- 전송할 메시지의 크기가 MSS보다 작아도 다음과 같은 경우에는 메시지가 채워질 때까지 기다리지 않고 즉시 전송이 이루어진다. 먼저 사용자가 키보드를 입력한 경우에 즉시 전송을 한다.
- 또한 키보드 입력을 천천히 하여도 일정 시간이 경과하여 타이머가 작동하여 입력된 데이터가 바로 전송된다.
TCP 흐름제어
- 링크 계층의 흐름제어는 인접한 노드를 연결하는 링크를 지나가는 모든 프레임을 대상으로 이루어지는 것으로서 그 목적은 링크의 이용률(처리율)을 높이기 위한 것이다.
- IP 계층에서는 흐름제어를 하지 않는데 그 이유는 IP의 주된 목적이 라우팅을 통하여 패킷을 목적지까지 "전달"하는 것이 IP의 주된 목적이기 때문이다.
- 트랜스포트 계층인 TCP가 제공하는 흐름제어는 종점 사용자간의 흐름제어이다. 종점 사용자간의 흐름제어가 필요한 이유는 다음과 같다.
- 종점 사용자 사이에는 여러 네트워크 요소들(링크, 라우터 등)이 관련되어 있다. 따라서 종점간의 지연 특성은 시간에 따라 매우 가변적이고 예측하기 어렵다.
- 따라서 계층 2에서 흐름제어를 한다고 하더라도 종점 사용자간에 제대로 데이터가 잘 전달되는지 최종적인 흐름제어가 필요하며 이것은 망의 트래픽 상태를 반영하는 적응적인 방식이어야 한다.
- 서울-대전간 고속도로를 지나는 차량의 흐름제어를 생각해 보자. 교통경찰관의 역할은 서울-대전 간 고속도로 구간을 지나가는 모든 자동차를 대상으로 교통흐름을 관리하며 목적은 원활한 차량의 흐름이다.
- 이와 달리 특정 고속버스 회사의 입장에서는 다른 차량의 흐름에는 관심이 없고 서울-대전간 고속버스의 흐름에만 관심이 있어서, 예를 들어 5분에 한 대면 1시간에 12대가 제대로 운행되고 있는지에 관심이 있을 뿐이다.
- 링크계층의 흐름제어는 서울-대전간 도로의 차량흐름을 관리하는 것과 같이 이 링크를 지나가는 모든 프레임을 대상으로 처리율(단위시간당 지나가는 프레임 수)를 높이는 것이 목적이며, 트랜스포트 계층의 흐름제어는 종점 프로그램간의 원활한 데이터 송수신을 관리하는 것이다.
- 링크계층에서 속도가 빨라지면 트랜스포트 계층에서도 빠른 통신이 이루어지고 반대로 링크계층에서 속도가 느려지면 트랜스포트 계층에서도 느려지므로 이들이 관련은 있다.
- 그러나 계층별로 흐름제어의 대상이 다른 것이다. 마치 고속도로 경찰은 특정 버스회사의 운행 횟수에 관심이 없고, 버스회사는 도로상의 다른 차량의 흐름에 관심이 없는 것과 같다.
- 흐름제어(flow control)가 수신측의 데이터 수신 능력을 고려한 송신지의 전송 속도 조절이라고 한다면 혼잡제어란 네트워크 내의 트래픽 부하가 증가할 때 이를 줄이기 위한 송신 속도 제어이다.
윈도우 흐름제어
- 트랜스포트 계층에서도 윈도우를 사용하여 흐름제어를 한다. 그런데 링크 계층에서 사용되는 슬라이딩 윈도우 흐름제어(SWFC)에서는 프레임 단위로 흐름제어가 이루어졌다.
- 즉, 수신측이 앞으로 몇 개의 프레임을 더 수신할 수 있는지를 송신측에게 알려주고 이 윈도우 수(즉, 프레임 수) 범위내에서 전송을 하도록 제한하는 방식이었다.
- 예를 들어 윈도우 값이 128이면 128개의 프레임 범위에서 Ack 없이 프레임을 송신할 수 있는 방식이었다.
- 그러나 TCP에서는 프레임 단위가 아니라 수신할 데이터 총량을 알려주는 방식으로 흐름제어를 한다. 즉, 현재 윈도우 값이 8000바이트이면 송신측은 8000바이트까지는 문제없이 보내도록 허용된 것이다.
- 수신측은 TCP 헤더의 Window에는 자신이 다음에 받을 수 있는 데이터의 양 즉, 윈도우 크기를 바이트 단위로 기록하여 송신측으로 전송하며 송신측은이 Window 크기 내에서만 데이터를 전송할 수 있다.
- 수신측은 자신의 메모리 상태, 데이터 처리 능력에 따라 Window 값을 업데이트 한다.
- 송신 순서번호의 크기로 32비트를 사용하고 있는데 예를 들어 155Mbps 속도의 채널에서는 같은 값의 순서번호가 4분마다 재사용된다.
- Window 크기는 16비트인데 이것으로 수신버퍼의 크기를 나타내기에는 충분하지 않다. 통신망의 속도가 빨라지면서 수신버퍼도 순간적으로 커질 수 있는데 16비트로는 64K 바이트 크기의 밖에 표시할 수 없기 때문이다.
- 따라서 고속망에서는 Window의 크기를 크게 표현할 수 있는 다른 방안을 사용하는 것이 필요하다.
재전송
- TCP에서는 어떤 세그먼트 전송 후 일정 시간 내에 이에 대한 ACK가 오지 않으면 재전송을 한다. 이 재전송까지 시간을 패킷의 RTT(round trip time)를 기준으로 정하게 된다.
- 예를 들어 편지를 보내고 4일이 지나도 답장이 없으면 다시 편지를 보내보는 것과 같다. 정상적이라면 편지는 이틀이면 가므로 편지가 가고 회신이 오는데 4일이면 되기 때문이다.
- 즉, 편지에서는 재전송 타이머 값이 4일이 적절한 것이다. 3일만에 재전송하는 것은 너무 빠른 것이고 10일이 지나서 재전송을 한다면 너무 낭비하는 시간이 많아지게 되어 통신효율이 떨어진다.
- 인터넷에서는 트래픽 상태에 따라 RTT 값이 일정하지 않고 변했다. RTT값은 20ms일 수도 있고 200ms일 수도 있다. 열배나 차이가 날 수 있다.
- 마치 편지가 2일이 아니라 20일 걸리는 것이라고 생각해보자. 그러면 40일 후에나 재전송을 해야 의미가 있는 것이다.
- TCP에서는 이렇게 변화가 심한 RTT 값을 수시로 측정하여 재전송 타이머 값을 계산한다.
- TCP에서 세그먼트를 전송할 때마다 시각을 기록하고 이 세그먼트에 대한 ACK 도착하면 RTT값을 측정한다. 이렇게 구한 샘플 RTT 값의 최근 평균치를 사용한다.
Jacobson/Karels 알고리즘
- 네트워크의 혼잡 제어를 개선하는 방법으로 Jacobson/Karels 알고리즘이 제안되었다.
- 만일 재전송 타이머(Timer) 값이 너무 적으면 재전송될 횟수가 불필요하게 많아져서 네트워크 내에 트래픽이 증가하게 되고 이로 인해 혼잡제어가 필요하게 된다.
- 반면에 재전송 타이머(Timer) 값을 너무 크게 잡으면 재전송이 필요한 때에 바로 재전송이 되지 않고 수신측이 많이 기다리게 된다.
- 보다 정확한 재전송 타이머(Timer) 값을 예측하기 위해서 재전송 타이머(Timer) 값의 편차(deviation) 정보를 이용할 수 있는데 만일 편차가 적으면 현재 측정된 RTT 값은 비교적 정확한 것이라고 볼 수 있다.
- 반대로 측정된 RTT 값의 편차가 크면 측정된 RTT 값은 정확한 것이 아니므로 재전송 타이머(Timer) 값을 크게 잡아야 할 것이다. 즉, 재전송 타이머(Timer)를 구하는데 있어 RTT의 평균 뿐 아니라 편차를 반영할 수 있다.
Timer = Tm + 4 * dev
- 위에서 Tm과 dev는 각각 RTT의 측정된 평균값과 편차이다. 재전송 타이머(Timer) 값을 구하기 위해 편차 값에 4배를 한 것은 실험에 의해서 구해진 적절한 값이다.
데이터 경계 표시
- TCP가 바이트 스트림을 제공한다고 하였는데 이것의 의미는 송수신 측이 바이트 단위로만 데이터를 읽기만 하면 한 번에 보내는 세그먼트의 바이트 수와 읽는 바이트 수가 서로 같지 하지 않아도 수신이 바이트 순서에 맞게 잘 이루어진다는 것이다.
- 예를 들어 송신측이 20바이트씩 10회 데이터를 송신하고, 수신측은 25 바이트씩 8회를 수신하여도 데이터는 정상적으로 수신된다.
- 한편 TCP에서는 필요하다면 바이트 스트림 중간에 어떤 경계 표식을 삽입할 수 있다. 이것은 응용 프로그램이 하나의 바이트 스트림을 여러 개의 데이터 블록으로 나누어 읽을 필요가 있을 때 사용될 수 있다.
- 이러한 경계 표식을 위한 첫 번째 방법은 긴급 데이터를 전송할 때 사용되는 URG 플래그와 URG 포인터를 이용하는 방법이 있다.
- 긴급 데이터란 원래는 일반 데이터가 아닌 특별한 데이터를 처리하기 위해서 마련된 것이었으나 실제로는 이 기능이 별로 사용되지 않고 있다. 그래서 URG와 URG 포인터를 경계를 구분하는 record marker의 기능으로 사용할 수 있다.
- 두 번째 방법은 push 기능을 이용할 수 있다. 원래 push 기능의 목적은 응용 프로그램에서 TCP에게 현재 가지고 있는 데이터를 상대방으로 바로 전송하도록 요구하는 것이었다.
- 이것은 telnet 응용에서 키보드 입력문자를 바로 전송하도록 하는데 사용된다.
- 그런데 PUSH플래그가 세트된 세그먼트를 받은 수신측은 이 사실을 응용 프로그램으로 알려주도록 옵션을 지정할 수 있으므로 이 기능을 이용하면 PUSH 기능을 이용하여 전체 메시지의 중간에 경계를 알려주는 것이 가능하다.
- 위에 설명한 TCP의 고유 기능을 이용하여 경계를 구분하는 방법보다 응용 프로그램에서 메시지를 작성할 때 레코드 경계를 미리 삽입하는 방법이 가장 편리한 방법이다.
- 예를 들어 메시지가 여러 레코드로 구성된 경우 각 레코드의 시작 위치를 알려주는 방법이 있겠고, 각 레코드 경계에 어떤 구분 문자를 삽입하는 방법도 가능하다.
TCP 옵션
- TCP에서도 송수신지 간에 옵션을 지정할 수 있는데 이러한 옵션은 연결 설정 과정에서 서로 정해야 한다.
- TCP 옵션이 들어 있는 지는 TCP 헤더의 크기를 보고 알 수 있는데 헤더의 크기가 20바이트를 넘으면 옵션이 추가되어 있다는 것을 알 수 있다.
- TCP 옵션의 대표적인 사용 예로 RTT를 측정하는데 옵션이 사용될 수 있다.(timestamp 옵션)
- RTT를 측정하기 위해서 송신측이 timestamp 값을 세그먼트 헤더에 넣어 전송할 수 있으며 이 timestamp 값을 수신측에서는 ACK에 실어서 송신측으로 되돌려 보내주도록 할 수 있다.
- 위에서 소개한 timestamp 옵션 기능을 활용하여 송신 순서번호(32비트)가 자주 wrap around 되는 문제를 피할 수 있다.
- 이 때에는 순서번호와 32비트의 timestamp를 묶어서(총 64비트) 각 세그먼트를 구분함으로써 32비트의 송신 순서번호가 자주 반복 사용되는 확률을 낮출 수 있다.
- 이 때 timestamp는 단지 두 세그먼트가 서로 다르다는 것을 구분하는데만 사용되며 "순서번호"의 목적으로 사용되는 것은 아니다.
- Window에 들어 있는 값 즉, 수신측이 다음에 받을 수 있는 메시지의 양은 디폴트로 바이트 단위로 표시하는데 이것을 4바이트 또는 64바이트 단위로 확장해서 사용할 수 있다.
- 이렇게 하는 이유는 고속 통신망에서는 16비트로 표시할 수 있는 64K 바이트 이상의 크기로 Window를 표현할 필요가 많기 때문이다.
UDP
- UDP는 간단히 메시지를 송수신하는 프로토콜이며 TCP와 달리 오류제어, 흐름제어를 하지 않아서 신뢰성 없는 서비스만 제공한다.
- 그렇다면 TCP가 UDP보다 안정적인 통신을 제공하므로 항상 TCP를 사용하면 좋을 것 같으나 어떤 응용 서비스는 UDP를 사용해야 하는 경우도 있다.
- 예를 들어 서버 프로그램이 UDP만을 사용하도록 작성되어 있는 경우 이러한 서버와 통신을하기 위한 클라이언트 프로그램도 UDP를 이용하여야 한다.
- 음성이나 비디오 신호와 같이 데이터 전송량이 많은 경우에는 오버헤드를 줄이기 위해서 TCP 대신 UDP를 사용한다.(TCP의 오버헤드는 20 바이트이나 UDP의 오버헤드는 8바이트이다)
UDP 헤더
- UDP는 비연결형 서비스로서 한 번에 하나의 메시지만 전송한다.
- UDP 헤더의 길이는 모두 8바이트인데 송신 포트(Source Port) 번호는 이 UDP 메시지를 전송하는 응용 프로세스를 구분하는 번호이고 수신포트(Destination Port)번호는 수신측 호스트에서 이 UDP 메시지를 수신 하기를 바라는 응용 프로세스를 구분하기 위한 번호이다.
- Length(16비트)는 UDP 패킷의 헤더 및 메시지 부분을 포함 전체 길이를 바이트 단위로 나타낸다.
- Checksum은 UDP 메시지 내에서 전송 중에 비트 오류가 발생하였는지를 검출하기 위한 코드인데 Checksum의 계산 범위는 pseudo 헤더, UDP 헤더 그리고 메시지 세 부분이다.
- UDP 헤더 그리고 메시지 부분은 전체가 되며 pseudo 헤더란 checksum을 계산하기 위해 임시로 정의한 헤더인데, IP 헤더에 들어있는 송수신지의 IP 주소(8 바이트)와 Protocol 필드(이 값은 UDP의 경우 17임) 그리고 UDP 메시지 길이를 나타내는 총 12바이트의 정보를 말한다.
- UDP의 checksum을 계산할 때 "하위 계층인" IP 계층의 도움을 받아 IP 주소를 얻은 다음 이것을 이용하여 pseudo 헤더를 구성하여 UDP checksum을 구하며 수신측에서 checksum을 확인하기 위해서 하위 계층인 IP 계층의 도움을 받아야 한다.
- IP 주소는 IP 계층의 checksum을 계산할 때 확인이 되는데도 이렇게 IP 주소를 중복하여 확인하는 이유는 이 UDP 메시지가 정확히 목적지에 배달되었는지를 이중으로 확인하기 위해서이다.
- 마치 송수신지 수소를 편지 봉투 뿐 아니라 편지지 내용의 상단에 다시 기입하는 것과 같다.
- Checksum의 사용은 옵션이므로 계산량을 줄이려면 이를 구현하지 않아도 된다. checksum을 사용하지 않을 때는 0으로 두면 된다. 그러나 IPv6에서는 UDP에서도 checksum을 반드시 구현하여야 한다.
- Checksum의 계산 방법은 IP의 Checksum 계산 방법과 같다(초기값을 0으로 하고 데이터를 16비트 길이로 나누어 계속 더하는 방식)
UDP 서비스
- UDP는 안정적인 데이터 송수신을 보장하지 않으므로 파일 전송, 메일 서비스 등에는 적합하지 않다.
- 그러나 도메인 네임(domain name) 서비스나 daytime 서비스와 같이 한 패킷의 송수신으로 서비스가 이루어지는 경우에는 UDP가 편리하다.
- 한편 LAN과 같이 전송 오류가 거의 없고 패킷의 전달 순서가 바뀌지 않는 환경에서는 굳이 TCP를 사용하지 않아도 되므로 많은 트래픽이 발생하는 응용에서는 TCP보다 오버헤드가 적은 UDP가 유리하게 사용될 수 있다.
- 예를 들어 LAN에서 제공되는 NFS(Network FIle system)는 UDP를 사용한다.
- UDP는 패킷의 분실 확인, 중복 패킷의 검출, 전달 순서 보장 등을 해주지 않으므로 이러한 기능이 필요하다면 상위 응용 계층 프로그램에서 이를 처리하도록 프로그램을 작성하여야 한다.
- 그러나 UDP는 프로토콜 헤더가 8바이트로 작고 연결 설정에 필요한 지연이 없으므로 간단한 패킷을 주고받는 경우에 유리하다.
반응형