https://balldev.tistory.com/33
시스템을 연결하는 네트워크 구조
네트워크 서로 다른 장비 간에 데이터를 교환할 때 기본적으로 네트워크를 경유해서 데이터 송수신 네트워크는 계층 간 역할이 나누어져 있다. 상호 연결되어 있는 계층들에서는 인터페이스로
balldev.tistory.com
위는 네트워크를 간단하게 정리한 글이고 이것을 좀 더 자세하게 풀어보려고 합니다.
전체적인 flow 순으로 작성했습니다.
주소창에 url을 입력한다.
- url을 입력 → 해당 웹서버에 get요청 전달 → 요청 내용 해석
- 응답으로 html 파일이 반환
- 브라우저는 이 파일을 해석해서 파일 내에 추가 이미지나 스크립트 등이 포함돼있으면 웹 서버에 이들을 다시 요청합니다.
⇒ 이 때 요청과 응답에는 메세지 헤더(상세정보 user-agent, host, cookie등), 바디가 들어간다.
브라우저가 DNS 요청을 OS에 의뢰하고 실행
인터넷 세상에는 막대한 수의 서버가 있기 때문에 이것을 전부 1대의 DNS 서버에 등록하는 것은 불가능합니다. 도메인을 . 으로 분리하여 계층화된 도메인 정보를 DNS 서버에 정보를 분산시켜 다수의 DNS 서버에 등록합니다.
IP주소를 OS가 알고 있기 때문에 DNS 요청을 포함한 모든 요청은 OS에 의뢰해서 진행합니다.
소켓 이하는 커널 공간에서 처리
소켓 - http 요청 통로
커널에 TCP/IP 통신을 위한 회선을 요청합니다. 요청받은 커널은 소켓을 만들어줍니다. IP정보와 포트번호 정보를 시스템 콜 경유로 커널에 전달하면 접속 대상 서버와의 연결이 생성됩니다.
TCP/IP 계층을 통해 전달
tcp는 전송을 제어하는 프로토콜로 어플리케이션이 보낸 데이터를 그 형태 그대로 상대방에게 확실하게 전달해야 합니다.
tcp가 담당하는 것은 서버가 송신할 때와 서버가 수신한 후 어플리케이션에 전달할 경우로 상대 서버까지 전송하는 부분은 하위 계층인 IP에 모두 위임합니다.
하지만 IP에는 데이터가 상대방에게 확실하게 전달 됐는지 확인 기능이나 도착 순서를 확인하는 기능이 없기 때문에 tcp가 있어야합니다.
데이터는 소켓 버퍼라는 메모리 영역에서 처리가 되고 tcp는 데이터를 세그먼트 단위로 관리하며 포트 번호를 포함해서 많은 정보를 가지고 있습니다.

위와 같은 형태로 만들어집니다.
그 후에 상대 서버에 데이터가 도착하지만 어떤 어플리케이션인지 알 수 없기 때문에 tcp 세그먼트의 포트 번호를 확인해서 전달
TCP는 three-way handshake를 통해 서버와의 연결
위 과정에서 tcp는 three way handshake를 통해 SYN ACK 비트를 주고 받으며 각 단말이 통신이 가능한 상태인지 확인합니다.

- 처음에 SYN 비트를 1로 만들어 전송
- tcp 헤더를 받은 서버는 포트 번호에 해당하는 소켓을 찾고 필요한 정보를 기록해서 접속 요청을 보냅니다. 서버가 수락하면 SYN(1) ACK(1) 를 만들어서 재선송을 합니다.
- SYN의 비트가 1이면 접속 성공으로 소켓의 서버 IP 주소나 포트 번호등과 함께 소켓에 접속 완료를 나타내는 제어 정보를 줍니다.
- 클라이언트는 패킷을 받으면 ACK 비트를 1로 만드는 TCP 헤더를 반송합니다.
IP계층을 통해 전달
IP의 역할은 지정한 대상 서버까지 전달받은 데이터를 전해주는 것입니다.
IP계층에서는 최종 목적지가 적힌 IP 헤더를 TCP 세그먼트에 추가해서 IP 패킷을 생성합니다. 이때 헤더에는 IP주소 외에 데이터 길이, 프로토콜 종류, 헤더 체크섬 등이 기록됩니다.

하지만 대상 서버는 항상 같은 네트워크 내에 있는 것이 아닙니다. 이 경우는 최종 목적지에 도착할 때까지 목적지를 알고 있는 라우터에 전송을 요청합니다.
IP 패킷을 받은 라우터는 해당 IP 패킷의 헤더에서 목적지를 확인해서 어디로 보내야 할지를 확인합니다.
데이터 링크를 통해 전달
링크 계층의 대표적인 프로토콜은 이더넷입니다.
링크 계층의 역할은 동일 네트워크 내의 네트워크 장비까지 전달받은 데이터를 운반합니다. 이 때 사용되는 주소가 MAC 주소입니다.
MAC 주소는 네트워크 인터페이스(LAN 카드)의 고유한 번호입니다.

