네트워크

dawn·2021년 4월 19일
0

네트워크

목록 보기
2/3

성공과 실패를 결정하느 1%의 네트워크 원리 2장 - 프로토콜 스택과 LAN어댑터의 탐험

1장에서는 브라우저의 URL 입력 상자에 입력한 URL을 해독하는 곳부터 시작하여 그것을 바탕으로 HTTP 리퀘스트 메시지를 만들고 송신하도록 OS에 의뢰하는 곳까지 탐험했습니다. 이 장에서는 OS에 내장된 프로토콜 스택이 어떻게 송신을 의뢰하는지에 대해 설명합니다.

    1. 소켓을 작성한다.
    • 소켓을 만든다. 프로토콜 스택의 내부구성, 소켓의 실체, 소켓을 만드는 동작 설명
    • 애플리케이션에서 의뢰를 받은 프로토콜 스택이 TCP 프로토콜을 이용해서 메시지를 송신하는 동작은 4단계로 구분할 수 있다.
    1. 서버에 접속한다.
    • 클라이언트 측의 소켓을 서버측의 소켓에 접속하는 단계

1. 프로토콜 스택의 내부 구조


OS에 내장된 네트워크 제어용 소프트웨어(프로토콜 스택)와 네트워크용 하드웨어(LAN 어댑터)가 브라우저에서 받은 메시지를 서버에 송출하는 동작을 탐험하기 전에 프로토콜 스택에 대해 먼저 알아본다.

이 그림의 상하 관계는 작업을 의뢰하는 쪽이 위쪽에 있고, 의뢰를 받아 실제로 작업하는 쪽이 아래에 있다는 의미이다.
맨 위에 있는 것은 네트워크 애플리케이션이다. 브라우저, 메일러, 웹서버, 메일 서버 등의 프로그램이 여기에 해당한다. 여기부터 아래로 향하여 데이터 송수신 등의 일을 의뢰한다.

1.1. 네트워크 애플리케이션

그 아래가 OS의 내부를 나타내며, 여기에 프로토콜 스택이 있다. 프로토콜 스택의 윗부분에는 데이터 송수신을 담당하는 TCP,UDP라는 프로토콜이 있으며, 이 둘이 애플리케이션에서 보낸 의뢰를 받아 송수신 동작을 실행한다. 브라우저나 메일 등의 일반적인 애플리케이션은 TCP를 사용하여 데이터를 송수신한다. 그리고 DNS서버에 대한 조회 등에서 짧은 제어용 데이터를 송수신 하는 경우에는 UDP를 사용한다.

1.2.프로토콜 스택

인터넷에서 데이터를 운반할 때는 데이터를 작게 나누어 패킷이라는 형태로 운반하는데, 이 패킷을 통신 상대까지 운반하는 것이 IP의 주 역할이다. 그리고 IP 안에는 ICMP와 ARP라는 프로토콜을 다루는 부분이 포함되어 있다. ICMP는 패킷을 운반할 때 발생하는 오류를 통지하거나 제어용 메시지를 통지할 때, ARP는 IP주소에 대응하는 이더넷의 MAC주소를 조사할 때 사용한다.

1.3. LAN

IP의 아래에 있는 LAN 드라이버는 LAN 어댑터의 하드웨어를 제어한다. 그리고 그 아래에 있는 LAN 어댑터가 실제 송수신 동작, 즉 케이블에 대해 신호를 송수신하는 동작을 실행한다.


2. Socket

프로토콜 스택 내부의 구조를 알아봤으니 이제는 소켓에 대해 구체적으로 알아보자.
프로토콜 스택은 내부에 제어 정보를 기록하는 메모리 영역을 가지고 있으며 여기에 통신 동작을 제어하기 위한 제어정보를 기록하는데 이 제어 정보가 소켓의 실체라고 할 수 있다 대표적인 정보는 통신 상대의 IP 주소는 무엇인가, 포트 번호는 몇 번인가, 통신 동작이 어떤 진행 상태에 있는가 하는 것이다. 즉, 프로토콜 스택은 소켓에 기록된 제어 정보를 참조하면서 움직인다.

