컴퓨터네트워크_Application Layer

김태성·2024년 9월 21일

개인 프로젝트-1

목록 보기
42/53

프로젝트 배포 자동화/테스트까지 모두 마쳤다. 이제 남은건 서비스 로직을 구현하는 것이다.
Postman과 Locust로 테스트를 돌리다 문득 떠오른게..
내가 네트워크에 대해 아는게 있는가? 였다.

곰곰히 생각해보니 이때까지 네트워크를 공부한게

  • 7계층
  • 네트워크강의 약간
  • tcp/ip
  • handshake
  • socket
  • gateway

이정도? 잠깐 깔짝 공부한게 다였고, 재대로 공부한적이 없었다.
그래서 지금부터는 네트워크에 대해 공부해보려고 한다.

어떻게 공부할까 검색을 해보던 도중
이석복 한양대 교수님의 네트워크 강의 추천글이 많았다.
그래서 그 강의를 듣고, 강의 요약 및 정리를 해볼 생각이다.
레퍼런스 : http://www.kocw.net/home/cview.do?cid=6b984f376cfb8f70

저작권 법에 따라 출처 공개, 영리목적 사용금지, 내용을 의도적으로 바꾸지 않습니다.

Application Layer

처음부터 중요한 개념이 나온다.

네트워크 디자인 패킷스위칭 방식으로 결정됨
cirkit 스위칭 방식으로 정해지지 않은 이유
장단점

  • 제한되지 않은 사용자를 수용할 수 있느냐

패킷스위칭의 단점
=> 한순간에 트래픽이 몰렸을때 2가지 증상 나옴
1. 큐에서 딜레이 길어짐
2. 상황이 악화되면 큐에 들어갈 수 없어서 패킷유실이 발생한다.(패킷 손실의 99.99%)

라우터 지연 4가지

위의 내용은 이전 강의의 리마인드로 나온 이야기이다.
예전부터 패킷 손실이 왜일어났는지 궁금했는데 단 한마디로 해결이 되었다..
(전압 약화로 인한 데이터 인식 불균형 등이 이유라고 생각했었음)

네트워크는 복잡하기 때문에 계층화를 시켰다.
우리와 가장 가까운 App 계층부터 살펴봄 - Web Browser

지금은 다른 계층을 없다고 가정하고, App 계층 관점으로 학습할것임.

Principles of network application

프로세스는 OS에서 제공하는 기능들을 사용해서 만든 프로그램이다.
프로세스는 고유의 IP 주소를 가지고, 다른 기기에 있는 프로세스와 연결을 하고 싶다.
이때 App 관점에서 Socket이라는 Interface를 제공한다.
(Socket도 SystemCall이다)

이때 중요한것은 프로세스에서 메시지를 보낼때, 다른 프로세스에서 받게 하기 위해서는
주소가 필요하다. 이때 주소는 IP주소(기기를 가리킴)라고 하고,
그 기기의 수많은 프로세스들(많은 Socket이 열림)중에 내가 어떤 프로세스를 지칭하는가는
포트번호라고 한다.

내가 했던 프로젝트로 생각하면
Local Host : 0000
이런 IP 주소를 가졌던것이 생각난다.
8082는 서버, 3000은 프론트, 또 다른건 Locust 등등..

이때 IP 주소를 일일이 다 기억하기 힘들기 때문에 문자열 시스템을 제공하는데,
이것을 DNS라고 부른다.
이때 DNS의 포트번호까지 일일이 호스팅하기 귀찮으니까(번거롭고 실수가 발생가능함)
문자열주소와 묶어버린다.
-> 이후 추가적으로 공부하다보면 엄밀히 맞는 말은 아니다.(일단 내가 아는건 게이트웨이도 안나옴)

이때 Transport 계층에서 뭔가 요구사항이 생길 것이다.(보안이라던가)
하지만 이런건 아래 계층에서 전혀 제공해주지 않는다.
tcp/ip설계한 70개발자들은 보안에 관해 고려하지 않았음.
그래서 이러한 요구사항이 발생하게 되는데, App 계층에서 전부 구현하는 방식으로 해결됨.

-> Spring Security가 그렇게 복잡하고 기능이 다양한지에 대해서 이유를 찾은거 같다.
그러고보니 "전송/인터넷 계층에서 자동접으로 안잡아주나?" 라는 생각은 하지도 못했었다..

이때 전송계층에서 제공하는것은 TCP/UDP 2가지이다.
TCP는 아무것도 제공 하지 않고 확실한 전송을 제공함.
UDP는 불확실한 전송

TCP는 email, web, file transfer 등이 있고,
UDP, TCP 혼용은 스트리밍, 인터넷 전화 등이 있다.