MAC 주소에는 ARP(IP 주소를 기반으로 MAC 주소를 알아오는 역할) 테이블이 있습니다.
LAN 어댑터를 통해 바이너리 데이터를 전기신호로 바꾼다
프리앰블 비트, 패킷 오류 검출을 위한 FCS 비트 등 데이터를 추가하여 이진 데이터를 전기신호로 바꿉니다. LAN 어뎁터가 없이 와이파이, 핸드폰 데이터를 통해서도 사용 가능
와이파이: ip 주소 하나를 여러 대의 컴퓨터가 공유해서 인터넷에 접속할 수 있도록 하는 기기
스마트폰 데이터: 가장 가까운 기지국으로 전기 신호를 보내고, 기지국은 초고속 유선망과 연결
원격지의 MAC 주소로 전기 신호를 송출
전기 신호를 LAN 케이블을 통해 송출합니다. 데이터가 집 밖으로 나가는 순간입니다. 이때 원격지가 대역폭이 다른 외부 네트워크라면 패킷은 네트워크의 라우터로, 대역폭이 같은 내부 네트워크라면 해당 원격지로 전송됩니다.
스위치들을 모아 네트워크를 만들 수 있습니다. 스위치는 패킷의 맨 끝의 FCS를 대조하여 패킷 오류의 유무를 검사하기도 하고, 맥 주소 테이블을 통해 해당 스위치에 붙은 단말이 패킷의 목적지인지 검사합니다.
스위치는 연결된 단말들의 모든 MAC 주소를 알고 있어 원래 브로드캐스팅이라 이론적으로는 모든 단말에 닿아야 하는 ARP 요청 같은 것들도 스위치에서 알아서 걸러줍니다.
패킷의 목적지가 외부 네트워크면 네트워크의 라우터에 패킷이 도달
라우터에 도착한 패킷은 연결된 포트를 통해 다른 네트워크에 존재하는 원격지 MAC 주소를 알아내기 위해 ARP를 원격지에 요청하고 라우팅 테이블을 뒤져서 패킷을 중개하기 위한 경로를 탐색하고 전기 신호를 송신합니다.

인터넷 내부에서의 패킷 흐름
인터넷은 다수의 네트워크가 서로 접속한 것
여러 프로바이더의 여러 라우팅 장비들을 거치면서 최종적으로 목적지 서버가 포함된 네트워크의 라우터를 거쳐 해당 목적지 웹 서버의 단말로 쪼개진 패킷들이 도착합니다.
통신사들의 여러 프로바이더들을 거치면서 전기 신호는 해저 케이블을 통해 바다를 건너기도 하고, 지구를 한 바퀴 이상 돌기도 한다고 합니다.
웹 서버로 전기 신호가 도착한 이후의 동작
전기신호를 받은 웹 서버의 LAN 어댑터가 전기 신호를 이진 데이터로 바꿉니다. 네트워크 인터페이스에서 수신된 패킷의 MAC 주소를 비교하고 FCS로 패킷 훼손이 없는지 판단하여 올바른 패킷일 경우 운영체제단의 프로토콜 스택으로 올려보냅니다.
프로토콜 스택의 IP 담당 부분에서는 IP 헤더를 바탕으로 잘려서 온 패킷을 다시 리어셈블링하고 IP주소가 제대로 된게 맞는지 판단한 후 문제가 없으면 TCP 담당 부분으로 전달합니다. 이때 패킷 IP 헤더의 플래그, 오프셋 항목을 참조합니다.
TCP 담당 부분은 TCP헤더를 토대로 데이터가 잘려있는 패킷들을 다시 완성된 데이터로 만들고 해당 패킷을 잘 받았다면 클라이언트에 수신 확인 응답용 ACK 번호를 반송합니다. TCP 헤더의 시퀀스 번호를 참조합니다.
완성된 데이터를 만들었으면 제어 정보와 포트 번호를 토대로 TCP Handshake를 할 때 만들어놓은 적합한 소켓을 찾습니다.완성된 데이터를 소켓에 기록해 애플리케이션의 프로세스에 건내줍니다.
이 과정이 네트워크 계층을 올라가면서 전기 신호를 바탕으로 조각난 패킷과 헤더 정보를 바탕으로 클라이언트에서 발송한 데이터를 재조립하는 디캡슐레이션 동작입니다.
어플리케이션의 응답
요청 url을 실제 서버의 파일 시스템에서의 url로 바꿔 해당되는 html 자원을 찾아 바디에 넣은 후 헤더와 함께 전달.
응답 메시지를 받은 클라이언트 브라우저의 동작
클라이언트의 브라우저는 HTTP 메시지의 content-type 헤더를 보고 응답 데이터가 html임을 알아냅니다. 이를 바탕으로 브라우저가 화면 표시 동작을 실행합니다.
브라우저는 HTML을 파싱하여 Critical Rendering Path를 거쳐 해석된 html을 화면에 띄우고, 파싱하다가 script나 link태그를 만나면 렌더링을 중단하고 JS, CSS등의 자원 역시 위에서 설명한 똑같은 과정을 거쳐 서버에 요청합니다.
HTML 이외의 자원들을 위와 똑같은 과정을 거쳐서 서버에서 받아 역시 또 critical rendering path를 거쳐 CSS를 적용하고 JS를 해석하여 실행시켜 완성된 웹 페이지를 브라우저 위에 띄웁니다.
요청이 종료되었다면 4-Way-Handshake를 통해 접속을 끊고 소켓을 말소한다.
데이터 송수신 과정이 끝났다면 접속을 끊기 위해 4-way-handshake를 실시합니다.
- TCP 헤더의 FIN 비트에 1을 설정해 연결이 끝났음을 클라이언트에게 알림
- FIN 비트를 받아 서버측이 소켓 연결을 해제하고 있음을 알고 ACK 번호를 다시 서버측에 반송
- 클라이언트는 서버에서 보낸 데이터를 모두 수신완료했다는 사실을 알리고 데이터 송수신 동작 정리
- 클라이언트 측의 프로토콜 스택이 FIN 1 TCP 헤더를 만들어 서버에 송신한 후 서버에서 ACK가 돌아오면 서버와의 접속이 종료 → 소켓 말소