소켓을 만든다는 동작은 여기(netstat: 윈도우 명령)에 새로 한 행의 제어 정보를 추가하고 '여기부터 통신을 시작하는 곳'이라는 식으로 상태를 기록하거나 송수신 데이터를 일시적으로 저장하는 버퍼 메모리를 준비하는 등 통신을 준비하는 작업이다.

2.1. Socket을 호출했을 때의 동작

브라우저가 socket이나 connect라는 Socket 라이브러리의 프로그램 부품을 호출했을 때 프로토콜 스택의 내부가 어떻게 움직이는지 살펴보자

2.1.1. 소켓을 만든다.

애플리케이션이 socket을 호출하여 소켓을 만들 것을 의뢰하면 프로토콜 스택은 의뢰에 따라 한 개의 소켓을 만든다. 이 때 프로토콜 스택이 최초로 하는 일은 소켓 한 개 분량의 메모리 영역을 확보하고 초기 상태라는 것을 이 영역에 기록하는 것이다. 소켓의 제어 정보를 기록하는 메모리 영역은 처음부터 존재하는 것이 아니므로 먼저 그것을 확보해두어야 한다.
소켓이 만들어지면 소켓을 나타내는 디스크립터를 애플리케이션에 알려준다. 디스크립터를 받은 애플리케이션은 이후 프로토콜 스택에 데이터 송수신 동작을 의뢰할 때 디스크립터를 통지한다. 이렇게 해서 통신 상대의 정보를 애플리케이션에서 일일이 통지받을 필요가 없어진다.

2.1.2. connect를 호출해 서버에 접속한다.

소켓을 만들면 애플리케이션(브라우저)은 connect를 호출한다. 그러면 프로토콜 스택은 자기쪽의 소켓을 서버측 소켓에 접속한다. 접속동작의 첫 걸음은 TCP 담당 부분에서 접속을 나타내는 제어 정보를 기록한 TCP헤더를 만드는 것이다. 그리고 TCP 헤더의 송신처와 수신처의 포트 번호로 접속하는 소켓을 지정한다.
데이터 송수신 동작을 실행할 때는 송수신하는 데이터를 일시적으로 저장하는 메모리 영역이 필요한데 이 메모리 영역을 '버퍼 메모리'라고 한다. 버퍼 메모리의 확보도 접속 동작을 할 때 실행된다.

그 다음 TCP헤더를 IP 담당 부분에 건네주어 송신하도록 의뢰한다. 그러면 IP 담당 부분이 패킷 송신 동작을 실행하고 네트워크를 통해 서버에 도착하면 서버측의 IP 담당 부분이 이것을 받아 TCP 담당 부분에 건네준다. 이후 서버측의 TCP 담당 부분이 TCP 헤더를 조사하여 기록되어 있는 수신처 포트 번호에 해당하는 소켓을 찾아낸다. 접속 동작이 진행 되면 서버의 TCP 담당 부분은 TCP 헤더를 만들어 응답을 돌려보낸다. 이로써 소켓은 데이터를 송수신할 수 있는 상태가 된다.

그렇다면 제어 정보에 대해 자세히 알아보자!
통신 동작에 이용하는 제어 정보는 헤더에 기입되는 정보와 소켓에 기록되는 정보 두가지가 있다.
1) 헤더 :하나는 클라이언트와 서버가 서로 연락을 절충하기 위해 주고받는 제어정보이다. 접속 동작의 단계에서는 데이터가 없고 패킷의 내용은 제어 정보로만 이루어져 있는데 이것을 헤더라고 부른다. 접속, 송수신, 연결끊기의 각 단계에서 클라이언트와 서버가 대화할 때마다 클라이언트와 서버 사이에 주고받는 패킷의 맨 앞부분에 부가한다.

