간단하게 정리한 질문에 대한 답변
1. 유저가 브라우저에서 www.google.com을 입력하면 먼저 브라우저에서 HTTP request message를 생성합니다.
2. 이후 DNS lookup을 통해 보내야 하는 서버 주소 ip를 알아 옵니다.
3. HTTP 메시지를 TCP/IP층에 전달합니다.
- TCP/IP 층에서는 HTTP 요청메시지에 자신들의 헤더를 추가하여 패킷을 생성합니다.
- TCP층에서는 상대방의 포트, 나의 포트가 추가되고, TCP 연결을 위한 flag등이 헤더에 추가되고
- IP층에서는 상대방의 ip 주소, mac주소 등이 추가가 됩니다.
4. 패킷은 전기신호로 변환되어 랜선을 통해 라우터들을 거쳐 목적지 ip에 전달되게 됩니다.
5. 목적지 서버에서는 전달받은 패킷을 생성한 과정과 반대로 해제하여 메시지를 복원합니다.
6. 복원된 메시지는 메시지에 기록되어 있는 포트로 전달되고 포트번호에 기록되어 있는 pid를 통해 해당 프로세스로 전달됩니다.
7. 서버의 프로세스에는 요청에 맞는 행동을 하고 response data를 가지고 HTTP response message를 생성합니다.
8. HTTP 응답 메시지를 전달받은 방식 그대로 client에게 보냅니다.
9. client에서는 응답 메시지를 가지고 브라우저에서 보여주게 됩니다.
이 글은 성공과 실패를 결정하는 1%의 네트워크 원리 책의 정리 내용입니다!
이 책은 주소창에 url을 입력하면 정보가 나오는 과정을 하나하나 세세히 알려줍니다.
근데 이 알려주는 방식이 반복해서 알려주고 친절히 알려줍니다.
아래에 교보문고 링크를 첨부해 두었으니 구매하셔도 좋을것 같습니다!
책의 목차
1장 웹 브라우저가 메시지를 만든다(웹 브라우저의 내부 탐험)
2장 TCP/IP의 데이터를 전기 신호롤 만들어 보낸다(프로토콜 스택과 LAN 어댑터의 탐험)
3장 케이블의 앞은 LAN 기기 였다(허브와 스위치, 라우터의 탐험)
4장 엑세스 회선을 통해 인터넷의 내부로!(액세스 회선과 프로바이더의 탐험)
5장 서버측의 LAN에는 무엇이 있는가?(방화벽과 캐시 서버의 탐험)
6장 웹 서버에 도착하여 응답 데이터가 웹 브라우저로 돌아간다(불과 몇 초인 '긴 여행'의 끝)
세부 내용
우선 이책의 내용은 http1.0 ~ http1.1을 기준으로 설명합니다.
현재는 http2가 2015년도 부터 상용화 되어 적용되어 지고 있고(점유율 40%정도),
구글에서 개발한 quic를 기반으로한 http3 또한 점차 적용중입니다.(udp 프로토콜 사용)
http2, http3에 대한 자세한 사항은 나중에 따로 포스팅 하고 이 책의 배경에 대해 먼저 언급 하였습니다!
1장 웹 브라우저가 메시지를 만든다(웹 브라우저의 내부 탐험)
주소창에 먼저 탐색하고자 하는 주소를 입력하면
브라우저는 요청 메시지를 만듭니다.
이 요청 메시지를 서버의 Ip에 보내고 서버에서는 요청에 따른 응답을 처리한후
응답 메시지를 생성해 요청이 들어온 곳에 응답 메시지를 보내줍니다.
브라우저에서 요청을 보내려면 먼저 서버의 ip 주소를 알아야 합니다.
목적지를 모르는데 선물을 보낼수는 없으니까요
브라우저에서는 요청 메시지 생성후 DNS 서버에 요청하여 해당 도메인의 ip 주소를 가져옵니다.
이때 소켓 라이브러리의 리졸버를 이용하고 UDP 프로토콜을 이용합니다.
생성되는 request message는 크게 세부분으로 구성됩니다.
- startline => 요청 메소드, 요청 주소, 프로토콜 버전이 명시됩니다.
- header => 요청시에 활용하는 헤더가 들어갑니다.
- body => post와 같이 body에 포함될 정보가 있을때 추가됩니다.
생성되는 response message도 크게 세부분으로 구성됩니다.
- startline => 프로토콜 버전, status code, 응답문구(status code의 내용을 나타내는 짧은 설명문)
- header => 응답 헤더
- body => 메시지 본문의 내용
어플리케이션에서 네트워크 요청은 OS의 내부에 포함된 프로토콜 스택에 실행을 의뢰합니다.
프로토콜 스택에서는 TCP/UDP, IP로 역할이 구분되어 있고 이후에는 네트워크 LAN 어댑터에서 실제 네트워크 요청이 이뤄지게 됩니다.
DNS 서버에서는 계층적으로 동작하게 됩니다. 트리구조로 존재하게 됨으로써 요청을 효율적으로 처리할 수 있습니다.
도메인에는 캐시를 활용합니다.
캐시란 요청에 대한 응답을 미리 저장해두고 요청이 발생하면 저장해둔 응답을 꺼내어 주는 것입니다.
이때 캐시의 기간 설정을 잘 하는 것이 중요합니다. 실제 도메인 주소에 해당하는 ip는 변경이 되었지만 캐시에 있는 응답을 사용하게 되면 잘못된 주소를 client에게 전달할 수 있기 때문입니다.
프로토콜 스택에 네트워크 요청을 의뢰하게 되면 내부적으로는 아래와 같이 동작합니다.
- 소켓을 만듭니다(소켓 작성 단계)
- 서버측의 소켓에 파이프를 연결합니다(접속 단계)
- 데이터를 송, 수신 합니다.(송.수신 단계)
- 파이프를 분리하고 소켓을 말소합니다(연결 끊기 단계)
현재 동작하는 소켓을 확인하려면 command line에서 netstat 명령어를 통해 소켓들을 확인할 수 있습니다.
소켓은 연결에 관한 정보를 가지고 있는 일련의 객체 입니다.
process, 상대방의 ip:port 주소 나의 ip:port 주소 등을 알수 있습니다.
소켓에 관한 설명은 추후에 더해질 예정입니다.
2장 TCP/IP의 데이터를 전기 신호롤 만들어 보낸다(프로토콜 스택과 LAN 어댑터의 탐험)
위의 그림이 핵심입니다.
소켓라이브러리 에서는 DNS서버에 조회하는 동작을 실행합니다.
프로토콜 스택은 OS에 위치하고 이곳에서 TCP/UDP, IP의 처리가 이루어 집니다.
ICMP는 IP계층에서 문제가 일어났을때 상대방에게 에러메시지를 반환해주는 곳
ARP는 상대방의 MAC주소를 알아야 할때 사용하는 프로토콜 입니다.
프로토콜 스택은 이전에 언급한 소켓의 제어정보를 참조하면서 동작합니다.
소켓에는 상대방의 IP 주소, port 번호, 통신동작은 어떤 상태에 있는지, 자신의 어떤 프로세스에서 동작하고 있는지 등이 기록되어 있습니다. (소켓에는 정보가 기록되어 있는 메모리 영역이다 라고 이해하셔도 무방합니다.)
서버측 에서는 자신의 소켓을 생성해 둡니다.
그리고 요청이 들어오면 생성해둔 소켓의 정보를 그대로 복사하고 소켓의 상대방 ip:port에 요청이 들어온 ip:port를 기록합니다.
요청이 들어올때마다 기존의 정보를 계속 복사하여 새로운 소켓을 생성합니다.
그리고 요청이 요청/응답이 종료되면 해당 소켓을 제거합니다.
TCP 헤더의 포맷중 일부
TCP 헤더 | 송신처 포트 번호 | 16비트 | 패킷을 송신한 측의 포트번호 |
수신처 포트 번호 | 16비트 | 패킷을 수신하는 측의 포트번호 | |
시퀀스 번호 | 32비트 | 이 패킷의 맨 앞 위치의 데이터가 송신 데이터의 몇 번째 바이트에 해당하는지를 송신측에서 수신측에 전달하기 위한 것 | |
ACK 번호 | 32비트 | 데이터가 몇 바이트가 수신측에 도착했는지를 수신측에서 송신측에 전달하기 위한것. ACK는 acknowledge의 약자 | |
컨트롤 비트 | 6비트 | 통신 제어를 의미 * URG * PSH * RST * ACK : 수신 데이터의 일련번호 필드가 유효하다는 것을 나타냅니다. 보통 데이터가 올바르게 수신측에 도착했다는 것을 의미 * SYN : 송신측과 수신측에서 일련번호를 서로 확인합니다. 접속 동작을 나타냅니다. * FIN : 연결 끊기를 나타냅니다. |
아래는 패킷이 생성되는 과정을 도식화 한것입니다.
TCP 계층에서 TCP 헤더가 어플리케이션 계층에서 넘겨받은 데이터의 앞에 붙게 되는데
이때 TCP 헤더에 포함되는 것이 제어정보이고 이것이 위에서 언급한 TCP 헤더의 정보입니다.
IP헤더에는 IP 계층에 관한 제어정보
MAC 헤더에는 MAC 주소에 관한 제어정보가 들어가게 됩니다.
특이한 점은 IP 계층에서 두개의 헤더가 추가된다는 것이고 두 헤더의 주요정보에 대해서는 아래에서 설명하겠습니다.
TCP 통신의 동작 흐름을 살펴보겠습니다.
헤더에 대한 정보와 흐름을 같이 살펴보시면 좋습니다.
3-way handshake, 4-way handshake에 대한 흐름도 같이 확인할 수 있습니다.
TCP 통신은 접속, 송/수신, 해제 단계로 나뉘어 집니다.
3-way handshake, 4-way handshake에 대하여는 너무 유명하므로 언급하지 않겠습니다.
예외로 한가지 언급할 점은 4-way handshake에서 기다리는 시간이 존재하는데 이 기다리는 시간은 클라이언트에서 남은 데이터의 수신을 완료할때 까지 기다려 주는 시간입니다.
송/수신 단계에서 데이터를 요청하면 시퀀스 번호와 데이터를 보냅니다.
수신을 받은쪽에서는 ack를 보냄으로써 몇번째 데이터까지 받았는지를 알려줍니다.
이 과정에서 HOL(Head of Line) blocking이 발생하게 됩니다.
이걸 대체하기 위해 HTTP2에서 멀티 플렉스 스트리밍이 도입됩니다.
자세한 설명은 이전에 포스팅한 내용이 있으므로 첨부하겠습니다.
2022.04.16 - [네트워크] - 네트워크 HTTP, HTTP 1.1, HTTP 2.0 🔥
IP 헤더의 주요정보에는 아래와 같은것들이 있습니다.
아래의 제어정보들이 ip 계층에서 헤더에 추가됩니다.
IP 헤더 | ID 정보 | 16비트 | 패킷을 식별하는 번호입니다. IP 클라이언트에 따라 분할된 패킷은 모두 값이 같습니다. |
생존기간(TTL) | 8비트 | 패킷이 영구적으로 순환하지 않도록 해주는 헤더 입니다. 라우터 하나를 거칠때마다 -1씩 됩니다. | |
프로토콜 번호 | 8비트 | 프로토콜의 번호가 기록됩니다. * TCP : 06(16진수 표기) * UDP : 11(16진수 표기) * ICMP : 01(16진수 표기) |
|
플래그 | 3비트 | 유효한 것은 2비트 입니다. 조각나누기가 가능한지 나타내고, 이 패킷이 조각으로 나눈것인지를 나타냅니다. | |
fragment offset | 13비트 | 패킷에 저장된 부분이 IP 메시지의 맨 앞부분부터 몇 번째 바이트에 위치하는지를 기록합니다. | |
송신처 IP 주소 | 32비트 | 패킷을 송신한 쪽의 IP 주소 입니다. | |
수신처 IP 주소 | 32비트 | 패킷을 수신한 쪽의 IP 주소 입니다. |
IP 담당 부분은 IP 헤더를 붙였으면 그 앞에 MAC 헤더를 붙입니다.
MAC 헤더는 이더넷에서 사용하는 헤더로서 수신처나 송신처의 MAC 주소 등이 기록되어 있습니다.
MAC 헤더 | 수신처 MAC 주소 | 48비트 | 패킷을 전달하는 상대의 MAC 주소 |
송신처 MAC 주소 | 48비트 | 패킷을 송신한 쪽의 MAC 주소 | |
이더 타입 | 48비트 | 사용하는 프로토콜의 종류를 나타냅니다. 0800 : IP 프로토콜 0806 : ARP 프로토콜 86DD : IPv6 |
MAC 헤더의 정보들은 패킷의 MAC 헤더에 추가됩니다.
IP 계층에서 MAC 헤더의 추가가 이루어 집니다.
이때 MAC 주소는 device마다 고유한 값을 가지게 됩니다.
LAN 어댑터를 제조할 때 그 안에 있는 ROM에 기록되므로 여기에 기록되어 있는 값을 읽어와서 MAC 헤더로 설정합니다.
상대의 MAC 주소를 알기위해서 ARP 프로토콜을 이용합니다.
이때 또한 중복된 요청을 방지하기 위해 캐시를 적극 활용하게 됩니다.
command line에서 arp -a 명령어를 통해 arp 캐시의 내용을 확인할 수 있습니다.
이제 IP계층에서 추가되는 헤더까지 살펴보았습니다.
다음은 데이터링크 계층에서 추가되는 헤더를 살펴볼 차례입니다.
데이터 링크 계층에서는 앞뒤로 하나씩 붙게 됩니다.
아래의 추가는 LAN 어댑터에서 추가가 됩니다.
프리앰블은 전기신호를 해석하는 타이밍을 제공하기 위해 추가되고 FCS는 오류검출을 하기 위한 용도로 추가됩니다.
프리앰블 : 송신하는 패킷을 읽을 때의 타이밍을 잡기 위한 것입니다.
스타트 프레임 딜리미터 : 11로 끝이 나는 비트 패턴입니다. 11 뒤에 패킷이 시작된다는 것을 알려주기 위해 사용합니다.
FCS : 오류 검출을 위하여 사용합니다. 패킷을 운반하는 도중에 잡음으로 인해 내용의 데이터가 변하면 수신측에서 계산한 FCS값과 송신측에서 계산한 FCS 값이 다르게 나타납니다. 다르면 오류입니다.
TCP 통신과 다르게 UDP 통신은 연결의 신뢰성을 보장하지 않습니다.
그래서 TCP 헤더에 비해 작은 사이즈의 헤더를 가지게 됩니다.
아래는 UDP 헤더의 정보입니다.
UDP 헤더 | 송신처 포트 번호 | 16비트 | 패킷을 송신한 측의 포트 번호 |
수신처 포트 번호 | 16비트 | 패킷을 수신한 측의 포트 번호 | |
데이터 길이 | 16비트 | UDP 헤더 이후의 길이 | |
체크섬 | 16비트 | 오류 유무를 검사하기 위한 것 |
DNS를 조회할때 UDP 통신을 이용하고, http3 에서도 UDP 기반의 통신을 이용합니다.
UDP는 음성이나 동영상등을 전달할때 사용합니다.
3장 케이블의 앞은 LAN 기기 였다(허브와 스위치, 라우터의 탐험)
가장 중요한 부분은 라우터 부분입니다.
라우팅 테이블의 경로표에는 아래와 같은 정보들이 기록되어 있습니다.
라우터는 IP 헤더에 포함되어 있는 수신처 IP 주소로 중계대상을 판단합니다.
아래는 라우터에 패킷이 도착했을때의 동작입니다.
- 신호가 도착하면 PHY 회로와 MAC 회로에서 신호를 디지털 데이터로 변환합니다.
- 패킷 끝부분의 FCS를 검사하고 오류가 있는지를 확인합니다.
- MAC 헤더의 MAC 주소가 자신의 MAC주소와 같다면 패킷을 수신 버퍼 메모리에 저장합니다(같지 않다면 패킷을 폐기합니다. 기본 통신 방식이 브로드캐스트 방식이기 때문에 폐기하여야 합니다)
라우터에서는 패킷 수신동작이 끝나면 맨앞의 MAC 헤더를 폐기합니다.
MAC 헤더의 역할은 이 라우터에 패킷을 건네주는 것이기 때문에 역할을 다 했습니다.
이제 라우터에서 다음 라우터 혹은 서버에 전달해주기 위해 MAC 헤더를 교체해주어야 합니다.
라우터에서 추가해주는 MAC 헤더의 송신 MAC 정보는 자신의 MAC 주소가 됩니다.
수신 MAC 정보를 알아야 하는데 이때는 아래와 같은 단계로 진행이 됩니다.
- 경로표의 '게이트웨이' 항목에 IP 주소가 쓰여있으면 IP 주소가 건네줄 상대
- 경로표의 '게이트웨이' 항목이 공란이면 IP 헤더의 수신처 IP 주소가 건네줄 상대 입니다.
이제 상대의 IP 주소를 알았으므로 ARP캐시 혹은 ARP를 이용하여 상대방의 MAC 주소를 알수 있습니다.
이렇게 알게된 수신측의 MAC 주소로 MAC 헤더를 완성하여 다시 요청을 전달해줍니다.
4장 엑세스 회선을 통해 인터넷의 내부로!(액세스 회선과 프로바이더의 탐험) , 5장 서버측의 LAN에는 무엇이 있는가?(방화벽과 캐시 서버의 탐험)
4,5 장은 내용의 이해가 부족하여 추후에 정리 예정입니다.
6장 웹 서버에 도착하여 응답 데이터가 웹 브라우저로 돌아간다(불과 몇 초인 '긴 여행'의 끝)
서버와 클라이언트에는 공통점과 차이점이 있습니다.
우선 서버는 용도에 따라 다양한 종류가 있고 하드웨어나 OS 부분은 클라이언트와 다른 것도 있습니다.
그러나 네트워크에 관한 부분, LAN 어댑터, 프로토콜 스택, Socket 라이브러리 등의 기능은 클라이언트와 조금도 다르지 않습니다.
서버측에서는 다음과 같은 단계로 소켓을 관리합니다.
- 소켓을 만듭니다(소켓 작성 단계)
- 2-1 소켓을 접속 대기 상태로 만듭니다(접속 대기 상태)
2-2 접속을 접수 합니다(접속 접수 단계) - 데이터를 송/수신 합니다(송/수신 단계)
- 파이프를 분리하고 소켓을 말소합니다((연결 끊기 단계)
이때 주요한 점이 있습니다.
서버쪽에서는 응답을 처리할때 클라이언트 IP, 클라이언트 포트 번호, 서버의 IP, 서버의 포트 번호 모두를 가지고 처리합니다.
이 4개의 정보는 소켓에 저장이 되어있습니다.
접속 대기 상태의 소켓을 만들어 놓습니다.
클라이언트에서는 이 소켓의 포트와 IP 주소를 가지고 갑니다.
클라이언트에 이 포트를 가지고 가므로 서버에서는 다른 포트의 소켓을 생성할 수가 없습니다.
따라서 같은 포트를 가진 소켓을 생성해야 합니다.
이러면 복수의 클라이언트에서 하나의 포트로 요청이 들어오게 되는데 응답을 어디에 보내주어야 할지 알수가 없습니다.
그래서 클라이언트의 IP/port를 같이 소켓에 저장하게 됩니다.
복수의 클라이언트끼리 같은 port번호를 자신의 소켓에 할당하였을 수도 있습니다.
그래서 ip 주소까지 이용하여 같은 port 번호가 배정되는 상황을 구별하기 위하여 사용합니다.
이러한 모든 정보를 매번 구별할 수는 없으므로 Pid 같이 소켓들을 구별하기 위한 디스크립터를 사용합니다.
'네트워크' 카테고리의 다른 글
네트워크 Browser 요청의 제한🌱 (HTTP/1.1, HTTP/2) (0) | 2022.04.21 |
---|---|
네트워크 JWT 🗝 (0) | 2022.04.19 |
네트워크 HTTP, HTTPS, SSL HandShake 😶🌫️ (0) | 2022.04.17 |
네트워크 HTTP, HTTP 1.1, HTTP 2.0 🔥 (0) | 2022.04.16 |
html5, 웹 표준 및 웹 접근성 🔥 (0) | 2022.04.13 |