컴퓨터를 공부하고자 마음먹은지 N일차
[239일차]네트워크 전반과 HTTP를 개괄적으로 알아보자 본문
Reference
HTTP 완벽가이드
모든 개발자를 위한 HTTP 웹 기본 지식
How DNS works
시작하며
감사하게도 제가 근무하는 회사에서 HTTP에 대해 발표를 하게 될 기회를 갖게되어
좀 더 제대로 HTTP에 개한 개념을 정리하고자 이 글을 연재하게 되었습니다.
이 글은 대부분 HTTP 완벽가이드 라는 책을 바탕으로 정리된 글이며,
해당 서적의 챕터별로 포스팅이 나눠져서 업로드 됩니다.
또한 모든 개발자를 위한 HTTP 웹 기본 지식 강의도 많은 참고가 되었습니다.
기타 포스팅의 기반이된 강의나 자료는 포스팅의 최상단에 있는 항목인 Reference 항목에 있는 자료들을 추가했습니다.
이 글을 작성하는 저 뿐만 아니라 읽으시는 모두에게 쉬운 이해를 위해 다소 비유의 함정 이 있을 수 있습니다.
비개발자 분들도 읽을 수 있게 글을 쓰는것을 지향합니다.
모든 지적과 질문을 댓글을 통해 감사히 받겠습니다. 보시는 모두가 도움이 되기를 바라며 글을 시작하겠습니다.
인터넷 네트워크
웹과 HTTP는 인터넷 네트워크망 기반으로 동작한다.
인터넷이 연결되어 있어야 브라우저에서 특정 사이트에 접속할 수 있다.
그렇기 때문에 네트워크에 대한 기본적인 이해가 뒷받침 되면 훨씬 머리속에 잘 그려질것이다.
인터넷 네트워크를 전반적으로 가볍게 알아보고, HTTP의 커넥션에 관해서는 추후 좀더 자세히 다뤄보겠다.
인터넷 통신
인터넷에서 컴퓨터와 컴퓨터 끼리는 어떻게 통신을 할까?
바로 옆에 있는 컴퓨터라면 종이컵 전화기처럼 케이블을 직접 연결해서 통신을 하면 될것이다.
하지만 원거리라면 반드시 인터넷 망을 사용하게 된다.
인터넷은 저렇게 간단한 아이콘으로 표시되곤 하는데,
사실 굉장히 많은 노드들이 엮여있는 복잡한 구조로 되어있다.
노드는 네트워크에 연결되어 있는 1개 1개의 기계라고 생각하면 된다.
수많은 노드들로 얽혀있는데 어떻게 전달해야할 데이터를 정확하게 보내줄 수 있을까?
IP에 대해서 알아보자.
IP(인터넷 프로토콜)
우선 프로토콜이라는 개념을 알아야 하는데, 우체국을 통해 편지를 보낸다고 가정을 해보자.
편지를 붙이기 위해 편지 봉투가 필요할 것이며, 편지가 도착할 주소가 필요하고, 그리고 편지의 내용이 필요할 것이다.
봉투와 우표 그리고 편지를 받는 주소가 필요하며 우체통이나 우체국을 통해 보내는것 처럼
컴퓨터 끼리도 원활한 통신을 위해 양식과 규칙의 체계가 정해져 있는데, 이것을 프로토콜이라고 한다.
즉 인터넷에서도 원활한 통신을 위해서 통일된 규약이 있는데, 이것이 IP, 인터넷 프로토콜이라고 한다.
IP 주소라고 들어봤는가? 인터넷을 통해 통신을 하는 기기들은 IP의 주소를 부여받게 된다.
서버에게 HI라는 메세지를 보내는데, 보내는 컴퓨터는 메세지를 200.200.200.2이라는 목적지 주소를 입력하면,
각 노드는 200.200.200.2 로 갈수있는 노드를 찾아서 전달해준다.
받는 서버는 보냈던 컴퓨터인 100.100.100.1이라는 주소를 찾아서 답장을 보낼것이다.
'나'라는 컴퓨터가 서버에 메세지를 보낸과정과 똑같이 HI라는 메세지의 출발지를 확인하고 답장을 해준다.
따라서 IP의 역할은 지정된 IP주소에 데이터를 전달해주는 역할을 한다. 그러나 IP는 'HI'라는 데이터만 단독적으로 보낼순 없다.
IP 패킷
패킷은 택배라고 생각하면된다.
우체국에서 택배를 보내본적이 있는가? 용량마다 권장하는 박스의 크기가 있고, 그 박스에 내용물을 감싼 후,
박스에는 우편물 스티커를 붙여야 된다. 그리고 그 우편물 스티커에는 보내는 사람의 주소가 있어야하고, 받는 주소가 있어야한다.
IP패킷또한 마찬가지인데, 전송할 데이터를 그냥보내는것이 아닌 IP패킷으로 한번 포장을 한다.
패킷에는 출발지 IP와 목적지 IP와 그외 기타 정보가 입력되어있다. 따라서 데이터를 보낼때는
패킷이라는 통신 단위로 데이터를 전달한다.
그러나 IP로만 데이터를 주고받기에는 다소 한계가 있다.
비연결성
IP 프로토콜은 서버가 살아있는지 여부와 상관없이 패킷에 데이터를 담아 전송한다.
비유가 많이 이상하지만, 누군가가 엄청 무거운 물건을 한 건물에 두라고 시켜서
힘들게 들고갔더니 건물이 철거되고 없는 상황을 상상해보면 된다.
비신뢰성 - 패킷이 유실될 수 있다.
인터넷은 결국 여러 서버를 거쳐서 통신을 할 수 밖에 없다.
메세지가 이동하는 중 갑자기 가는 길목의 해저케이블이 갑자기 상어에게 물어뜯기면 전송하던 패킷은 그대로 유실된다.
비신뢰성 - 순서를 보장하지 않는다
보내려는 데이터의 크기가 큰 경우가 있다.
휴대폰 번호가 하나에 4500바이트라고 예시를 들어보자.(그런 경우는 없다 예시일 뿐)
패킷은 전송의 부하를 줄이기 위해서 보통 1500바이트 단위로 나누어진다.
010과 3333 그리고 7777 각각 1500바이트라면 각각 패킷으로 나눠서 전송을 하게된다.
각각 패킷을 보냈을 때, 드라마틱하게 순서대로 도착하면 좋겠지만,
아쉽게도 도착하는 순서가 달라지는 경우도 있다. 각 패킷마다 상황에 따라 다른 노드를 경유할 수 있기 때문이다.
IP 프로토콜에는 아무런 순서정보가 없기 때문에 서버는 3333 010 7777 이라는 번호를 전달받을 가능성이 있다.
각각 치명적이지만 이러한것들을 해결해주는것이 바로 TCP 프로토콜이다.
인터넷 프로토콜 스택의 4계층
TCP를 알아보기 전에 인터넷은 어떤 프로토콜들을 사용하는지 알아보자.
애플리케이션 계층은 TCP와 UDP기반으로 작동하는 프로토콜들이다.
그리고 전송을 도와주는 계층인 전송계층이 있고, 위에서 설명한 IP가 있는 인터넷 계층이 있다.
마지막으로 네트워크 인터페이스 계층이 있는데, LAN이라던지 WIFI를 떠올리면 되겠다.
각 계층이 따로따로 움직이는것이 아닌, 애플리케이션의 프로토콜을 전송계층의 프로토콜에 담고 또 그것을
인터넷계층에 담고, 네트워크 인터페이스 계층을 통해 인터넷망으로 뻗쳐나간다고 생각하면 된다.
위와 같이 브라우저를 통해 'HI'라는 메세지를 전달한다고 하면, 어플리케이션계층인 HTTP에서 메시지를 만들어,
운영체제에 전달하고, 운영체제는 전송계층에서 메시지를 TCP 패킷으로 감싸서 인터넷계층에 전달한다.
인터넷 계층에서 IP패킷이 TCP패킷을 감싸서 네트워크 인터페이스 계층으로 넘어와, 최종적으로 이더넷프레임으로 감싸서,
인터넷 망으로 전달한다. 각 계층마다 포장된 박스를 또한번 포장한다고 생각하면 된다.
TCP(전송 제어 프로토콜)
TCP는 이름 그대로 전송을 어떻게 처리할지 제어를 하는 프로토콜이다.
TCP는 어떤 특징을 가지기에 IP를 보완해줄까?
TCP 패킷
4계층에서 언급한것처럼 TCP또한 패킷을 통해 전송할 데이터를 감싼다.
다만 IP패킷과 차이가 있는것은 출발지 PORT와 목적지 PORT에 대해서 기입되어 있는것과,
순서정보가 적혀있는것이 차이가 있다.
연결지향 - TCP 3 way handshake (가상 연결)
TCP는 약속된 세가지 동작을 통해 연결을 보장한다.
즉 연결을 먼저 해보고 데이터를 전송한다는 것이다.
이 동작을 TCP 3 way handshake 라고 하는데 이것에 대해서는 따로 포스팅을 했었다.
이 글을 통해 학습을 한다면 한번 읽어보길 권장한다.
TCP 3 way handshake
데이터 전달 보증
TCP는 데이터가 잘 전달됐는지 보증을 해준다.
그림과 같이 데이터를 전달을 했을 때, TCP가 붙게되면 서버에서 데이터를 잘 받았다고 응답을 준다.
만약 응답을 받지 못했다면, 데이터의 전달에 문제가 있음을 인지하게 된다.
순서 보장
TCP는 패킷에 대해 설명했던것처럼 패킷에 순서정보를 담는다. 그 순서정보에 따라 서버는 데이터를 조합하게되는데,
이 패킷이 순서대로 안왔을 때 서버에서 어떤 일이 일어나는지 그림으로 알아보자.
그림과 같이 서버에서 받은 순서정보와 다르게 패킷이 도착했다면, 순서가 맞지않는 패킷부터 다시보내달라고 요청한다.
물론 자체적으로 최적화가 있을 수 있겠지만, 기본적으로는 순서가 맞지않는다면 다시 보내달라고 요청한다.
UDP(사용자 데이터그램 프로토콜)
UDP또한 TCP와 마찬가지로 전송계층에 해당하는 프로토콜이다.
다만 UDP는 TCP처럼 3 way handshaking 도 일어나지 않고, 데이터가 전달됐음을 보증하지도 않는다.
순서도 보장하지않는다. IP와 거의 유사해보이지만 차이점은 TCP처럼 출발지 PORT와 목적지 PORT가 패킷에 있다는 점이다.
그렇다면 UDP는 사실 장점이 거의 없어보이지만 TCP에는 있고 UDP에는 없는것이 때로는 장점이 된다.
언급했던 3 way handshaking이 일어나지 않기 때문에 단순하고, 빠르게 데이터를 전달할 수 있다.
또한, TCP에서는 이미 정해진 체계와 규칙이 있는 반면 UDP는 PORT와 같은 가벼운 정보같은 것들만 있기 때문에
하얀 도화지에 비유를 한다. 필요에 따라서 필요한 부분을 애플리케이션계층에서 얼마든지 추가작업을 할 수 있다.
최근 HTTP의 새로운 스펙(HTTP3.0)이 공개하면서 TCP의 연결 과정을 생략해보려는 시도가 있다.
하지만 아직은 실험적인 단계이다.
PORT
포트는 '항구' 라는 의미를 가지고 있다.
IP패킷에 감싸진 TCP패킷을 다시한번 살펴보자.
TCP패킷에는 패킷이 출발하는 포트와 패킷의 목적지가 적혀있다.
만약 우리가 하나의 컴퓨터로 게임도하고 웹브라우저를 통해 검색도하고 디스코드로 음성통화까지 한다고 생각해보자.
하나의 컴퓨터는 하나의 IP만 가지는데 게임서버에서 오는 데이터와, 웹에서 오는 데이터와,
디스코드서버에서 오는 데이터를 구분할 필요가 있다. 그래서 우리의 컴퓨터는 포트라는 것을 활용한다.
하나의 컴퓨터에 들어오는 데이터라고 해도, 항구를 나눠서 어디에 활용되는 데이터인지 구분을 해준다.
통상적으로 웹브라우저는 http통신을 보낼때 목적지 포트를 80으로 약속해두고 있다.
DNS(도메인 네임 시스템)
보통은 몇몇 친한 친구들 빼고는 친구들의 전화번호를 외우고 다니지는 않을것이다.
앞에는 010으로 통일한다 쳐도, 뒤의 숫자 8자리는 외우기가 사실상 쉽지가 않다.
그래서 전화번호부에 이름으로 저장하는게 흔한 방식이다.
IP는 어떨까? 124.231.115.2 라는 서버가 있다. 이 서버의 IP를 한번만 보고는 도저히 외우기 힘들것이다.
겨우 외웠지만 그 서버가 대대적인 교체작업에 들어가서 IP가 바뀌는 경우가 생길 경우, 해당하는 IP를 힘들게 또 외워야한다.
그래서 인터넷은 DNS라는 전화번호부와 유사한 서버를 제공한다.
도메인은 개개인이 구매후 자신의 서버에 원한다면 등록이 가능하다. naver.com이라는 사이트에 접속을 할 때
어떤 절차가 이루어지는지 보자.
위 그림은 naver.com에 처음 접속을 했을때 상황이다. naver.com 이라는 정보만으로는 데이터를 얻을 수 없기에,
DNS서버에 naver.com의 IP주소를 알려달라고 요청한다. 획득한 IP를 통해 네이버에 접속한다.
물론 우리의 브라우저는 똑똑해서 한번 접속했던 도메인에는 IP주소를 우리의 컴퓨터에 저장해준다.
HTTP 개관
눈치가 빠르다면 TCP패킷안의 내용물이 뭐가 들어갈지 예상이갈것이다.
바로 애플리케이션 계층의 프로토콜이 들어가게 되는데, 이번에 알아볼 HTTP역시 TCP패킷의 내용물로 들어간다.
지금 시대는 모든 것을 HTTP로 전송한다. HTML, 이미지, 영상, 파일뿐만 아니라
앱과 서버가 통신할 때, 또 서버와 서버가 통신할 때도 대부분 HTTP를 사용한다.
즉 웹으로 통신하는 거의 모든것들이 HTTP기반이다.
이번 포스팅에선 이 HTTP가 뭔지, HTTP는 어떤 방식으로 소통을 하는지,
그리고 HTTP에서 주로 사용되는 개념은 어떤게 있는지 개괄적으로 알아보자.
HTTP: 인터넷의 멀티미디어 배달부
HTTP는 HyperText Transfer Protocol의 약자이다.
웹에서 클라이언트와 서버 사이에 이루어지는 요청과 응답의 양식과 규칙의 체계이다.
지금 이 글을 보고 잇는 동안에도, 본문의 내용뿐만 아니라 블로그를 구성하고있는 뼈대 또한
HTTP를 통해 당신의 브라우저에 도착했을것이며, 수 많은 이미지, HTML페이지,
텍스트파일, 동영상, 음성파일 등이 인터넷을 항해 중 이다.
이 HTTP는 데이터가 지구 반대편에서 오더라도 TCP를 활용하기 때문에 정보가 손상되거나 순서가 섞이지 않음을 보장한다.
웹 클라이언트와 서버
웹 컨텐츠는 웹 서버에 존재한다. 웹 서버는 HTTP로 의사소통하기 때문에
보통 HTTP 서버라고 불린다. 이 서버는 인터넷의 데이터를 저장하고,
HTTP 클라이언트가 요청한 데이터를 제공한다.
위 그림과 같이 클라이언트는 필요한 데이터가 있을 때 서버에게 요청을 하고,
서버는 요청받은 내용에 따라 필요한 데이터를 실어서 응답을 준다.
물론 해당하는 데이터를 찾지 못하거나 요청이 올바르지 않다면 그에 따라 응답을 준다.
리소스
리소스는 웹 컨텐츠를 이루는 자원이다. 이미지, 동영상, 텍스트파일 등 모든게 리소스에 해당한다.
웹 클라이언트와 서버 목차에 사용된 그림에서, index.html문서를 원한다고 클라이언트가 요청을 하고있다.
요청받아서 응답과 함께 주는 html파일 또한 리소스에 해당한다.
우리가 사용하는 웹앱의 화면들은 서버에서 응답받은 리소스들로 구성되어 있다.
미디어 타입
인터넷은 수많은 종류의 데이터 타입(jpg, txt, wmv등)을 가진 리소스를 다룬다.
이것들을 구분하기 위해서 HTTP는 MIME(Multipurpose Internet Mail Extensions)타입 이라는
데이터 포맷을 가진다. 이것은 원래 각기 다른 전자메일 시스템 사이에서 메세지가 오갈 때 겪는 문제점을 해결하기
위해 설계 되었지만, 이메일에서도 워낙 잘 작동했기 때문에 HTTP에서도 이러한 방식을 채택하여 컨텐츠를 구분한다.
유튜브에서 동영상을 불러올 때 http메세지를 가져왔다.
위 메세지와 같이 어떤 데이터타입인지 라벨을 붙여주고, 응답을 받은 브라우저는 다룰 수 있는 데이터인지 확인한다.
- HTML로 작성된 텍스트 문서는 text/html 라벨이 붙는다.
- plain ASCII 텍스트 문서는 text/plain 라벨이 붙는다.
- JPEG 이미지는 image/jpeg가 붙는다.
- JSON은 application/json이 붙는다.
이 외에도 수 많은 MIME타입이 있다.
MDN-MIME타입
URI (Uniform Resource Identifier)
서버에 있는 리소스는 각자 이름을 가지고있다.
클라이언트는 필요한 리소스를 지목해서 요청을 해야하는데, 지목할 리소스는 각자 식별할 수 있는 주소나 이름이 있어야 한다.
예를 들어 아이폰12를 택배로 주문을 시켰는데 아이패드가 택배로 오면 안되기 때문이다.(ㄱㅇㄷ)
리소스를 구분하는 방법에는 아래 그림과 같이 크게 두가지로 분류된다.
URL (Uniform Resource Locator)
가장 널리쓰이고 흔한 행태이며 서버의 한 리소스에 대한 구체적인 위치를 서술한다.
URL은 리소스가 정확히 어디에 있고 어떻게 접근할 수 있는지 구체적으로 알려준다.
오늘날 대부분의 URI는 URL이다.
네이버에서 webtoon에 위치해 있는 titleId가 602910을 가진 리소스이다.
titleId만 살짝 바꾸면, 다른 웹툰을 가져오거나 유효하지 않은 웹툰이라고 할것이다.
위와 같이 어떻게 리소스의 정확한 위치와 접근방법을 표현하는지 상용되는 URL을 보면 알 수 있다.
URN (Uniform Resource Name)
또다른 구분 방식인 URN은 리소스의 위치에 영향을 받지 않는 고유한 이름이다.
이러한 독립적인 URN은 리소스를 다른 위치로 옮기더라도 문제없이 찾아낼 수 있다.
위 그림과 같이 URN또한 고유한 체계가 있다. 하지만 URN은 여전히 실험 중인 상태고,
아직 널리 채택되지 않았다. 그래서 통상적인 관래로 URI와 URL을 같은 의미로 주로 사용중이다.
트랜잭션
보통 트랜잭션이라고 하면 데이터베이스에서의 트랜잭션을 떠올리는데,
트랜잭션의 사전적 의미는 일련된 작업이라는 뜻이다.
HTTP에는 클라이언트가 서버에서 보내는 요청 명령과 서버에서 클라이언트에게 응답해주는 응답이 있는데,
HTTP트랜잭션은 이러한 하나의 특정 요청과 그 요청에 해당하는 하나의 응답을 묶어서 의미한다.
메서드
클라이언트는 단지 리소스를 불러오기만 하지는 않을것이다.
지금 이 글의 작성을 마치고 등록을 누르면 이 글에 해당하는 리소스들을 서버에 등록을 해야 할 것이고,
서버는 내가 올린 글을 저장을 할것이다.
그렇기에 단순히 리소스를 불러오는것과, 등록을 하는 행위는 구분되어져야 한다.
HTTP는 이러한 행위를 메서드를 통해 구분하고 있다.
상태코드
서버에서 응답하는 모든 HTTP 응답 메세지는 상태 코드와 함께 반환된다.
상태코드는 서버가 클라이언트에게 요청이 성공했는지 아니면 실패했는지 또는 추가적인 조치가 필요한지 알려준다.
아래 사진은 흔히 볼 수 있는 404 Not Found이다.
Not Found라는 메세지가 뜻하는 바와 같이 URL에 해당하는 리소스를 찾을 수 없을 때 응답하는 코드다.
정상적으로 접속이 되는 홈페이지로 들어가서 브라우저 개발자 콘솔을 (F12) 켜보자.
그리고 네트워크 탭을 열어보면, 200으로 된 응답들이 여러개 있을것이다.
페이지 하나를 로드하기위한 리소스들의 요청에대한 응답들이다.
위와같이 리소스에 대한 요청이 성공하면 200번대 코드를 보내준다.
각 응답 코드의 100의자리 수 마다 통용되는 의미가 있다.
지금은 개괄적으로만 이해를 하고 추후 좀 더 자세히 알아보자.
HTTP 메시지
HTTP 요청과 응답 메시지의 구조를 지금은 가볍게 들여다 보자. 추후에 더 자세히 다룰 예정이다.
HTTP 메시지는 단순 줄 단위의 문자열이다. 즉, 줄바꿈으로 내용을 구분하고있다.
당연히 아무렇게나 보내는것이 아닌 양식을 가지고 있다.
시작줄
HTTP 메시지의 첫 줄은 시작줄로, 요청이라면 행위를 나타내는 메서드로 시작하고,
응답이라면 요청에 대해서 어떤 결과가 일어났는지 상태코드와 함께 알려준다.
위 그림과 같은 경우에는 POST요청을 보냈지만 서버에서는 403코드를 보내며 접근을 제한하는 응답을 보냈다.
헤더
시작줄 바로 다음줄에는 0개 이상의 헤더 필드가 이어진다.
각 헤더 필드는 콜론(:)으로 구분되는 하나의 이름과 하나의 값으로 줄바꿈으로 구분한다.
다른 헤더를 추가할때 한줄을 더하는 식으로 이루어진다.
빈줄
헤더와 본문을 구분하기 위한 빈 줄이 있다.
메세지 가운데 빈줄이 있으면 빈 줄 상단에는 시작줄과 헤더가 있고,
하단에는 본문을 담고있다.
본문
빈 줄 다음에는 어떤 종류의 데이터든 들어갈 수 있는 메시지 본문이 필요에 따라 올 수 있다.
헤더와는 달리 지켜지는 양식이 없으며, 임이의 데이터를 포함할 수 있다(이미지, 오디오, 비디오 등).
물론 단순 텍스트도 포힘할 수 있다.
프로토콜 버전
대부분의 서버는 현재의 HTTP 버전인 1.1의 스펙을 사용중이다. 그러나 여전히 1.0스펙이 쓰이는곳이 간혹있다.
1.0과 1.1은 기존의 구조적 결함을 교정하고, 두드러진 성능 최적화, 잘못된 기능 제거에 집중했다.
그리고 1.1의 성능 문제를 개선하기 위해 2.0은 2015년에 공식적으로 발표가 되었고, 각종 해외사이트나,
우리나라 다수 커뮤니티 등에서 사용중이다. 적용된 사이트
웹의 구성요소
기본적인 요청과 응답을 담당하는 웹 애플리케이션(웹 브라우저와 웹 서버) 말고도 인터넷과 상호작용을 하는
애플리케이션은 많다. 각각 간략하게만 알아보고 추후에 더 자세히 다뤄보자.
프록시
프록시는 위 그림과 같이 서버와 클라이언트 사이에 위치하여, 클라이언트의 모든 HTTP요청을 받아서
서버에 사용자대신 전달한다. 주로 보안을 위해서 사용되고, 요청과 응답을 필터링하거나,
무엇인가를 다운받을 때, 바이러스를 미리 검출하고, 유해사이트를 차단하는데에도 사용된다.
캐시
캐시는 프록시와 비슷하게 서버와 클라이언트 사이에 위치한다.
다만, 자주 찾는 내용을 저장해놨다가 서버까지 가지않고 대신 전달 해주는 역할을 한다.
추후 캐싱 기술에 대해서는 더 자세하게 다뤄보도록 하자.
이 외에도 게이트웨이나 터널, 에이전트와 같은 애플리케이션이 있지만,
추후 다른 포스팅으로 자세하게 다뤄볼 예정이다.
다음 포스팅에서는 URL과 리소스에 대해서 좀 더 자세히 다뤄보자.
'🌏Network' 카테고리의 다른 글
[246일차]URL (1) | 2021.05.17 |
---|---|
[206일차]TCP 3-way Handshaking (0) | 2021.04.07 |
[191일차] RESTful API란? 그리고 장점까지 (0) | 2021.03.23 |