Web and HTTP

Web은 HTTP의 별칭이다.
그리고 HTTP 프로토콜의 이름을 이해하는것이 중요하다.

HTTP

HTTP : Hypertext Transfer Protocol - 하이퍼텍스트(링크달린 글) 전송 프로토콜

Http는 Request와 Response로 이루어진다.
Request : Client(Web)이 필요하다고 요청
Response : 적절한 값을 반환하는것

즉, 필요한 데이터를 달라고 요청하고, 그대로 반환하는것이 전부이다.
App 계층 프로토콜이기 때문에 하위 Transfer Protocol 중 하나를 골라야 한다.(TCP/UDP)
그중 HTTP 개발자는 TCP를 선택하였다.

TCP를 사용한다 = 비용을 내야 한다.

  • TCP로 데이터를 보낼려면 서버와 클라이언트가 TCP 커넥션이 맺어져야 한다.

또한 2가지 방식으로 통신한다.

  • Non - Persistent HTTP
  • Persistent HTTP

한번 생성한 TCP 커넥션을 계속 사용할것인가? 에 대한 방법임.
(나중에 이 방법에 대해 공부해야함)

Sample 문제
persistent HTTP를 사용했을때 end - to - end 딜레이는 얼마인가?

  • 요청을 보내기 위해 TCP 커넥션을 만들어야함. 따라서 TCP 커넥션 요청 메시지 보냄(메시지크기/벤딧 + 딜레이)
  • TCP 커넥션 메시지 반환(K/R + d)
  • Http Request(K/R + d)
  • Http Response(L/R + d) -> L = 반환값
  • 부족한 Obj Request( Request - Response N번 반복)

(Obj의 갯수를 미리 알고있으니까 한번에 요청을 보냄)
따라서, N(K+L)/R + N*d

HTTP Request Message

Get / index.html HTTP/1.1 \r\n
-> 요청방식(Get, Post..) , 페이지 이름(index.html), 버전(HTTP/1.1)
Host : www.net....
-> 누가 보내는가
User-Agent : Firefox/3.g
-> 유저가 뭘로 보냈는가(브라우저, Firefox)
Accept :
->클라이언트가 수락할 수 있는 MIME 타입(미디어 형식)을 지정
Connection:
-> Keep Alive = 연결 계속하겠다

교수님은 대충 넘어가라고 했지만, 이후 CORS가 왜 발생하는지에 대해 알수 있는 부분이었다.

이전에 발생했던 CORS 에러 상태이다.
Host와 Origin이 다른것을 확인할 수 있는데, 여기서 Host가 HTTP 프로토콜 헤더에 담겨서 전달된다는 것을 알 수 있다.

Response Message

HTTP/1.1 200 OK
-> 상태 메시지
Date:Sun, 26...
-> 시간
Server: Apache/2.0.52..
-> 서버 정보. 아파치 서버를 이용하는 중이다.(Java의 톰켓과 같은 기능)
Last-Modified:
-> 마지막 수정 날짜
ETag:
-> 엔티티 태그라고 하는데, 리소스 변경을 알아본다고 한다..
이후~~~

  • 여기에 쿠키를 추가하고 싶으면 Set-Cookie를 사용해서 집어넣는다.
    프로젝트 진행중 로그인 로직을 만들때, JWT 토큰을 쿠키로 만들었는데, 이때 사용한다.

React에서 쿠키를 사용했다.

또한 HTTP는 StateLess이다.
Server는 Client에 대한 어떤것도 기억하지 않고, Client도 마찬가지이다.

Cache

Cache를 사용해면 트래픽이 줄어들어서 비용이 줄어든다.
하지만 데이터가 업데이트 되었을때 일관성 문제를 해결해야 한다.
이건 CloudFront CDN에 프론트 페이지를 업로드 했을때 무효화를 하지 않으면 한참 걸리는 이유이다.

설명하기 위한 예시.
A 라우터에서 들어오는게 15.4Mbps이고, 외부 LAN은 100Mbps인 상황이다.
이러면 A 라우터에서 나오는 대역폭이 너무 작아서 85% 이상의 딜레이가 발생한다.
이 상황은 학교 내부 인터넷망에서 외부 도메인에 접속할때 속도가 심각하게 느려진다는 말이다.

그래서 외부로 나가는 대역폭을 확 늘려버리면 일단 된다.
하지만 케이블 공사라는게 비용이 수천만원~ 이상 발생할수 있어서 엄청나게 비효율적이다.
공사할려면 땅 다까고 전선 매설하고 추가 관리도 필요하다.

