11.1 클라이언트-서버 프로그래밍 모델
모든 네트워크 응용 프로그램은 클라이언트-서버 모델에 기초한다.
1. 클라이언트-서버 모델
- 하나의 애플리케이션은 서버 프로세스와 하나 이상의 클라이언트 프로세스로 구성된다
- 서버는 특정 자원을 관리하고, 자원을 조작하여 클라이언트에게 서비스를 제공한다
- 예) 웹 서버는 디스크에 저장된 파일을 관리하고 클라이언트 요청에 따라 반환
2. 트랜잭션 (Transaction)
클라이언트-서버 간 상호작용은 4단계 트랜잭션으로 구성
- 클라이언트가 서비스를 필요로 할 때, 서버에 요청(request) 보냄 (Client : ”스펀지밥 이미지 줘”)
- 서버는 요청을 받고, 해석, 자원을 조작 (Server : ”스펀지밥이 어딨는지 디스크에서 읽어보자..”)
- 서버가 응답을 클라이언트에게 전송 (Server: “오키 드림”)
- 클라이언트가 응답을 받아 처리 (Client: “화면에 띄움. 사용자야 이거야 스펀지밥”)
3. 중요 개념
- 클라이언트와 서버는 프로세스이다. (물리적 호스트가 아니다)
- 하나의 호스트에서 여러 클라이언트 및 서버가 동시 실행 가능
- 클라이언트와 서버가 어디 호스트에 있든 모델은 동일하게 적용
11.2 네트워크
1. 네트워크는 I/O 장치처럼 동작한다
- 호스트 입장에서는 네트워크는 단순한 입출력 장치이다
- 네트워크 어댑터를 통해 데이터를 전송, 수신.
- 시스템 버스를 통해 메모리와 직접 연결된다. (DMA 방식 사용)*
- ✅ 왜 DMA 방식일까?
2. 물리적 네트워크 계층 구조
🔽 하위 계층: LAN (Local Area Network)
- 가장 기본적인 단위는 LAN(Local Area Network). 이를 구현하기 위해 가장 많이 쓰이는 기술이 Ethernet
- Ethernet 구성 요소
- 이더넷 세그먼트 : 전선과 허브로 구성. 여러 호스트를 연결하는 물리적 전송 매체. (100 Mb/s or 1Gb/s 의 비트 대역폭을 가진다)
- 이더넷 어댑터 : 호스트(컴퓨터) 내부에 장착된 네트워크 인터페이스 장치 (NIC : Network Interface Card). 프레임 단위로 데이터를 송수신함. 전 세계적으로 고유한 48비트 MAC 주소를 갖는다.
- *<논리적 구성 요소 (구조/연결 관점)>**
- 허브 : 여러 호스트 세그먼트를 묶어주는 장치. 모든 포트로 받은 데이터를 복사하여 브로드캐스트.
- 브릿지 : 여러 세그먼트를 연결하며 목적지 MAC 주소 기반으로 데이터 전달을 효율화. 허브보다 더 높은 전선 대역폭을 가짐.
- <물리적 구성 요소 (하드웨어)>
- 프레임 : 네트워크에서 전달되는 데이터 전송 단위. 이더넷에서 어댑터는 데이터를 네트워크로 보내기 전에 프레임으로 포장한다.
- 프레임 구성
- 헤더 : 전송 제어용 정보 포함
- 목적지 MAC 주소
- 출발지 MAC 주소
- 페이로드 : 실제 전송할 데이터 (예, 웹 요청, 파일 조각 등)
- 이더넷 세그먼트를 브리지를 통해 연결. 대역폭을 효율적으로 사용할 수 있게 한다
- 왜 더 효율적?
- → 모든 프레임이 전체 네트워크에 퍼지지 않고 목적지로만 향함.
- → 전체 네트워크 충돌 가능성 감소 + 병렬 처리 가능성 증가
- → 여러 브리지-브리지 간 연결로 더 큰 LAN 구성할 수 있다.
🔼 상위 계층: 라우터를 통한 Inter-LAN 연결
- 라우터는 네트워크 간 연결을 구성한다. 각 LAN을 구분하고, IP 패킷을 적절한 LAN으로 전달한다
- 물리적으로 서로 다른 네트워크 기술( 이더넷 ↔ 와이파이 )을 라우터가 중개 가능
- WAN (Wide Area Network) : 여러 지역에 흩어진 네트워크를 라우터들이 Point-to-point 연결로 이어서 구성하는 네트워크
3. 프로토콜의 기능
- 프로토콜 : 여러 장치/시스템이 데이터를 주고 받을 수 있도록 약속된 “언어와 규칙”을 사용하는 것
- 기능 1 : 명명법 (”어디로, 누구에게 가!”)
- 어떤 호스트나 프로세스를 전 세계적으로 고유하게 식별하기 위한 시스템
- MAC 주소 : 이더넷 어댑터의 고유한 48비트 주소 → 로컬 LAN 식별용
- IP 주소 : 전 세계적으로 유일한 32비트 주소 (IPv4 기준) → 인터넷 전체 범위에서 호스트 식별
- 포트 번호 : 호스트 내에서 실행 중인 응용 프로세스 식별
- 기능 2 : 전달 기법 (”어떻게 갈까?”)
- IP 패킷 : IP 계층에서 목적지 IP 주소 기반으로 라우팅 수행
- 라우터 : IP 헤더를 보고 다음 홉 (next hop) 결정
- 링크 계층 : 목적지 MAC 주소를 통해 실제 데이터 전달
4. 데이터의 이동 과정
internet에서 데이터가 호스트 A에서 호스트 B로 이동하는 과정에는 다음과 같은 단계가 있다.
- 클라이언트에서 커널로 데이터 복사
- 클라이언트 응용 프로그램이 시스템 콜을 호출
- 사용자 버퍼의 데이터를 커널 버퍼로 복사
- 데이터 캡슐화 및 LAN1 프레임 생성
- 커널의 프로토콜 소프트웨어가..
- 데이터에 IP 헤더 추가 (→ 인터넷 패킷 생성)
- IP 패킷에 LAN1 프레임 헤더 추가 (→ 목적지 MAC은 라우터)
- 이더넷 프레임 완성 → 어뎁터에 전달
- 커널의 프로토콜 소프트웨어가..
- LAN1 어댑터가 네트워크로 전송
- LAN1 어댑터가 프레임을 전기 신호로 네트워크에 전송
- 라우터가 프레임 수신
- 라우터의 LAN1 어댑터가 수신 → 프로토콜 소프트웨어에 전달
- 라우팅 결정 및 프레임 재구성
- 라우터가 IP 헤더를 읽고 목적지 IP를 확인
- 라우팅 테이블을 조회해 다음 홉이 LAN2임을 결정
- LAN1 프레임 헤더 제거 → LAN2 프레임 헤더 생성 (목적지 MAC은 Host B)
- 어댑터로 전달
- 라우터의 LAN2 어댑터가 새 프레임을 네트워크로 전송
- Host B가 프레임 수신 → 프로토콜 소프트웨어로 전달
- 데이터 최종 전달
- 프로토콜 소프트웨어가 프레임 헤더와 IP 헤더 제거
- 나머지 순수 데이터를 응용 프로세스의 가상 주소 공간으로 복사 (서버가 system call로 읽음)
11.3 글로벌 IP 인터넷
TCP/IP 프로토콜
- 인터넷은 TCP/IP 프로토콜 스택이라는 계층적 프로토콜 체계에 의해 운영된다
- 각 계층은 상하 인접 계층과만 통신.
- 캡슐화를 통해 데이터 전달
계층 | 주요 프로토콜 | 기능 |
응용 계층 (Application) | HTTP, FTP, DNS 등 | 사용자 수준 서비스 제공 |
전송 계층 (Transport) | TCP, UDP | 프로세스 간 데이터 전송, 오류 제어 |
인터넷 계층 (Internet) | IP | 호스트 간 패킷 라우팅 및 주소 지정 |
네트워크 엑세스 계층 (Network Access) |
이더넷, PPP 등 | 동일 네트워크 내 프레임 전송 |
✅ TCP vs UDP
구분 | TCP | UDP |
신뢰성 | Reliable | Unreliable |
연결성 | Connection-oriented | Connection less |
재전송성 | 재전송 요청함 (오류 및 패킷 손실 시) | 재전송 없음 |
특징 | Flow control을 위해 windowing 사용 | 신뢰성을 보장하지 않지만, 고속 데이터 전송 |
용도 | 신뢰성이 필요한 통신 (HTTP, SMTP, FTP) |
총 패킷수가 적은 통신 (스트리밍, 실시간 게임, DNS 요청) |
TCP : 전화. 상대방 번호를 알아야 전화 걸 수 있음. 동일하게 상대방 IP 주소와 Port 번호를 알아야함. 그리고 전화 걸어도 받을때까지 대기해야함.
UDP : 편지. 편지가 왔는지 안왔는지 우편함 열어봐야 앎. 데이터가 와도, UDP 소켓을 통해서 자신의 포트를 열어봐야 데이터가 도착했는지 알 수 있음.
11.3.1 IP 주소
- 인터넷의 각 호스트는 고유한 32비트 IP 주소를 갖늗나
- 표현 방식 : 점으로 구분된 십진수 (dotted-decimal)
- 내부적으로는 네트워크 바이트 순서(big-endian)의 4바이트 이진수
- 변환 함수
inet_pton
: 문자열 → 이진 IPinet_ntop
: 이진 IP → 문자열- → 시스템 간 IP 주소를 표준화된 형식으로 주고 받기 위해 필수
- Big Endian vs Little Endian
- 여러 바이트로 구성된 데이터를 메모리에 저장할 때, 바이트 순서를 어떻게 정할 것인가 정하는 방식
- 특히 멀티바이트 숫자 (2, 4, 8바이트 등)을 저장하거나 전송할 때 중요
- 네트워크 전송은 항상 Big Endian 사용하지만, Intel CPU(x86)은 내부적으로 Little Endian 사용
- → 그래서 데이터를 네트워크로 보낼때
htonl()
(host to network long), 받을때는ntohl()
(network to host long) 같은 함수로 바이트 순서를 변환한다.
구분 | Big Endian | Little Endian |
저장 방식 | 가장 큰 바이트(상위 바이트)를 먼저 저장 | 가장 작은 바이트(하위 바이트)를 먼저 저장 |
사람에게 익숙한 방식 | 예 (왼→오 읽기) | 아니오 (오→왼 읽기) |
사용 예 | 네트워크 (IP, TCP 등), 일부 RISC CPU | x86 계열 CPU (Intel, AMD 등) |
11.3.2 인터넷 도메인 이름
- 도메인 이름이란?
- 사람은 숫자로 된 IP주소 대신 기억하기 쉬운 문자열 주소를 사용하기 위해 만듬
- www.google.com
- 도메인 이름의 계층 구조
- 루트 (.) : 최상위 도메인 (com, edu, org 등)
- 2차 도메인 : google
- 3차 이하 도메인 : mail
- 최종 : mail.google.com
- ⇒ 모두 google.com 이라는 2차 도메인 아래에서 서브 도메인 (mail, maps, drive)으로 구분됨
Root (.)
└── com
└── google
└── mail
🔁 도메인 ↔ IP 매핑: DNS 시스템
- 예전에는
HOSTS.TXT
라는 수동 파일로 관리 - 현재는 DNS (Domain Name System)라는 전 세계 분산 데이터베이스가 담당
- 입력 : 도메인 이름
- 출력 : 해당하는 하나 이상의 IP 주소
- 하나의 도메인 → 여러 IP 가능
- 여러 도메인 → 동일 IP 가능. 즉, 일대다 / 다대일 매핑 모두 가능
🔁 localhost
- 각 인터넷 호스트는 지역적으로 정의된 도메인 이름인 localhost를 가지고 있고
- 항상 루프백 주소 127.0.0.1 에 매핑된다
- nslookup (domain name) 으로 IP 주소 확인 가능
11.3.3 인터넷 연결
인터넷 연결이란?
- 호스트(컴퓨터)가 인터넷에 접속하려면, ISP (인터넷 서비스 제공자)를 통해 라우터에 연결됨
- 라우터는 하나 이상의 네트워크 인터페이스(어댑터)를 통해 외부 인터넷과 통신
- TCP 기반 통신은 신뢰성 있는 바이트 스트림을 양방향으로 주고받는 방식
- → 양쪽 모두 읽기/쓰기가 가능하여 완전한 양방향 통신(Full-Duplex)
연결 방식
- 로컬 네트워크 → 라우터
- 사용자 컴퓨터는 이더넷 또는 무선 네트워크를 통해 로컬 라우터에 연결
- 라우터 → ISP 백본 → 인터넷
- 실제 전기 신호/패킷이 지나가는 물리적 경로 → 데이터를 어디로 보낼지 결정
- 라우터는 ISP 핵심망 (backbone)에 연결됨
- 중간에 있는 여러 라우터를 거쳐 데이터가 목적지 호스트에 전달됨
- 소켓과 종단점
- 애플리케이션 수준의 논리적 연결 관계 → 데이터를 누구에게 보낼지 식별
- 소켓 : 프로세스가 네트워크 통신을 하기 위해서 사용하는 추상적 I/O 객체
- 소켓의 종단점(endpoint)은 아래 정보로 유일하게 식별됨
- IP 주소
- 포트 번호
(cliaddr : cliport, servaddr : servport)
: (클라이언트 IP : 클라이언트 포트, 서버 IP : 서버 포트)- 이 때 클라이언트가 열어주는 포트는 커널이 할당한 단기 포트 (ephemeral port) : 49152 ~ 65535 범위
- 서버 포트는 지정된 고정 포트 : 80 (HTTP), 443 (HTTPS), 22 (SSH)
- ✅ 왜 서버는 고정 포트를 사용하고, 클라이언트는 단기 포트를 사용하는가?
- 서버는 외부에서 요청을 “들어야” 하기 때문에 항상 고정된 포트에 바인딩(bind) 필요
- 클라이언트는 그럴 필요 없음.
- 서버는 114라는 고객센터 번호를 열어두고, 클라이언트의 요청을 대기함→ 심지어 클라이언트가 한명일수도 여러명일수도 모름!
- → 하지만 클라이언트는 서버를 찾아가려면, 꼭 114라는 번호를 누르고 찾아가는거임. 다른 번호로 전화 걸면 다른 서버거나, 엇? 여기 그런데 아닌데요 라며 에러를 띄움 (Connection refused)
- → 클라이언트가 언제, 어떤 번호로 전화할지 모름!
11.4 소켓 인터페이스
소켓 인터페이스란?
- 네트워크 응용 프로그램을 만들기 위한 시스템 호출 API 집합
- 파일 I/O와 유사하게 작동하는 추상화된 방식
11.4.1 소켓 주소 구조체
- 소켓은 커널 입장에서의 “통신 종단점”
- 소켓은 통신을 위한 파일 디스크립터처럼 사용되는 객체이다
- 프로그램 관점에서는 소켓은 통신을 위한 식별자를 가진 파일처럼 다뤄진다 (read, write, close 등)
/*IP Socket address structure*/
struct sockaddr_in{
uint16_t sin_family; // 주소 체계 (AF_INET : IPv4)
uint16_t sin_port; // 포트 번호 (네트워크 바이트 순서, big endian (16비트))
struct in_addr sin_addr; // IP 주소 (32비트, 네트워크 바이트 순서)
unsigned char sin_zero[8]; // 패딩용 바이트 (구조체 크기 맞춤용으로 사용안함)
}
/*Generic socket address structure (for connect, bind, accept)*/
struct sockaddr{
uint16_t sa_family; // Protocol family
char sa_data[14]; // Address data
}
- 왜 이렇게 설계되었나?
- 초기 C언어에는 void* 타입이 없어서
- 다형성을 흉내내기 위해 범용 구조체를 사용
- 왜 포인터로 전달하는가?
- 아래 함수에서 IPv4, IPv6, Unix 도메인 소켓 등 다양한 주소 체계를 지원해야 하기 때문에, 구체적인 주소 구조체(
sockaddr_in
,sockaddr_in6
,sockaddr_un
)가 아닌, 공통 상위 타입struct sockaddr *
를 인자로 받음. - 따라서 우리가 사용하는
struct sockaddr_in
을 전달하려면 명시적으로struct sockaddr *
로 형변환해야 합니다. - C에서는
struct sockaddr_in *
→struct sockaddr *
로 암시적 형변환이 되지 않기 때문에, 컴파일러 오류 없이 넘기기 위해 명시적 캐스팅이 필요합니다
- 아래 함수에서 IPv4, IPv6, Unix 도메인 소켓 등 다양한 주소 체계를 지원해야 하기 때문에, 구체적인 주소 구조체(
11.4.2 ~ 4.6 구현 함수
- socket()
- 소켓 생성 함수
- 반환된 소켓은 파일 디스크립터처럼 사용
- 아직 연결되거나 바인딩되지 않은 초기 상태의 소켓
#include <sys/types.h> #include <sys/socket.h> int socket(int domain, int type, int protocol); // Return : nonnegative descriptor if OK, -1 on error
- domain : IPv4, IPv6 설정
- type : TCP (SOCKET_STREAM), UDP(SOCKET_DGRAM)
- protocol : IP 사용시 0
- connect()
- 클라이언트용 함수
- 서버의 IP와 포트 번호가 담긴 주소 구조체를 인자로 받아 연결을 시도
- 연결이 성공하면 해당 소켓은 양방향 데이터 송수신 가능 상태
#include <sys/socket.h> int connect(int clientid, const struct sockaddr *addr, socklen_t addrlen); // Return 0 if OK, -1 on error
- clientid : 클라이언트의 소켓 디스크립터
- addr : 서버의 IP 주소와 Port 번호를 담고있는 주소 구조체의 포인터. sockaddr*로 형변환 하여 전달.
- addrlen : addr 구조체의 크기 (주소 길이)
- bind()
- 서버용 함수
- 소켓에 IP 주소와 포트 번호를 명시적으로 연결
- 서버는 고정된 포트에서 클라이언트의 요청을 받기 위해 사용
#include <sys/socket.h> int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); // Returns 0 if OK, -1 on error
- sockfd : socket()의 리턴값
- listen()
- 서버가 bind로 주소를 지정한 후, 이 소켓을 클라이언트의 연결 요청을 받을 수 있도록 설정
- backlog 인자로 대기열 크기를 설정 (연결 요청을 저장하는 큐의 길이 = 연결 가능한 클라이언트 수)
#include <sys/socket.h> int listen(int sockfd, int backlog); // Return 0 if OK, -1 on error
- 서버는 accept()를 호출하고 대기 상태로 들어감
- 이때 listenfd 는 리스닝 소켓
- 아직 클라이언트 연결 요청이 없으니 블로킹 상태에 들어감.
- 클라이언트가 connect()을 호출하여 연결 요청
- 클라이언트가 서버의 IP 및 포트로 연결 시도
- 커널은 이 요청을 리스닝 소켓 큐에 추가
- 서버 accept() 함수가 연결을 수락
- 커널은 클라이언트 요청을 수락
- 새로운 연결 소켓(connfd)을 생성
- 클라이언트 주소 정보(addr)을 채우고 connfd 반환
- ✅ 왜 accept()는 클라이언트가 없으면 블로킹 되는가?
- 클라이언트 요청이 없는데, connfd를 돌려줄 수 없으니까! → 그냥 연결 올때까지 대기하는거임
- ✅ 리스닝 소켓 큐는 메모리 어디에 위치하나?
- 운영 체제 메모리는 사용자 공간과 커널 공간으로 나뉨.
- 결론: 커널 공간의 소켓 자료구조 내 존재한다.
- 운영체제 메모리accept()
-
- ✅ 왜 accept()는 새 소켓을 만드는가?
- 연결마다 독립된 입출력 채널이 필요하다.
- 그래야 서버가 여러 클라이언트를 동시에 or 순차적으로 처리할 수 있다
- ✅ 왜 accept()는 새 소켓을 만드는가?
- 연결마다 독립된 입출력 채널이 필요하다.
- 그래야 서버가 여러 클라이언트를 동시에 or 순차적으로 처리할 수 있다.
- 연결 수락되면 fork() 로 자식 프로세스 생성
- 자식은 새로 생성된 connfd만 가지고 클라이언트 처리서버의 구조에 따라 새 소켓을 만드는 방식의 차이가 있다! → 본질은 똑같다.
- 🔹 프로세스 기반 서버
- 연결 수락되면 fork() 로 자식 프로세스 생성
- 자식은 새로 생성된 connfd만 가지고 클라이언트 처리
- 🔹 스레드 기반 서버
- 연결 수락되면 pthread_create() 등으로 새 스레드 생성
- 새 스레드는 넘겨받은 connfd로 클라이언트 요청 처리
- ✅ 왜 accept()는 새 소켓을 만드는가?
11.5 웹 서버
11.5.1 웹 기초
- HTTP 개요 : 웹 클라이언트와 서버는 HTTP라는 텍스트 기반 애플리케이션 계층 프로토콜을 사용해 통신한다
- HTML과 웹의 차별성 : FTP와 달리 HTML을 기반으로 텍스트와 그래픽의 표시 방법을 지정하고, 하이퍼링크를 통해 인터넷 상의 다른 자원과 연결될 수 있다.
11.5.2. 웹 컨텐츠
- 콘텐츠의 개념 : 웹 클라이언트와 서버에게 “콘텐츠란” MIME (Multipurpose Internet Mail Extensions) 타입이 지정된 바이트의 시퀀스이다. MIME 타입은 콘텐츠 형식을 설명하는 식별자이다. (text/html, image/jpeg)
- 콘텐츠 제공 방식 2가지 :
- 정적 콘텐츠 (Static Content) : 서버가 디스크 파일을 읽어서 클라이언트에 반환 (Html, 이미지 파일)
- 동적 콘텐츠 (Dynamic Content) : 실행 파일을 실행한 결과물 (런타임에 만든 출력)을 클라이언트에 반환 (CGI 프로그램 실행 결과
- 서버의 해석 규칙 :
- 정적/동적 콘텐츠를 구분하는 표준 규칙은 없으며, 서버가 내부 규칙을 정한다
/
은 루트 디렉터리가 아닌 해당 서버의 콘텐츠 홈 디렉토리를 의미한다. 그래서 단독 요청은 보통/index.html
같은 기본 페이지로 확장된다
11.5.3 HTTP Transaction
- HTTP 요청 구조 :
- 요청 라인 : GET / HTTP/1.1 형태로 구성 (메서드, URI, 버전)
- 헤더 : Host 는 HTTP/1.1에서 Required 헤더
- 빈줄 : 헤더의 끝을 나타냄
- HTTP 응답 구조 :
- 응답 라인 : HTTP/1.0 200 OK
- 응답 헤더 : MIME 타입, 콘텐츠 길이 등 포함
- 빈줄 : 응답 헤더의 끝
- 본문 : 요청된 콘텐츠
- 요청 메서드 : GET, POST, PUT, DELETE 등 다양한 메서드가 있으나 이 절에서는 GET만 설명.
GET / HTTP/1.1
: index.html을 리턴하라는 뜻이며, 서버에게 나머지 요청들이 HTTP/1.1 포맷임을 알린다.
- HTTP 버전 : HTTP/1.0와 HTTP/1.1은 호환 가능하지만, HTTP/1.1은 캐싱, 보안, 지속 연결 등 고급 기능을 지원한다
- 헤더 활용 : 특히 Host 헤더는 프록시 서버가 요청된 콘텐츠의 도메인을 식별할 수 있게 해준다
Host : www.aol.com
: HTTP/1.1 부터 필수로 요구되는 헤더로, 프록시 캐시가 사용한다.- → 필요 이유
- 하나의 IP 주소에 여러 도메인을 운영하는 경우, 서버는 host 헤더를 보고 어떤 웹사이트의 리소스를 요청했는지 판단한다
- 클라이언트 ↔ 프록시 서버 ↔ 웹 서버 구조에서, 프록시는 Host 헤더를 참조해 어느 웹 서버의 리소스를 요청한 것인지 판단
- 여러 프록시가 프록시 체인으로 연결될 수 있고, 각각 Host 정보를 사용하여 요청을 전달.
- 프록시 체인을 왜 쓸까?
- 보안 강화 : 여러 프록시 서버를 거치면서 원본 클라이언트 IP 주소를 숨길 수 있음. Tor 네트워크
- 접속 제어 및 모니터링 : 체인 중간에 위치한 프록시 서버에서 접속 로그를 기록하고, 사용자 요청을 검사하여 보안 정책 적용 가능. (악성 코드 차단, 접근 금지 사이트 필터링 등)
- 캐싱 효율 증가 : 상위 프록시 서버가 자주 요청되는 리소스를 캐시해두고 같은 콘텐츠를 여러 사용자에게 빠르게 제공
- 네트워크 경로 최적화 : 일부 프록시 서버는 더 빠른 경로를 찾아 지연 시간 줄임
- 접속 우회 : 국가나 조직 차원에서 차단된 사이트도 외부에 있는 프록시 서버를 경유하여 접속 가능
11.5.4 동적 컨텐츠의 처리
- 클라이언트 → 서버로 인자 전달 방법
- GET 방식 : URI의 ? 이후에 인자 전달, 인자들을 &로 구분
- 예 :
/cgi-bin/adder?15000&213
- 공백은
%20
으로 인코딩
- 예 :
- GET 방식 : URI의 ? 이후에 인자 전달, 인자들을 &로 구분
- 서버 → CGI 프로그램 (자식 프로세스)으로 인자 전달
- 서버는 fork로 자식 프로세스를 만들고 execve로 CGI 프로그램을 실행함
- 실행 전, 환경변후 QUERY_STRING 에 URI 인자를 저장해서 프로그램이 getenv() 로 읽게 함
- QUERY_STRING :
15000&213
- 기타 정보 전달
- CGI 표준은 다양한 환경 변수 지원
- REQUEST_METHOD : GET, POST
SERVER_PORT
,REMOTE_ADDR
,CONTENT_TYPE
,CONTENT_LENGTH
등
- CGI 표준은 다양한 환경 변수 지원
- 출력은 어떻게 전달되는가?
- CGI 프로그램은 표준 출력(stdout)에 콘텐츠 출력
- 서버는 dup2를 사용해 stdout을 클라이언트 소켓으로 리다이렉트
- 프로그램이 출력하는 모든 HTML은 클라이언트로 직접 전송됨
- 응답 헤더 처리
- 부모 서버는 자식이 어떤 콘텐츠를 출력할지 모름
- CGI 프로그램이 Content-Type, Content-length 등 응답 헤더를 직접 작성
'IT 성장기 (교육이수) > 크래프톤정글 (2025.03-07)' 카테고리의 다른 글
[PintOS] Project 1 : Priority Scheduling 구현 (0) | 2025.05.19 |
---|---|
[PintOS] Project 1 : Alarm Clock 구현 (0) | 2025.05.19 |
[자료구조] Red-Black Tree (0) | 2025.04.24 |
[CS] C : Malloc과 동적 메모리 (0) | 2025.04.21 |
[CS] 가상화 (0) | 2025.04.17 |