이 장에서는 OS에 내장된 네트워크 제어용 소프트웨어(프로토콜 스택)와 네트워크용 하드웨어(LAN 어댑터)가 브라우저에서 받은 메시지를 서버에 송출하는 동작을 탐험합니다.
애플리케이션 -> OS -> 드라이버 소프트웨어 -> 하드웨어
프로토콜 스택은 내부에 제어 정보를 기록하는 메모리 영역을 가지고 있으며, 여기에 통신 동작을 제어하기 위한 제어 정보를 기록합니다.
프로토콜 스택은 이 제어 정보를 참조하면서 동작합니다.
- socket을 호출하여 소켓을 만들 것을 의뢰하면 프로토콜 스택은 의뢰에 따라 한 개의 소켓을 만듭니다.
- 소켓을 나타내는 디스크립터를 애플리케이션에 알려줍니다.(프로토콜 스택의 내부에 있는 다수의 소켓 중 어느 것을 가르키는지를 나타냄).
- 디스크립터를 받은 애플리케이션은 이후 프로토콜 스택에 데이터 송수신 동작을 의뢰할 때 디스크립터를 통지
소켓을 만들면 애플리케이션(브라우저)는 connect를 호출합니다. 그러면 프로토콜 스택은 자기쪽의 소켓을 서버측 소켓에 접속합니다.
데이터를 신호로 변환하여 송신하기만 하면 언제든지 통신이 가능
소켓을 만든 직후는 아무것도 기록되어 있지 않으므로 통신 상대가 누군지 모릅니다.(저장 공간만 할당) 서버의 IP주소나 포트 번호를 프로토콜 스택에 알리는 동작이 필요
접속 동작 첫번째는 통신 상대와의 사이에 제어 정보를 주고받아 소켓에 필요한 정보(IP 주소, 포트 번호)를 기록하고 데이터 송수신이 가능한 상태로 만드는 것
데이터 송수신 동작을 실행할 때 일시적으로 저장하는 메모리 영역 버퍼 메모리 버퍼 메모리 확보 -> 접속
제어 정보는 크게 헤더, 소켓(프로토콜 스택의 메모리 영역)에 기록되는 정보
제어 정보를 패킷의 맨 앞부분에 배치하는 곳 -> 헤더
클라이언트와 서버는 헤더를 통해 정보를 기록하여 연락을 취하면서 동작 진행
이 대화가 가능하지 않으면 통신이 성립되지 않습니다.
제어 정보는 소켓에 기록하여 프로토콜 스택의 동작을 제어하기 위한 정보가 더 있습니다.(애플리케이션에서 통지된 정보, 통신 상대로부터 받은 정보 등이 수시로 기록 but, 소켓에 기록하는 제어 정보는 프로토콜 스택에 만드는 사람(ex. 윈도우와 리눅스)에 따라 달라지므로 간단히 설명 불가)
connect(디스크립터, 서버측의 IP 주소와 포트 번호);
서버측의 IP 주소와 포트 번호를 쓰면 명령이 프로토콜 스택의 TCP 담당 부분에 전달됩니다. 그러면 TCP 담당 부분은 IP 주소로 표시된 상대, 즉 서버의 TCP 담당 부분과의 사이에 제어 정보를 주고 받습니다.
헤더에는 다수의 항목이 있는데 중요한 것은 송신처와 수신처의 포트 번호입니다.
이를 통해 송신처가컨트롤 비트인 SYN이라는 비트를 1로 만듭니다.
이렇게 TCP 헤더를 만들면 이것을 IP 담당 부분에 건네주어 송신하도록 의뢰합니다. 그러면 IP 담당 부분이 패킷 송신 동작을 실행하고 네트워크를 통해 패킷이 서버에 도착하면 서버 측의 IP 담당 부분이 이것을 받아 TCP 담당 부분에 건네줍니다.서버 측의 TCP 담당 부분이 TCP 헤더를 조사하여 기록되어 있는 수신처 포트 번호에 해당하는 소켓을 찾아냅니다.
클라이언트와 마찬가지로 송신처와 수신처의 포트 번호나 SYN 비트 등을 설정한 TCP 헤더를 만듭니다. 그리고 응답을 돌려보낼 때 패킷을 받았다는 것을 알리기 위해 ACK라는 컨트롤 비트도 1로 만듭니다.
패킷이 도착한 것을 서버에 알리기 위해 ACK 1로 만들어 반송합니다.
이로써 소켓은 데이터를 송수신할 수 있는 상태가 됩니다.
connect에서 애플리케이션에 제어가 되돌아오면 데이터 송수신 동작에 들어갑니다. 이 동작은 애플리케이션이 write를 호출하여 송신 데이터를 프로토콜 스택에 건네주는 곳부터 시작됩니다.
프로토콜 스택은 받은 데이터를 곧바로 송신하는 것이 아니라 일단 자체의 내부에 있는 송신용 버퍼 메모리 영역에 저장하고, 애플리케이션이 다음 데이터를 건네주기를 기다립니다.
건네주는 데이터의 길이는 애플리케이션의 사정(ex. OS)에 따라 결정되며, 프로토콜 스택에서는 제어할 수 없습니다.
프로토콜 스택은 내부에 타이머가 있어서 이것으로 일정 시간 이상 경과하면 패킷을 송신합니다. (시간은 OS 종류나 버전에 따라 결정됩니다.)
HTTP 리퀘스트 메시지는 보통 그다지 길지 않으므로 한 개의 패킷에 들어가지만, 폼을 사용하여 긴 데이터를 보낼 경우 등 한 개의 패킷에 들어가지 않을 만큼 긴 것도 있습니다.
송신 버퍼에 저장된 데이터는 MSS의 길이를 초과하므로 다음 데이터를 기다릴 필요가 없습니다.
TCP에는 송신한 패킷이 상대에게 올바르게 도착했는지 확인하고, 도착하지 않았으면 다시 송신하는 기능이 있으므로 패킷을 송신한 후에는 동작으로 넘어갑니다.
시퀀스 번호 : 데이터의 조각을 송신할 때 세어둔 값을 TCP 헤더에 기록한 값.
패킷 전체의 길이에서 헤더 길이를 빼면 데이터의 크기를 계산하여 산출
수신 확인 응답 : 수신 측은 그 이전에 수신한 데이터와 합쳐서 데이터를 몇 번째 바이트까지 수신한 것인지 계산하고, 그 값을 TCP 헤더의 ACK 번호에 기록하여 송신측에 알려줍니다.
ACK 번호가 돌아오는 것을 기다리는 시간을 타임아웃 값이라고 합니다.
한 개의 패킷을 보낼 때마다 ACK 번호를 기다리는 방법은 단순하지만 시간 낭비입니다.
수신 측의 TCP는 패킷을 수신하면 일단 수신용 버퍼 메모리에 데이터를 일시 보관합니다. 수신 버퍼에 데이터가 차곡차곡 쌓여서 곧 넘쳐버리는데 이 것을 초과하지 않도록 송신 동작을 실행하는 방식을 윈도우 제어 방식이라고 합니다.
윈도우 사이즈 : 수신 가능한 데이터 양의 최대값
송수신 동작의 효율성을 높이기 위해 ACK 번호와 윈도우를 통지하는 타이밍을 고려해야 합니다.
수신측에서 애플리케이션에 데이터를 건네주고 수신 버퍼의 빈 영역이 늘어났을 때 이것을 송신 측 에 통지하는 것을 윈도우 통지 타이밍이라고 합니다.
ACK 번호는 수신측에서 데이터를 받았을 때 내용을 조사하여 정상 수신을 확인할 수 있는 경우에만 송신측에 보냅니다. 데이터를 수신한 후 즉시 보낸다.
브라우저는 리퀘스트 메시지를 송신해 달라고 의뢰하고, 끝나면 서버에서 돌아오는 응답 메시지를 받기 위해 read 프로그램을 호출합니다.
데이터 송수신 동작이 끝난 후 프로토콜 스택의 움직임을 설명합니다.
웹이라면 브라우저에서 웹 서버에 리퀘스트 메시지를 보내고, 서버가 이것에 응답하여 응답 메시지를 반송 완료하면 데이터 보내기가 완료된 것입니다. 서버측이 연결 끊기 단계에 들어갑니다.
서버와의 대화가 끝나면 소켓을 사용하여 서버와 대화할 수 없게 됩니다. 하지만 오동작이 있을 수 있으므로 바로 소켓을 말소하지 않고 잠시 기다린 후 소켓을 말소합니다.
TCP 프로토콜에서 애플리케이션의 데이터를 송수신하는 동작 정리
최초의 동작은 소켓을 작성하는 단계
소켓을 만들면 클라이언트 서버를 향해 접속 동작을 실행
데이터 송수신 단계
응답 메시지 보내기를 완료하면 데이터 송수신 동작이 끝나므로 연결 끊기 동작 시작
TCP 담당 부분은 접속, 송수신, 연결 끊기의 각 단계에서 통신 상대와 대화할 때 IP 담당 부분에 의뢰하여 대화하는 데이터를 패킷의 모습으로 만들어 상대에게 도착합니다. 의뢰를 받은 IP 담당 부분이 어떻게 패킷을 상대에게 송신하는지 살펴보겠습니다.
TCP/IP의 패킷
MAC 헤더 IP 헤더 TCP 헤더 데이터 조각
이더넷의 패킷 : MAC 헤더 + IP 헤더 + TCP 헤더 + 데이터 조각
IP의 패킷 : IP 헤더 + TCP 헤더 + 데이터 조각
먼저 패킷의 송신처가 되는 기기가 패킷을 만드는데, 헤더에는 적절한 제어 정보를 기록하고, 데이터 부분에는 얼마간의 데이터를 넣은 후 패킷을 가장 가까운 중계 장치에 송신합니다.
중계 장치는 도착한 패킷의 헤더를 조사하여 패킷의 목적지를 판단 합니다. 목적지를 향해 패킷을 송신하면 패킷은 다음 중계 장치에 도착
차례로 패킷을 중계하면 최종적으로 수신처의 기기에 패킷이 도착
송신처와 수신처의 기기 : 엔드 노드
순서
MAC 헤더 : 이더넷용 헤더
IP용 헤더 : IP용 헤더
IP 담당 부분은 다음 두 개의 헤더를 덧붙입니다.
IP 담당 부분은 TCP 담당 부분에서 패킷 송수신 의뢰를 받으면 IP 헤더를 만들어 TCP의 헤더의 앞에 붙입니다.
IP 헤더의 수신처 IP 주소에는 통신 상대의 주소를 설정합니다.
송신처 IP 주소는 송신처가 되는 LAN 어댑터를 판단하여 주소를 설정합니다.
어떤 상황에서는 TCP 보다 효율적으로 데이터를 다시 보낼 수 있습니다.
DNS 서버에 대한 조회 등 제어용으로 실행하는 정보 교환은 한 개의 패킷으로 끝나는 경우가 많으므로 UDP를 사용합니다.
UDP 헤더
음성이나 영상 데이터는 결정된 시간 안에 데이터를 건네주어야 합니다. 데이터의 도착이 지연되면 이것을 재생하는 타이밍이 맞지 않아서 음성이 끊기거나 영상이 멈춥니다. 몇 배나 더 빠른 고속 회선이 필요한데 UDP가 효율적입니다.