그래서 WebProxy를 설치해 봤다.
내부 망에 프록시가 있기 때문에 외부에서 들어오는 데이터의 대부분이 이 프록시에서 처리 가능하다.
즉, 네이버 페이지를 로딩하는데 대부분의 데이터를 캐시되어있는 프록시에서 꺼내고, 나머지를 요청한다는 것이다.

다 접속하는 사이트가 거기서 거기라서 캐시의 성능이 매우 높다.

Conditional GET

그럼 이 프록시가 생김으로서 생기는 일관성 문제는 어떻게 해결해야 되냐?
HTTP 헤더에서 if-modified-since:date 를 추가하고,
이 시간 이후에 업데이트 되지 않았으면, 304 Not Modified를 return 한다.
업데이트 한 경우는 200OK를 리턴한다.
요청 데이터가 너무 많다면 날짜로 버전만 확인한다는 것이다.

FTP

Electronic mail

Three major components

  • user agent
  • mail servers (gmail...)
  • simple mail transfer protocol : SMTP

SMTP와 HTTP의 차이

  • SMTP는 전송, HTTP는 당겨오는 방식

access protocol

  • pop3
  • imap
  • http

DNS

Domain Name System
위에서 적은것처럼 특정 IP랑 문자열 주소랑 1:1 매핑시켜놓는것이다.
하지만 서버에 이러한 데이터를 Key-Value로 가지고 있다면 엄청난 트래픽이 몰릴것이고
서칭하는데 시간이 무지막지하게 걸릴 것이다.
또한 서버가 다운된다면? 전세계 인터넷망이 멈추게 될 것이다.

그래서 DNS 서버는 계층화를 시켜놨다.
규모가 너무 커져서 감당이 안되니 각 DNS 서버를 만들어서 분산을 시켜버린 것이다.

Root Copy - 전세계 13개 카피서버
TLE - Top-Level Domain 서버
Authoritative DNS Server - 각 기관이 보유하고 있는 호스트 도메인은 자기가 관리.
Local DNS name server

예시1) 한양대라는 네트워크에 컴퓨터가 무수히 많은데, 이중 이름을 가지고 있는 컴퓨터가 있음.
그러한 컴퓨터들의 이름들은 한양대 DNS에서 관리를 해야 된다는 것이다.
이때, 그러한 도메인 이름을 알고 있는 서버를 Authoritative DNS Server라고 한다.

예시2)내부 서버에서 외부 도메인으로 이동할때, 서버는 호스트와 ip 매핑에 대한 캐시를 가지는데, 이것을 Local DNS Name Server라고 한다.

-> 이후 자세하게 다시 공부 필요

resolution example

리퀘스트 호스트 -> 로컬 dns서버 -> (1.root, 2. tld, 3. authoritative)
그럼 여기서 또 일관성문제가 터지면 어떻하나?
DNS Records

  • name, value, type, ttl

TTL 필드 라는걸 둔다. Key-Value에 유효기간을 두는것.(이 기간 지나면 파기)
그럼 타입은 뭐냐?

  • A : name = hostname, value = ip
  • NS : name = domain, value = hostname of authoritative name
  • CNAME : name = alias name for some canonical, value = canonical name
  • MX : value = name of mailserver associated with name

4가지가 있다.

aws route53에서도 확인할 수 있는 내용이다.
그리고 DNS는 UDP를 사용한다.
왜? 어차피 유실될 확률 거의없고 빠르게 통신해야한다.

P2P Applications

Socker UDP/TCP

소켓 = 프로그램 사이의 통신을 위한 인터페이스(OS에서 제공)
TCP(SOCK_STREAM)/UDP(SOCK_DGRAM) 2가지가 존재함.

Sockets API
네트워크 소켓을 사용하기 위한 System Call

이거말하는거다.
전체적인 부분이 다 위의 TCP 소켓 코드레벨을 설명하는거라서 뭘 정리해야될지는 잘 모르겠다.
그래서 미니 프로젝트 숙제를 내는거같은데 내 코드를 보면서 복습하는게 나을거 같다.
진짜 소스코드 보면서 설명하는데 글자도 잘 안보인다..

그래도 적어보자면
socket() => 소켓 만드는거
bind() => 주소 매핑하는거
listen() => 외부 신호를 듣는거(요청 감지)
accept() => connect 할때까지 block해서 socket()이 끊어지지 않도록
connect => 3way handshake를 통해서 소켓 연결

이후 write <-> read 반복

후기

대부분 아는내용이지만 체계적으로 관리가 된다는 것에 많은 도움을 받았고
내가 무엇을 모르는지, 어떤 공부를 해야할지 감이 잡힌거 같다.
강의가 거의 20개쯤 되는데, 다 듣고 한번 복습할 예정이다.
내일부터 열심히 들어야겠다..

profile
닭이 되고싶은 병아리

0개의 댓글