이 글은 인프런의 김영한 강사님의 http강의를 정리한 글이다
인터넷 상에서 컴퓨터 둘은 어떻게 통신할까?
복잡한 인터넷 망을 두고 클라이언트끼리 통신을 주고받을수 있는 이유
IP (인터넷 프로토콜)
IP주소 부여
우선적으로 보내고자하는 내 클라이언트가 IP주소를 부여받아야 하고, 받고자하는 상대방도 IP주소가 있어야한다
IP 역활
그러면 IP는 인터넷 프로토콜 역활을 수행하는데, 방금 지정한 IP주소(IP Address)의 메세지를 전달할 수 있도록 정해놓은 규칙을 수행
이때, 패킷(Packet)이라는 통신 단위로 데이터를 전달한다
IP 패킷 정보
IP 패킷은 규칙이 존재
클라이언트 패킷 전달
클라이언트 -> 인터넷 -> 서버
인터넷 망에 던져진 ip패킷은 ip프로토콜에 의해서 서버들이 모두 규약을 따르고 있으므로 해당 패킷의 출발지와 목적지를 알고 노드들 끼리 목적지를 확인하면서 계속 돌린다. 그렇게 계속 돌다가 목적지에 맞는 ip주소를 가진 클라이언트에 도달하게 된다
서버 패킷 전달
클라이언트 <- 인터넷 <- 서버
서버가 전달받은 패킷을 잘 받으면 받았다고 패킷을 전달하게 되는데 똑같이 자신의 출발 ip주소와, 도착 ip주소, 확인 내용 등 을 담아서 다시 전달 해준다. 그럼 위와 똑같이 노드 들끼리 해당 패킷의 도착 ip주소를 확인해보면서 돌리다가 최종적으로 도착 ip주소에 도착하게 된다
비연결성
ip프로토콜은 패킷에 적혀있는 목적지 ip주소가 받을 수 있는 상태인지 모른다
따라서, 인터넷 망에 올라간 패킷이 돌다가 최종적으로 목적지 ip에 도달하더라도 꺼져있거나 비활성 상태라면 받지 못한다
패킷 소실
패킷은 서버들을 돌고돌아 가는 것인데 도중에 해당 노드에 문제가 발생하면 소실될 수 있다
패킷 전달 순서 문제
패킷은 보낼 데이터 크기가 일반적으로 1500byte가 넘으면 나눠서 보낸다. 그래서 3000byte 크기의 데이터를 보냈을 때 a패킷과 b패킷으로 나눠서 가게 되었다고 가정해보자. 그런데 이때 a와 b가 동일한 인터넷 망의 길을 간다고 보장할 수 없다. 따라서 도착순서도 보장 할 없게된다
위와 같은 비연결성, 비신뢰성, 패킷 전달 순서 문제가 존재하므로 이를 해결하기 위한 필요성이 존재했다
-> TCP, UDP의 등장
인터넷 프로토콜 스택의 4계층
랜카드(인터넷선 꽂는 장치)를 이용해서 인터넷을 통해 서버에 연결된다
채팅프로그램으로 미국의 친구에게 메세지를 전달한다고 해보자
이너넷 프레임
랜카드에 포함된 MAC주소와 같은 물리적인 주소가 포함되어있다
IP패킷 정보
기존 ip패킷에는 출발지 ip, 도착지 ip 정도만 포함
TCP/IP 패킷 정보
ip패킷 정보 외에도 tcp 헤더의 정보가 포함된다
TCP 특징
전송 제어 프로토콜 - Transmission Control Protocol
SYN
메시지를 전달 후 SYN_SENT
대기 상태로 전환SYN
을 받은 서버는 SYN_RCVD
상태가 되고, ACK
와 SYN
를 같이 요청한다ACK
와 SYN
을 받은 클라이언트는 서버에게 ACK
를 보내고 ESTABLISHED
상태가 되고, ACK
를 받은 서버도 ESTABLISHED
상태가 된다SYN
: 접속 요청
ACK
: 요청 수락
클라에서 서버로 ACK
를 보낼 때 데이터를 함께 전송이 가능하다
실제로 클라-서버간 랜선 연결이 아닌 그 사이에는 인터넷 망을 통한 수많은 노드들이 존재, 단 3way handshaking을 통해 연결을 확인했으니 논리적으로 연결되었다 판단
클라가 서버에게 데이터를 전송하고 서버가 데이터를 받으면 ACK(데이터 잘받았음)
을 클라에게 전송해준다. 만약 클라가 데이터를 전송했는데도 ACK
를 받지 못한다면 재송신 해준다
UDP 특징
즉, 거의 ip와 동일하지만 추가적으로 PORT번호와 체크섬 정도만 추가된 것이다
애플리케이션에서 사용 시 추가 작업이 필요하다
하나의 클라이언트에서 한번에 둘 이상의 서버를 연결해야 한다면?
IP패킷들이 서버에서 클라이언트로 들어올텐데 이때 어떻게 해당 패킷들을 구별해서 필요한 프로그램에게 전달할 것인가
-> 포트번호를 부여 (응용프로그램 내에서의 구별)
TCP에서 패킷에 출발지의 PORT번호와 도착지의 PORT번호 정보를 담는다
사실상 패킷은 TCP/IP 패킷으로 구성되어 사용된다
출발지의 IP, 포트와 도착지의 IP, 포트를 가지며, 전송 데이터 및 그외 순서 보장, 도착 보장 등의 정보를 갖는다
즉, 같은 IP내에서 프로세스를 구분하기 위해 PORT를 사용하게 되는 것이다
IP를 아파트라 하면 포트는 동, 호수 개념
번호
0 ~ 65535 할당 가능
Domain Name System
따라서 IP주소를 외울 필요가 없고, 추후 IP주소가 변경되더라도 DNS서버에 등록된 IP주소만 변경하면 DNS는 변경되지 않는다
Uniform Resource Identifier
URI는
로케이터(Locator)
,이름(URN)
또는 둘다 추가로 분류될 수 있다즉 URI개념 안에
URL(Resource Locator)
과URN(Resource Name)
이 있는 것
URI에서 URL을 거의 대부분 사용
URL (주소로 표현, 어디에 어디로 가면 찾는 뭐가있다)
URN (찾는 무언가의 이름)
Uinform : 리소스를 식별하는 통일된 방식
Resource : 자원, URI로 식별할 수 있는 모든 것
Identifier : 다른 항목과 구분하는데 필요한 정보
URL - Locator : 리소스가 있는 위치를 지정
URN - Name : 리소스에 이름을 부여
문법
scheme://[userinfo@]host[:port][/path][?query][#fragment]
https://www.google.com/search?q=hello&hl=ko
프로토콜 : https
호스트명 : www.google.com
포트번호 : 443
패스 : /search
쿼리 파라미터 : q=hello&hl=ko
scheme
- scheme://[userinfo@]host[:port][/path][?query][#fragment]
- https://www.google.com/search?q=hello&hl=ko
userinfo
거의 사용하지 않는것으로 URL에 사용자 정보를 포함해서 인증할 때 사용한다
host
- scheme://[userinfo@]host[:port][/path][?query][#fragment]
- https:// www.google.com/search?q=hello&hl=ko
PORT
접속 포트로 일반적으로 생략한다
PATH
- scheme://[userinfo@]host[:port][/path][?query][#fragment]
- https:// www.google.com/search?q=hello&hl=ko
query
- scheme://[userinfo@]host[:port][/path][?query][#fragment]
- https:// www.google.com/search?q=hello&hl=ko
?
로 시작하며, &로 추가할 수 있다fragment
- scheme://[userinfo@]host[:port][/path][?query][#fragment]
- https:// docs.spring.io/spring-boot/docs/current/reference/html/getting-
started.html#getting-started-introducing-spring-boot
웹에 위와 같은 URL을 입력하게 되면 HTTP 요청 메시지
가 생성된다
HTTP 요청 메시지
GET/search?q=hello&hl=ko HTTP/1.1
Host: www.google.com
이런 형태의 HTTP요청 메시지가 생성된다
생성된 메시지는 아래와 같은 절차를 통해 전송되게 된다
생성된 패킷의 모습
TCP/IP패킷에 전송 데이터로 http 메시지가 들어간 모습이다
이 패킷이 인터넷 망을 돌다가 원하는 IP주소에 도착하게 되면 해당 서버는 요청 패킷을 받아서 TCP/IP패킷은 벗겨버리고 전송 데이터인 HTTP메시지를 확인하게 된다
http메시지를 확인한 서버는 HTTP 응답 메시지
를 다시 클라이언트에게 전달하게 된다
HTTP 응답 메시지
HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Content-Length: 3423
<html>
<boldy>...</body>
</html>
요청 패킷을 받은 구글서버는 위와 같은 http 응답 메시지를 만들고 다시 TCP/IP 패킷을 씌워서 응답패킷
을 인터넷 망에 올려서 전달해준다
최종적으로 요청패킷을 보냈던 웹브라우저(클라이언트)는 응답 패킷을 받고 해당 패킷의 HTTP 메시지를 열어서 HTTP 메시지 안에 들어있는 html 내용물을 웹 브라우저 상에 띄어서 보게 된다