2)소켓에 기록되는 정보 : 소켓에 기록하여 프로토콜 스택의 동작을 제어하기 위한 정보
클라이언트와 서버는 이 헤더에 필요한 정보를 기록하여 연락을 취하면서 통신 동작을 진행한다.여기에는 애플리케이션에서 통지된 정보, 통신 상대로부터 받은 정보, 송수신 동작의 진행상황 등 이 수시로 기록되며, 프로토콜 스택은 하나하나 차례로 정보를 참조하면서 움직인다.
소켓에 기록한 제어정보는 상대측에서 볼 수 없다.

2.1.3. 데이터를 송수신한다.

데이터를 송신하는 동작은 다음과 같다.
1) 프로토콜 스택에 HTTP 리퀘스트 메시지를 넘긴다.
connect에서 애플리케이션에 제어가 되돌아오면 데이터 송수신 동작이 들어간다. 이 동작은 애플리케이션이 write를 호툴하여 송신 데이터를 프로토콜 스택에 건네주는 곳부터 시작된다.
이때 프로토콜 스택은 받은 데이터를 곧바로 송신하는 것이 아니라 일단 자체의 내부에 있는 송신용 버퍼 메모리 영역에 저장하고, 애플리케이션이 다음 데이터를 건네주기를 기다린다.

2) 데이터가 클 때는 분할하여 보낸다.
HTTP 리퀘스트 메시지는 보통 그다지 길지 않으므로 한 개의 패킷에 들어가지만, 폼을 사용하여 긴 데이터를 보낼 경우 한 개의 패킷에 들어가지 않울 만큼 긴것도 있다. 띠라서 송신 버퍼에 들어있는 데이터를 맨 앞부터 차례대로 MSS의 크기에 맞게 분할하고, 분할한 조각을 한 개씩 패킷에 넣어 송신한다.

3) ACK번호를 사용하여 패킷이 도착했는지 확인한다.
TCP에는 송신한 패킷이 상대에게 올바르게 도착했는지 확인하고, 도착하지 않았으면 다시 통신하는 기능이 있으므로 패킷을 송신한 후에는 확인 동작으로 넘어간다.
시퀀스 번호와 ACK번호를 통해 상대가 데이터를 받은것을 확인하는데, 확인할 때까지 송신한 패킷을 송신용 버퍼 메모리 영역에 보관해 둔다. 그리고 송신한 데이터에 대응하는 ACK번호가 상대로부터 돌아오지 않으면 패킷을 다시 보낸다.

프로토콜 스택이 데이터를 수신할 때는 먼저 수신한 데이터 조작과 TCP 헤더의 내용을 조사하여 도중에 데이터가 누락되었는지 검사하고, 문제가 없으면 ACK번호를 반송한다. 그리고 데이터 조각을 수신 버처에 일시 보관하고. 조각을 연결하여 데이터를 원래 모습으로 복원한 후 애플리케이션에 건네준다. 구체적으로는 수신 데이터를 애플리케이션이 지정한 메모리 영역에 옮겨 기록한 후 애플리캐이션에 제어를 되돌려준다. 그리고 애플리케이션에 데이터를 건네주고 나서 타이밍을 가늠하여 윈도우를 송신측에 통지한다.

2.1.4. 데이터 보내기를 완료했을 때 연결을 끊는다.

데이터 보내기를 완료한 쪽에서 연결 끊기 단계에 들어가는데, 웹의 경우 서버에서 연결 끊기 동작에 들어갈것이다. 거기에서는 먼저 FIN을 1로만든 TCP 헤더가 흐르고 이것을 받았음을 나타내는 ACK번호의 TCP헤더가 돌아올 것이다. 이후 역방향으로 FIN을 1로 만든 TCP헤더와 ACK 번호의 TCP헤더가 흐르다가 잠시 후 소켓이 말소된다.


그림출처

profile
안녕하세요

0개의 댓글