• 네트워크 애플리케이션은 end system 에서 동작함
End Systems : 사용자 컴퓨터, 스마트폰, 서버 등
실제 애플리케이션(ex. 웹 브라우저, 이메일 클라이언트, 웹 서버)이 실행되는 장치
직접 코드를 작성하여 실행하는 것은 end system에 설치되는 프로그램
ex. 웹 브라우저, 웹 서버
• network-core device는 애플리케이션을 실행하지 않음
network-core device : 라우터, 스위치, 게이트웨이 등
데이터를 전달하는 역할만 하며, 애플리케이션을 실행하는 용도로 설계되지 않음
개발자는 상위 계층(애플리케이션 계층)의 논리만 구현하면 되고,
나머지 하위 계층(전송, 네트워크 등)은 이미 표준화된 프로토콜에 따라 동작
• 서버(Server)
서비스를 제공하는 장치(호스트)
ex. 웹 페이지를 제공하는 웹 서버, 이메일을 전송/수신하는 메일 서버
• 클라이언트(Client)
서버에 서비스를 요청하는 장치
ex. 웹 브라우저, 이메일 클라이언트, 모바일 앱
동적 IP 주소는 DHCP(동적 호스트 구성 프로토콜) 등을 통해 사용자가 네트워크에 접속할 때마다 ISP가 임시로 할당하는 IP 주소
→ 사용 중에는 공인 IP 주소로서 전 세계적으로 고유하게 관리됨
DHCP : 애플리케이션 계층 프로토콜
클라이언트-서버 모델과는 달리,
중앙에 항상 켜져 있는 서버가 없이 네트워크에 참여하는 모든 노드(peer)가
서로 동등한 역할을 수행하는 구조
→ 서버이자 클라이언트 역할을 동시에 함
• 중앙 서버 없음
: 모든 peer가 독자적으로 데이터를 주고받음
• 양방향 역할
: 각 peer는 클라이언트의 기능과 서버의 기능을 모두 수행
• 직접 통신
: 중앙 서버를 거치지 않고 peer들은 서로 직접 연결되어 데이터를 교환
• 확장성 (Self-Scalability)
: 새로운 peer가 네트워크에 참여할 때마다 전체 네트워크의 자원
(ex.파일 공유 용량, 처리 능력 등)이 증가
• 동적 환경
peer가 언제든지 네트워크에 연결되었다가 끊길 수 있고, 연결될 때마다 새로운 네트워크 설정(ex.IP 주소)을 받을 수 있음
Process : 호스트 내에서 실행 중인 프로그램
Inter-Process Communication (IPC)
: 한 호스트 내의 두 프로세스가 서로 데이터를 주고받기 위해 사용하는 통신 방법
→ 운영체제(OS)에 의해 정의되고 관리됨
서로 다른 호스트에 있는 프로세스들은 네트워크를 통해 메시지를 교환하여 통신
Client Process
: 통신을 시작(initiates communication)하는 프로세스
ex. 웹 브라우저가 사용자의 요청에 따라 웹 서버에 데이터를 요청
서버 프로세스 (Server Process)
: 클라이언트의 요청을 기다리며, 연결을 수신하고 처리하는 프로세스
ex. 웹 서버, 메일 서버, 데이터베이스 서버
Sockets
: 애플리케이션 프로세스가 네트워크 통신을 하기 위해 전송 계층(TCP, UDP)의 서비스를 쉽게 사용할 수 있도록 하는 프로그래밍 인터페이스(API)
→ 데이터가 다니는 문(door)
application layer에서 생성된 데이터가
socket 인터페이스를 통해 transport layer(TCP/UDP)으로 전달되고,
그 아래 IP, link, physical layer을 거쳐 실제 네트워크로 전송됨.
→ 소켓은 application layer 과 transport layer 사이에서
데이터의 입출력을 중개하는 역할
• 두 Socket이 필요 :
네트워크 통신에서는 양쪽에 각각 소켓이 존재.
ex. 클라이언트와 서버가 통신할 때
클라이언트는 자신의 소켓을 통해 요청 메시지를 보내고,
서버는 자신의 소켓을 통해 그 요청을 받고 응답
메시지를 받으려면 각 프로세스는 자신만의 식별자(Identifier)를 가져야 함
각 호스트는 전 세계적으로 고유한 32비트 IP 주소를 가지고 있음 (동적/정적)
but, 한 호스트에서는 여러 프로세스가 동시에 실행될 수 있으므로,
호스트의 IP 주소만으로는 어떤 프로세스가 메시지를 받아야 하는지
구분할 수 없음
호스트 내에서 실행되는 프로세스를 구분하기 위해 사용
→ 전체 식별자는 (IP 주소 + 포트 번호)로 구성
= 소켓 주소(Socket Address)
ex.
메시지의 종류
애플리케이션 간에 교환되는 기본 메시지 유형들을 규정
ex. request, response
메시지 구문 (Message Syntax)
메시지 내의 fields(데이터 요소)와 그 구조가 어떻게 구성되어 있는지를 정의
메시지 의미론 (Message Semantics)
메시지 내의 각 필드에 담긴 정보의 의미를 명확히 규정
ex. HTTP 응답에서 상태 코드(200, 404)는
요청의 성공 여부나 오류 종류를 나타냄
메시지 송수신 규칙
application 간에 언제, 어떻게 메시지를 보내고,
어떤 상황에서 응답해야 하는지에 대한 규칙
ex. 클라이언트가 HTTP 요청을 보내면,
서버는 반드시 일정 시간 내에 응답을 보내야 함
: RFC(요청 의견서, Request for Comments)와 같은 공개 문서에 의해 정의되며, 누구나 그 규격을 열람하고 구현 가능
ex. HTTP, SMTP
: 특정 회사나 조직이 내부적으로 개발하여 사용하는 프로토콜로, 공개되지 않음
100% 신뢰성 요구
전송된 데이터가 전혀 누락되거나 손상되면,
전체 파일이나 거래가 실패할 수 있는 경우
ex. 파일 전송, web transaction, 전자 상거래
→ TCP와 같은 신뢰성 있는 전송 프로토콜이 필요
일부 손실 허용
약간의 데이터 손실이 발생해도, 자연스러운 재생이 중요한 경우
ex. 실시간 오디오 스트리밍
→ UDP처럼 빠른 데이터 전달을 우선시하는 프로토콜 필요
실시간 상호작용이 필수인 애플리케이션은
지연(latency)이 너무 길어지면 사용자 경험이 크게 저하됨
→ 빠른 전송과 최소 지연이 중요하므로, 약간의 신뢰성 손실을 감수
최소한의 처리량(대역폭) 요구
일정 수준 이상의 데이터 전송 속도가 보장되어야
스트리밍 서비스가 끊김 없이 재생
ex. 멀티미디어 스트리밍 (비디오, 고해상도 오디오)
탄력적(elastic) apps
네트워크 상황에 따라 가변적으로 데이터를 처리할 수 있으며,
어느 정도의 속도 변화는 서비스에 큰 영향을 미치지 않는 app
ex. 웹 브라우징, 이메일, 파일 다운로드
전송되는 데이터가 도청되거나 변조되지 않도록 보호해야 함
ex. 온라인 금융 거래(password), 개인 데이터 전송, 의료 정보
TCP 기반 애플리케이션 (신뢰성 중요, 손실 허용 X)
TCP / UDP 혼합 기반 애플리케이션
신뢰성 있는 전송 (Reliable Transport)
데이터가 손실 없이 순서대로 도착하도록 보장
오류 검출, 재전송, 순서 보장, 흐름 제어, 혼잡 제어 등의 메커니즘을 포함
연결 지향 (Connection-Oriented)
통신 전에 클라이언트와 서버 사이에 연결을 설정
제공하지 않는 기능
타이밍(지연 최소화)나 최소 처리량 보장, 보안(암호화)은 기본적으로 제공하지 않음
신뢰성 없는 전송 (Unreliable Data Transfer)
데이터 손실, 순서 변경, 중복 등이 발생할 수 있음
오류 검출은 있지만, 재전송이나 순서 보장은 제공하지 않음
비연결형 (Connectionless)
연결 설정 없이 바로 데이터를 보내며, 통신 오버헤드가 매우 적음
제공하지 않는 기능
신뢰성, 흐름 제어, 혼잡 제어, 타이밍, 최소 처리량 보장, 보안, 연결 설정 등 거의 모든 제어 메커니즘을 제공하지 않음
오버헤드* : 네트워크 통신에서 데이터(payload) 외에 추가로 전송되는 모든 정보 (ex. header)
일반적인 TCP와 UDP 소켓은 데이터를 그대로 전송
애플리케이션이 소켓을 통해 패스워드나 민감한 정보를 전송하면,
데이터는 암호화되지 않고 cleartext로 네트워크를 통해 전송
애플리케이션이 사용할 수 있는 보안 라이브러리로,
기본 TCP 연결 위에서 암호화된 안전한 통신을 제공
주요 기능:
동작 방식:
: 하나의 HTML 파일만 있는 것이 아니라,
텍스트, 이미지, 스크립트 등 여러 종류의 객체(파일)들이 모여 웹 페이지를 만듦
하나의 웹 페이지에 포함된 모든 객체가 같은 서버에 있는 것이 아니라, 다른 서버에 저장되어 있을 수 있음
브라우저는 HTML 파일을 먼저 요청하고, 그 안에 있는 여러 URL을 찾아
각 URL에 해당하는 객체를 별도로 요청하여 가져옴
www.someschool.edu/someDept/pic.gif
• 호스트명 (Host Name): www.someschool.edu
→ 이 이름을 DNS를 통해 IP 주소로 바꿔서 실제 서버에 접속
• 경로 (Path): /someDept/pic.gif
→ 해당 서버 내에서 실제로 요청하는 파일이나 리소스의 위치
웹 브라우저가 URL 입력
→ DNS 조회를 통해 호스트의 IP 주소를 확인하고,
해당 서버에 HTTP 요청을 보냄
서버가 응답
→ 기본 HTML 문서를 전송
HTML 파싱 후
→ 브라우저는 HTML 문서 내의 <img> <script> <link> 등의 태그를 인식하고, 각각의 URL에 대해 추가 HTTP 요청을 보냄
최종적으로
→ 모든 객체가 브라우저에 로드되어
하나의 완성된 웹 페이지가 사용자에게 표시됨
웹 브라우저(HTTP 클라이언트)가
TCP 연결(소켓을 생성하여 80번 포트에 접속)을 통해 웹 서버와 연결하고,
HTTP 메시지(요청과 응답)를 교환
각 HTTP 요청은 독립적이며,
서버는 이전 요청에 대한 상태 정보를 유지하지 않음
→ state 유지가 필요한 경우, 애플리케이션 차원에서 별도의 상태 관리
(ex. 쿠키)를 통해 해결
만약 서버가 클라이언트의 과거 요청을 계속 기억한다면,
ex. 로그인 상태, 세션 정보
서버 측에서 이 정보를 관리하는 로직이 추가되어야 하고,
클라이언트와 서버 간의 동기화 문제,
(= 한 쪽이 crash(오류 발생)하거나 재시작할 경우)
→ state 정보가 불일치하는 문제가 발생
HTTP 메시지의 종류 : Request, Response
GET /index.html HTTP/1.1\r\n
<GET> : 메서드 (요청 방식, ex. GET, POST, HEAD, PUT)
</index.html> : 요청 대상 경로 (서버에서 가져오려는 리소스)
<HTTP/1.1> : HTTP 버전
클라이언트의 정보나 요청 조건을 설명
헤더 부분이 끝났음을 알리는 구분자
(Carriage Return + Line Feed)
→ HTTP 메시지는 텍스트 기반의 ASCII 형식으로 작성되어, 사람이 읽을 수 있음
method sp URL sp version cr lf
<method> : HTTP 메서드 (ex. GET, POST, PUT, DELETE)
<sp> : 공백(Space)
<URL> : 요청하려는 리소스 경로 (ex. /index.html)
<version> : HTTP 버전 (ex. HTTP/1.1)
<cr lf> : 줄 끝 표시 (Carriage Return + Line Feed, \r\n)
header field name : value cr lf
<header field name> : 헤더의 이름 (ex. Host, User-Agent)
<value> : 해당 필드의 값
<cr lf> : 줄 끝 (\r\n)
→ 모든 헤더가 끝난 뒤에는 빈 줄 하나 <\r\n> 가 있어야 함
일부 요청 방식(POST, PUT)은 이 부분에 실제 데이터를 담아 전송
웹 페이지에 입력 폼(form)이 포함되어 있을 때,
사용자가 입력한 데이터를 서버로 전송할 때 사용
클라이언트(ex. 웹 브라우저)는 사용자가 입력한 데이터를
HTTP POST 요청의 entity body에 담아 서버로 전송
→ URL에 데이터가 노출되지 않기 때문에 보안상 장점
주로 서버로부터 데이터를 요청할 때 사용
간단한 사용자 데이터(ex. 검색어)를 함께 전송하는 경우에도 사용
클라이언트는 요청 URL에 ? 이후에 데이터를 쿼리 문자열(query string) 형태로 포함시킴
www.somesite.com/animalsearch?monkeys&banana
<animalsearch> : 요청 리소스
ex. 서버에 "동물 검색"과 관련된 기능이나 데이터를 요청
<monkeys&banana> : 서버에 전달되는 사용자 데이터
ex. 어떤 동물을 검색할 것인지,
"원숭이와 바나나"와 관련된 정보를 찾으라는 추가 정보를 전달
→ 데이터가 URL에 노출되므로 민감한 정보를 전송하기에는 적합하지 않음
GET 요청과 거의 동일하게 작동하지만,
본문(body)은 제외하고 헤더 정보만 요청할 때 사용됨
클라이언트가 특정 URL에 대해 HEAD 요청을 보내면,
서버는 해당 URL에 대해 GET 요청을 보냈을 때 반환될 헤더만을 응답
리소스의 존재 여부, 크기, 최종 수정일 등 정보를 확인할 때 사용
→ 실제 데이터를 다운로드하지 않고 메타데이터만 확인할 수 있으므로,
네트워크 자원을 절약 가능
클라이언트가 새로운 파일(객체)를 서버에 업로드하거나,
이미 존재하는 파일을 완전히 대체할 때 사용
클라이언트는 PUT 요청의 entity body에
업로드할 데이터(파일 내용 등)를 담아 전송
서버는 해당 URL에 이미 존재하는 파일이 있다면 그 내용을 완전히 대체
HTTP/1.1 200 OK\r\n
<HTTP/1.1> : 사용된 HTTP 버전
<200> : 상태 코드 (200은 성공)
<OK>: 상태 코드에 대한 설명 (status phrase)
→ 클라이언트에게 요청이 정상적으로 처리되었는지,
오류가 발생했는지 알려주는 부분
<Date> : 응답이 생성된 시간
<Server> : 사용 중인 웹 서버 소프트웨어 정보
<Last-Modified> : 리소스가 마지막으로 수정된 시간
<Content-Length> : 응답 본문의 길이 (바이트 단위)
<Keep-Alive>, <Connection> : TCP 연결을 유지할지 여부
<Content-Type> : 콘텐츠 유형 및 문자 인코딩 (ex. HTML, UTF-8)
\r\n
헤더와 본문(body)을 구분
→ HTTP 규약에서 빈 줄 이후가 본문 시작을 의미
data data data data data ...
실제로 클라이언트가 요청한 데이터(ex. HTML 문서, 이미지 파일)
HTTP 응답 메시지의 첫 번째 줄(Status Line)에 나타남
서버가 클라이언트의 요청에 대해 처리한 결과를 나타냄
: 요청이 성공적으로 수행되었으며,
요청한 객체(리소스)가 응답 본문에 포함되어 있음
: 요청한 리소스가 영구적으로 다른 위치로 이동했음
응답 헤더의 Location 필드에 새 URL이 제공되어,
클라이언트는 이후 이 새 위치를 통해 접근해야 함
→ 웹 사이트가 도메인을 변경한 경우
기존 URL 대신 새 URL로 자동 리다이렉션할 때
클라이언트가 보낸 요청 메시지가 서버에서 이해할 수 없는 형식이거나
잘못되어 있음을 나타냄
잘못된 구문, 누락된 필드 또는 잘못된 파라미터 때문에
서버가 요청을 처리할 수 없을 경우
요청한 문서나 리소스가 서버에 존재하지 않음
클라이언트가 존재하지 않는 페이지나 파일을 요청했을 경우
클라이언트가 사용한 HTTP 버전이 서버에서 지원되지 않음
클라이언트가 매우 오래되었거나, 비표준 HTTP 버전을 사용하여 요청했을 경우
장점
단점
클라이언트가 서버에 데이터 X를 업데이트하는 작업을 두 번 수행해야 하는 상황
ex. 주문 상태를 변경하는 등의 작업에서,
클라이언트가 “업데이트 1”을 보낸 후에 “업데이트 2”를 보내야
전체 작업이 완료되는 경우
상태 정보 유지:
stateful 시스템은 각 클라이언트의 이전 작업 상태를 서버가 기억
ex. 클라이언트가 업데이트 1을 완료한 후,
서버는 “이 클라이언트는 업데이트 1을 완료했다”는 상태를 기록
클라이언트의 연결 끊김:
업데이트 2를 보내기 전에 t′ 지점에서 클라이언트가 죽거나 연결이 끊기면, 서버는 업데이트 1만 수행된 상태로 남게 됨
→ 데이터 X는 완전히 업데이트되지 않고 중간 상태가 되어버려서,
원래 의도했던 최종 상태와 다르게 됨
회복 및 재동기화의 복잡성:
이런 상황이 발생하면, 서버는 클라이언트의 상태를 추적하여,
중간에 끊긴 작업을 어떻게 복구할지 결정해야 함
ex. 클라이언트가 다시 연결될 때 이전 상태를 확인하고 업데이트 2를 다시 요구하는 등의 추가 처리가 필요
→ 시스템 전체가 복잡해지고 오류 발생 가능성이 높아짐
HTTP는 stateless + 쿠키 사용
: 웹 서버가 클라이언트의 웹 브라우저에 작은 데이터를 저장하게 하는 메커니즘
쿠키는 서버에서 생성되는 경우가 일반적
클라이언트에게 이후의 모든 HTTP 요청에 쿠키를 포함시켜 보내게 하여,
서버는 쿠키를 통해 사용자의 상태를 식별할 수 있음
ex. 로그인 후 발급된 쿠키를 통해 서버는
“이 사용자는 이미 로그인했다”는 정보를 알 수 있음
: 쿠키와 함께 사용되어, 서버에서 별도로 관리하는 상태 정보
쿠키에는 세션 식별자(session ID)가 저장되고,
서버는 이 식별자를 사용해 해당 사용자의 상태 정보를 조회함
HTTP 응답 메시지의 쿠키 헤더
: 웹 서버가 클라이언트에 쿠키를 전송
쿠키에는 고유 식별자(ID)가 포함되어 있어, 서버가 사용자를 식별할 수 있음
HTTP 요청의 쿠키 헤더
: 클라이언트(브라우저)가 서버로 요청할 때, 이전에 받은 쿠키 정보를 함께 전송
이를 통해 서버는 사용자를 인식하고, 이전 상태 정보를 조회
사용자 호스트에 저장된 쿠키 파일
: 브라우저가 쿠키 정보를 로컬에 저장하는 파일이나 데이터베이스
브라우저는 쿠키 파일을 관리하며, 쿠키에 저장된 정보를 HTTP 요청 시
자동으로 첨부
웹 사이트의 백엔드 데이터베이스
: 서버는 쿠키에 포함된 고유 ID를 사용하여, 사용자와 관련된 상태 정보
(ex. 로그인 정보, 장바구니 내용)를 데이터베이스에 저장하고 관리
처음 접속 (최초 요청)
클라이언트가 Amazon 서버에 HTTP 요청을 보냄.
Amazon 서버는 사용자를 식별할 ID(1678)를 생성,
응답 메시지에 Set-Cookie: 1678이라는 HTTP 헤더를 포함시켜 전송.
브라우저는 이 쿠키(amazon 1678)를 로컬 쿠키 파일에 저장.
다음 접속 (이후 요청)
클라이언트가 같은 사이트에 다시 HTTP 요청을 보낼 때,
요청 헤더에 Cookie: 1678을 자동으로 포함시켜 전송함.
Amazon 서버는 이 쿠키 ID를 보고 사용자를 알아보고 사용자별 처리를 함.
서버 내부 동작
서버는 쿠키 ID에 해당하는 사용자 정보를 backend database에 저장해 둠.
쿠키를 통해 들어오는 요청마다 이 DB를 조회해서,
로그인 상태 유지, 장바구니 정보 불러오기, 사용자 맞춤 추천 등을 수행함.
일주일 후
쿠키 유효기간이 남아 있다면,
브라우저는 Cookie: 1678을 계속 포함시켜 서버에 전송.
서버는 이전처럼 똑같이 사용자 정보를 식별하고 서비스를 제공함.
Authorization (인증):
사용자가 로그인한 후, 쿠키에 저장된 세션 ID나 토큰을 통해
사용자가 인증된 상태임을 확인함
Shopping Carts (장바구니):
온라인 쇼핑몰에서 사용자가 선택한 상품 목록을 쿠키에 저장하여, 사용자가 사이트를 이동하거나 재방문할 때 장바구니의 내용이 유지되도록 함
Recommendations (추천):
사용자의 방문 기록이나 행동 정보를 쿠키에 저장하여,
개인화된 추천 서비스를 제공
User Session State (사용자 세션 상태):
ex. 웹 메일 서비스는 쿠키를 사용해
사용자의 로그인 상태와 세션 정보를 유지
사이트 내부 추적:
웹 사이트는 쿠키를 이용해 사용자의 활동, 선호, 방문 이력 등을 수집 가능. 이를 통해 사용자의 행동 패턴이나 관심사를 분석할 수 있음.
third party persistent cookies (Tracking Cookies):
제 3자 쿠키는 방문하는 사이트와는 별도로, 광고 네트워크나 분석 업체 등이 사용자의 동일한 쿠키 값을 여러 웹 사이트에서 추적 가능하게 함.
→ 사용자가 다양한 사이트를 방문할 때마다, 그 쿠키를 통해 사용자의 활동이 연결되어, 결국 사용자의 전체 인터넷 활동이 모니터링될 수 있음
bad cookie
: 클라이언트와 실제 서버 사이에 위치하여,
클라이언트의 요청을 대신 처리하거나 보조하는 역할을 하는 중간 서버
목적:
Web cache의 주요 목적은 웹 콘텐츠(ex. HTML 문서, 이미지, 동영상 등)를
미리 저장(캐싱)해 두어, 클라이언트가 동일한 콘텐츠를 요청할 때
원 서버에 직접 접근하지 않고도 빠르게 응답할 수 있도록 하는 것
동작 과정:
클라이언트의 요청
사용자가 웹 브라우저에서 URL을 입력하면,
브라우저는 요청을 프록시 서버에 보냄
프록시 서버의 캐시 검사
프록시 서버는 해당 요청에 대한 콘텐츠가
자신의 캐시에 저장되어 있는지 확인
캐시에 있음:
→ 저장된 콘텐츠를 클라이언트에게 바로 전달.
캐시에 없음:
→ 프록시 서버가 원 서버에 해당 리소스를 요청.
원 서버와의 통신
요청한 리소스를 원 서버에서 받으면, 프록시 서버는 받은 콘텐츠를
자신의 캐시에 저장하고, 클라이언트에게 전달.
이후 요청
클라이언트가 같은 리소스를 재요청할 경우, 프록시 서버에 이미 캐시되어 있다면 원 서버에 재요청하지 않고, 캐시된 콘텐츠를 즉시 제공.
웹 캐시는 단순히 중계 서버 역할을 넘어서,
클라이언트와 원 서버 사이에서 동시에 클라이언트와 서버의 역할을 수행.
클라이언트 역할:
원 서버에 요청을 보내고, 응답을 받는 역할을 대신함.
→ 웹 캐시는 원 서버의 콘텐츠를 요청하는 클라이언트로 동작
서버 역할:
이미 캐시에 저장된 콘텐츠를 클라이언트에게 제공하는 역할을 함.
→ 원 서버에 접근하지 않고, 로컬에 저장된 콘텐츠를 바로 응답하여 클라이언트의 요청을 처리.
일반적으로 웹 캐시는 ISP나 조직(대학, 회사, 가정용 ISP)에 의해 설치
클라이언트 응답 시간 감소
웹 캐시가 클라이언트에 더 가까이 위치해 있는 경우,
원 서버까지의 거리가 줄어들어 응답 속도가 빨라짐
기관의 외부 접속 링크(인터넷 회선)에 걸리는 트래픽 절감
콘텐츠 전달 효율성 향상
인터넷 상에는 많은 웹 캐시 서버들이 분산되어 있음.
→ 소규모 콘텐츠 제공자나 인프라가 부족한 사이트도,
웹 캐시를 활용하면 콘텐츠를 보다 빠르고 효율적으로 전달 가능