- 신뢰성을 위해 3-way-handshaking, 4-way-handshaking한다.
- 데이터가 유실되었다면 재전송한다.
- 즉, 신뢰성이 높다
- 연결형 서비스이다
- 가상 회선 방식을 통해 패킷을 교환한다.
- 전송 순서가 보장된다.
- 전송 속도가 느린 편이다.
- Port 번호의 범위 때문에 연결은 최대 6.5K개 까지 할 수 있다.
- UDP는 TCP에 비해 제약이 덜하고 유연하다.
- 비연결형 서비스이다.
- 데이터그램 방식을 통해 패킷을 교환한다.
- 전송 속도가 빠르지만 신뢰성이 떨어진다.
과거에는 네트워크가 불안해서 패킷이 소실되는 경우가 많았다. 그래서 TCP를 많이 사용했다.
하지만 최근에는 네트워크가 많이 발전했기 때문에, UDP의 사용 범위가 커졌다.
UDP를 사용하는 분야
- streaming (음악, 영상)
- HTTP3
- unicast, multicast, broadcast 모두 지원
- (TCP는 unicast만)
I/O Stream
네트워트 간 데이터 전송이다.
stream의 특징
- 시작과 끝이 명확하지 않다.
- 헤더를 통해 req인지 res인지 판단하고 끊어서 해석한다.
HTTP
OSI 7계층과 TCP/IP 4계층의 차이와, TCP/IP 4계층에 해당하는 프로토콜 종류
그 중 HTTP는 Application Layer에 속하는 프로토콜이다. 따라서 전송계층과 네트워크계층을 통과해야 한다. HTTP에서는 신뢰성만 보장한다면 어떤 전송 프로토콜을 사용해도 문제가 되지 않는다.
HTTP/0.9 ~ /2.0은 TCP를 사용한다.
HTTP/1.1
- 다양한 파일을 지원한다.
- 하나의 연결 당 하나의 파일만 전달한다. → 단순하게 구현할 수 있다.
- truly stateless
- 매번 새로운 TCP 연결로 overhead가 크다.
- 성능이 저하된다
- persistaent connection
- 지정한 timeout동안 커넥션을 닫지 않는다.
- overhead를 조금 줄일 수 있었다.
- pipeline 기법
- 기존 방식은 순차적으로 데이터를 전달한다.
- 지연 시간을 줄이기 위해
- 응답을 기다리지 않고 일단 순차적으로 데이터를 연속적으로 보낸다
- 그 순서에 맞추어 응답을 받아 지연 시간을 줄인다.
- HTTP의 head of line blocking이라는 심각한 문제가 발생한다.
- 뒤 요청이 기다려야 하는 blocking 문제가 발생한다.
- 헤더 구조가 중복되는 문제가 발생한다.
HTTP/1.1 Request
HTTP/1.1 에서 명령어 줄바꿈 sep은 \r\n
으로 사용한다.
Request 자체의 메타 데이터를 Header로 관리한다.
HTTP/1.1 Response
HTTP/2 (2015)
- 기존 HTTP/1.1의 확장
- 메시지 전송 방식이 변화했다.
- 기존 HTTP/1.1방식이 하나의 덩어리로 데이터를 보냈다면,
- 바이너리 프레이밍 계층 사용(바이너리 인코딩)
- 전송속도는 높이고, 오류 발생 가능성은 낮춘다.
- 데이터를 frame 단위로 쪼갰기 때문에, 순서가 상관 없어졌다.
- req, res를 mulitplexing하게 처리할 수 있다.
- HTTP head
- 전송하는 stream의 가중치를 부여할 수 있다.
- Server Push
- 클라이언트가 요청하지 않아도 필요하다고 판단되면 알아서 준다.
- Header comporession
- HTTP/1.1에는 헤더 중복 문제가 있었다.
- static/dynamic table을 활용해서 중복되는 헤더는 인덱스만 전달
- 중복되지 않는 헤더는 허프만 인코딩해서 전달
- 평균적으로 헤더크기를 85% 줄인다.
- 상태를 어느정도 관리를 해주어야 한다.
- 하나의 TCP 커넥션으로 한꺼번에 resource를 주고 받는다.
- 비동기적으로 요청을 보낼 수 있다?
- 멀티플랙싱을 제공한다.
- 중간 데이터가 손실되면 뒤 데이터가 다 기다려야 한다.
- TCP head of line blocking 문제가 있다.
QUIC (2013)
- 구글에서 제안한 새로운 전송 계층 프로토콜
- 현재 구글 관련 제품 대부분의 기본 프로토콜
- UDP 기반으로 제작되었다
- TCP는 지연을 줄이기 힘든 구조이다
- 데이터 전송에만 집중되어 있다
- 설정에 필요한 데이터와 데이터를 전송한다
- 연결 성공 시 설정을 캐싱해서 다음 연결 때 바로 성립할 수 있다.
- Connection UUID라는 고유한 식별자로 서버와 연결
- 커넥션을 재수립할 필요가 없다
- TLS가 기본 적용되어 있다
- IP Spoofing과 Replay Attact을 방어할 수 있다
- 독립 스트림을 통해 향상된 멀티플랙싱을 제공한다.
- 한 스트림에 문제가 생겨도 다른 스트림에 영향을 주지 않는다
- 유투브는 평균 30프로 스트리밍 속도가 향상되었다.
Network 동작 형태
Network Framework in NodeJS
보통 상위 레벨의 모듈을 사용하지만, 가끔 로우레벨까지 내려가서 처리해야할 때가 온다.
Network API의 발전
Sync - Blocking
- 요청을 한 후 Blocking 상태로 기다린다.
- timeout이나 예외처리등 따로 설정해 주어야 하는 것이 많다.
- 응답이 완전히 도착할 때까지 대기
Sync - non-Blocking
- Client가 호출의 응답을 기다리지 않고 바로 처리할 수 있다.
- 연결되고 있다는 것을 알 수 있다.
- 과정에 대해 화면 처리를 할 수 있다.
- 이를 위해서 클라이언트가 주기적으로 현재 상태를 물어야한다.
- 주도권은 Client측이 갖고 있다.
Async - non-Blocking
- 콜백을 전달 해주고,
- 요청이 끝나면 콜백이 알아서 실행된다.
- 비동기 처리를 해주는 워커가 따로 존재해야 한다.
Async - Blocking
- Async - Blocking은 없는 것 같다..?
- 요청을 한다음에 응답은 바로 받지만
- 서버의 응답을 기다리긴 해야한다.
- 주도권은 둘 다 있는듯?
Coroutine
- 등장은 진작 했다.
- 더 효율적인 비동기 작업을 위해 등장했다.
- 워커가 둘다 동작해야한다.
- 루틴이 동시에 돌아가는 구조를 갖는다.
- 하나 혹은 여러 쓰레드에서 동작한다.
- Kotlin이 이 기능을 지원한다.