Today I Learned_220816
HTTP
모든 것이 HTTP 기반으로 동작함. 앱/서버 통신, 서버/서버 통신도 HTTP 프로토콜 위에서 진행
웹 기술, 웹 프레임워크 -> 모두 HTTP 기반으로 구현이 되어 있음
HTTP 전체 흐름
HTTP : TCP/IP, UDP 기반으로 동작하기에 인터넷 네트워크를 알아야 한다.
인터넷 네트워크
- 인터넷 통신
- IP(Internet Protocol) : 복잡한 인터넷 통신 망에서 메시지를 보내기 위한 방식
- TCP, UDP : IP의 보완책
- PORT : 같은 IP 안에서 통신할 애플리케이션 구분
- DNS : 외우기 쉬운 IP를 쉽게 찾기 위한 수단
인터넷 통신
인터넷에서 컴퓨터 둘이 통신하는 방법
메시지를 보내야 하는데 컴퓨터 둘이 너무 멀리 있다면? -> 인터넷 망을 통해 메시지를 보내야 함.
인터넷은 단순하지 않다. 광케이블로 가거나, 위성을 통해 내려가는 등 수많은 중간 노드 서버를 거쳐서 메시지가 안전하게 넘어간다.
어떤 규칙으로 넘어가서 목적지까지 도착하는지?
IP(Internet Protocol)
인터넷 프로토콜, IP Protocol이라고 함
클라이언트가 IP 주소를 부여받음 - 서버의 IP 주소가 있어야 함
IP의 역할
- 지정한 IP Address에 데이터 전달할 수 있도록 정해놓은 규칙
- 패킷 단위로 데이터 전달
IP 패킷 : 출발지 IP, 목적지 IP, 기타 -> IP 패킷을 만들어서 인터넷 망에 패킷을 던진다 -> IP 프로토콜에 의해 서로의 노드끼리 던지면서 목적지를 찾아간다.
메시지를 받았으면 OK 메시지를 IP 패킷을 만들어서 다시 던진다.
요청할 때랑 응답할 때랑 서로 다른 곳으로 전달이 될 수 있다.
IP 프로토콜의 한계
- 비연결성
- 패킷을 받을 대상이 없거나 서비스 불능 상태여도 패킷 전송 (상대 PC가 꺼져있는지 켜져있는지 모르고 일단 전송한다)
- 대상 서버가 패킷을 받을 수 있는 상태인지 모른다.
- 비신뢰성
- 패킷이 중간에 사라지거나 패킷이 순서대로 오는 것을 보장하지 않음.
- 중간의 노드 서버가 문제가 생긴다 -> 패킷이 유실되는 것을 모른다.
- 패킷의 용량이 클 때 (1500byte가 넘으면 보통 끊어서 보낸다) - 패킷들이 중간에 다른 노드를 거쳐갈 수 있음 - 순서가 다르게 도착할 수 있다.
- 프로그램 구분
- 한 PC에서 여러 애플리케이션이 같은 IP를 쓰고 있는데 어떻게 구분되지? - 구분이 안 됨
이러한 문제는 IP 프로토콜만으로 해결할 수 없음 -> TCP를 활용해야 한다.
TCP, UDP
IP 프로토콜에서 발생한 문제들을 TCP 프로토콜에서 해결해 줌. UDP 자체가 해결해 주지는 않지만 그래도 도움은 준다…
인터넷 프로토콜 스택의 4계층
- 애플리케이션 계층(HTTP, FTP)
- 전송 계층(TCP, UDP)
- 인터넷 계층(IP)
- 네트워크 인터페이스 계층(랜카드, 랜 드라이버 등등)
이해하기 쉽게 그룹화한 계층
- 애플리케이션 : 웹 브라우저, 네트워크 게임, 채팅 프로그램, 소켓 라이브러리
- OS : TCP, UDP, IP(Internet Protocol)
- 네트워크 인터페이스 : 랜 드라이버, 랜 장비
메시지가 전송되는 과정
- 프로그램이 메시지 생성
- 소켓 라이브러리를 통해 OS 계층으로 메시지 전달
- OS 계층에서 TCP 정보를 씌움
- IP계층에서 TCP 정보 밖에 IP 관련 데이터 씌운다 - IP 패킷 생성
- 네트워크 랜카드 인터페이스를 통해 나갈 때, 이더넷 프레임이 포함되어서 나간다.
이더넷 프레임 : 맥주소 등 물리적인 정보가 포함되어 있다.
IP 패킷 정보
출발지 IP, 목적지 IP, 기타
패킷 : package + bucket의 합성어
TCP/IP 패킷 정보
IP 패킷 안에 TCP 관련 정보가 들어간다.
출발지 PORT, 목적지 PORT, 전송 제어, 순서, 검증 정보 등… -> IP만으로 해결이 되지 않았던 문제들 해결 가능
TCP(Transaction Control Protocol) 특징
전송을 어떻게 할 지 제어하는 프로토콜
- 연결지향 - TCP 3 way handshake (가상 연결) : 쟤랑 나랑 연결이 되었는지 안 되었는지 메시지를 보낸다.
- 데이터 전달 보증 : 내가 보낸 패킷이 유실되었는지 확인
-
순서 보장
- 신뢰할 수 있는 프로토콜
- 현재는 대부분 애플리케이션에서 TCP 사용
TCP 3 way handshake
진짜로 물리적 연결이 수립되는 것이 아니라 가상 연결에 해당. 논리적으로 연결이 되었다고 생각하는 것
- 클라이언트에서 서버로 SYN 보냄
- 서버에서 SYN + ACK 메시지를 클라이언트에 보냄
- 클라이언트가 서버로 ACK 보냄
- 3 way handshake를 통해 연결이 수립되면 데이터를 보낸다.
데이터 전달 보증
클라이언트가 데이터를 전송하면, 서버가 데이터를 잘 받았다는 응답을 보내주는 것
-> 메시지 전달 여부를 확인할 수 있다.
순서 보장
- 클라이언트가 서버로 패킷1, 패킷2, 패킷3 순서대로 전송
- 서버에 패킷1, 패킷3, 패킷2 순서대로 도착
- 서버가 클라이언트에게 뒤에꺼 다 버리고 패킷2부터 다시 보내기를 요청
서버 자체의 내부적인 최적화가 일어날 수는 있지만,
그렇다면 서버가 패킷의 순서가 뒤바뀌었는지는 어떻게 아는가? - TCP header의 sequence number에서 확인 가능.
UDP(User Datagram Protocol) 특징
TCP와 같은 계층, IP 계층 바로 위에 있는 프로토콜
사용자 데이터그램 프로토콜
- 기능이 거의 없는 하얀 도화지와 유사하다.
- 3 way handshaking이 없다.
- 데이터 전달을 보증하지 않음
- 순서 보장하지 않음
- IP 프로토콜과 거의 유사하나, PORT와 checksum이 추가된 형태라고 보면 된다.
- 애플리케이션에서 추가 작업이 필요하다.
PORT : 한 IP에서 어플리케이션을 구분하기 위한 용도
TCP : 헤더에 이것저것 붙어서 데이터의 양이 많고 느리다. 거의 90% 이상을 점유함
UDP : handshaking이 없기에 최적화를 한다면 여기서 최적화를 할 수 있겠다.
PORT
패킷을 받거나 보낼 때 같은 IP인데 어느 응용프로그램에서 사용하는지 모른다.
TCP/IP 패킷 정보에 출발지 PORT, 목적지 PORT 가 있다.
IP는 서버를 찾는 것, PORT는 서버 내 어플리케이션을 구분하는 것이라고 생각하면 된다.
PORT는 같은 IP내에서 프로세스를 구분하는 수단
한 아파트(IP, 서버, PC)에서 동과 호수(포트)를 구분하는 수단
- 0 ~ 65535 : 할당 가능
- 0 ~ 1023 : Well-known port, 사용하지 않는 것이 좋다.
- FTP : 20, 21
- telnet : 23
- http : 80
- https : 443
DNS(Domain Name System)
IP주소는 기억하기 어려우며, IP는 변경이 될 수 있다 -> 그러면 접근이 불가능함 ㅠㅠ
DNS는 전화번호부와 같은 서버로, 도메인 명을 IP주소로 변환해 준다.
DNS가 사용되는 flow
- 도메인 명을 주소창에 입력
- DNS가 IP주소를 응답으로 준다.
- 해당 IP주소를 변경
URI와 웹 브라우저 요청 흐름
- URI
- 웹 브라우저 요청 흐름
URI(Uniform Reesource Identifier)
리소스를 식별하는 통합된 방법
URI는 로케이터(locator), 이름(name) 또는 둘 다 추가로 분류될 수 있다.
- URI(Resource Identifier) : 리소스를 식별한다. 자원 자체를 식별하는 방법
- URL(Resource Locator) : 리소스의 위치를 지정. 웹 브라우저에서 적는 것. URL 주소는 리소스가 이 위치에 있을 것이다.
- URN(Reource Name) : 리소스의 이름. 이름을 부여해버리는 것.
일반적으로 URL을 주로 사용하지, URN은 잘 사용하지 않는다.
![URL and URN]](/assets/img/posts/2022_08-16-TIL_220816/Screen Shot 2022-08-16 at 10.20.01 PM.png)
rfc 표준 스펙에 정의되어 있음 : https://www.ietf.org/rfc/rfc3986.txt
URI의 뜻
- Uniform : 리소스를 식별하는 통일된 방식
- Resource : URI로 식별할 수 있는 모든 것(웹 브라우저에 있는 파일, 교통 정보 등 모든 정보)
- Identifier : 식별할 수 있다.
URL, URN
- URL : 리소스가 있는 위치를 지정
- URN : 리소스에 이름을 부여 -> 이것만으로 실제 리소스를 찾을 수 있는 방법이 보편화되지 않음
따라서 URI가 URL과 같은 의미로 사용되는 경우가 있음.
URL 문법
구조
scheme://[userinfo@]host[:port][/path][?query][#fragment]
예시
https://www.google.com/search?q=hello&hl=ko
- scheme : 프로토콜(https)
- 어떤 방식으로 자원에 접근할 것인가 하는 클라이언트와 서버간의 약속 규칙(ex. http, https, ftp 등등)
- http는 80, https는 443을 사용하므로, 이 둘을 사용할 경우 포트번호 생략이 가능
- [userinfo@] : 사용자 정보(예시에는 없음)
- 거의 사용하지 않음
- host : 호스트명(www.google.com)
- 보통 도메인명이나 IP주소를 직접 사용가능
- [:port] : 포트번호(443)
- 일반적으로 생략 가능함
- [/path] : 패스(/search)
- 리소스가 있는 경로
- 계층적 구조로 되어 있음
- [?query] : 쿼리 파라미터, 쿼리 스트링(q=hello&hl=ko)
- key=value 형태
- ?로 시작, &로 추가 가능
- 웹 서버에 제공하는 파라미터 정보.
- string 형으로 넘어온다. (숫자를 넣어도 문자로 넘어온다)
- fragment (예시에 없음)
- html 내부 북마크 등에 사용
- 서버에 전송하는 정보가 아님
웹 브라우저 요청 흐름
인터넷 브라우저에 https://www.google.com/search?q=hello&hl=ko 를 입력했을때의 흐름
- host(www.google.com)를 가지고 DNS를 조회 -> IP주소 획득
- https이므로 443 포트정보 획득
- HTTP 요청 메시지 생성(GET)
GET /search?q=hello&hl=ko HTTP/1.1
Host: www.google.com
- 앞에 GET 있고, path부터 쿼리 정보가 들어간다.
- 뒤에 HTTP 버전 정보 포함
- 호스트 정보 포함
HTTP 메시지 전송
- 웹 브라우저가 HTTP 메시지 생성
- 소켓 라이브러리를 통해 TCP/IP 계층에 메시지 전달
- IP와 포트 정보를 가지고 3-way handshaking을 통해 연결
- 데이터 전달
- TCP/IP 패킷 생성(IP, PORT 정보 포함), HTTP 메시지 포함(GET /search…..)
- 요청 패킷을 전달
- 목적지에 도착하면 패킷을 깐 다음에 HTTP 메시지를 해석한다.
- 그 다음 서버에서 HTTP 응답 메시지를 생성한다.
HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Content-Length: 3423
<html>
<body>...</body>
</html>
- 받은 HTTP 메시지를 열어서 웹 브라우저가 HTML을 렌더링