OSI (Open Systems Interconnection) 7계층 모델은 네트워크 통신의 표준 모델

| 계층 | 이름 | 역할 | 예시 |
|---|---|---|---|
| 7 | Application Layer (응용 계층) | 사용자 인터페이스 제공 | HTTP, SMTP, FTP, DNS |
| 6 | Presentation Layer (표현 계층) | 데이터 암호화, 압축, 변환 | SSL/TLS, JPEG, MPEG |
| 5 | Session Layer (세션 계층) | 세션 관리 및 동기화 | NetBIOS, RPC |
| 4 | Transport Layer (전송 계층) | 신뢰성 있는 데이터 전송 | TCP, UDP |
| 3 | Network Layer (네트워크 계층) | 라우팅 및 패킷 포워딩 | IP, ICMP, ARP |
| 2 | Data Link Layer (데이터 링크 계층) | 프레임 단위 전송 | Ethernet, PPP |
| 1 | Physical Layer (물리 계층) | 비트 단위 전송 | 케이블, 허브, 리피터 |
TCP/IP 모델은 실제 인터넷에서 사용되는 프로토콜 스택입니다.
| 계층 | 이름 | OSI 대응 | 역할 |
|---|---|---|---|
| 4 | Application Layer | 5-7계층 | 응용 프로그램 간 통신 |
| 3 | Transport Layer | 4계층 | 프로세스 간 통신 |
| 2 | Internet Layer | 3계층 | 호스트 간 통신 |
| 1 | Network Access Layer | 1-2계층 | 물리적 네트워크 접근 |

클라이언트-서버 모델은 네트워크 서비스를 제공하는 아키텍처 패턴
소켓(Socket)은 네트워크 통신의 끝점(endpoint)으로, 프로세스 간 통신을 위한 인터페이스


/* IPv4 전용 소켓 주소 구조체 */
struct sockaddr_in {
uint16_t sin_family; /* 주소 체계 (항상 AF_INET) */
uint16_t sin_port; /* 포트 번호 (네트워크 바이트 순서) */
struct in_addr sin_addr; /* IP 주소 (네트워크 바이트 순서) */
unsigned char sin_zero[8]; /* 패딩 (struct sockaddr와 크기 맞추기용) */
};
/* 범용 소켓 주소 구조체 (connect, bind, accept 등에서 사용) */
struct sockaddr {
uint16_t sa_family; /* 주소 체계 (AF_INET, AF_UNIX 등) */
char sa_data[14]; /* 주소 정보 (실제 내용은 구조체마다 다름) */
};
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
domain: 주소 패밀리 (AF_INET, AF_INET6)type: 소켓 타입 (SOCK_STREAM, SOCK_DGRAM)(TCP, UDP)protocol: 프로토콜 (보통 0)서버가 자신이 사용할 IP/포트 번호를 커널에 등록하는 함수
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd: socket()으로 만든 디스크립터addr: 서버가 사용할 주소 정보addrlen: 그 주소 구조체 크기#include <sys/socket.h>
int listen(int sockfd, int backlog);
sockfd: 소켓 파일 디스크립터backlog: 대기 큐 크기sockfd: bind까지 끝낸 소켓backlog: 커널이 대기열에 허용할 최대 요청 수커널은 기본적으로 소켓을 클라이언트용(active)으로 생각하므로,
서버로 사용하려면 listen()으로 수동 대기(passive) 모드로 바꿔야 함.
→ 이후 클라이언트가 connect()로 연결 요청 시 대기열에 쌓임
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
listenfd: listen() 호출된 디스크립터addr: 연결 요청을 보낸 클라이언트 주소가 담김addrlen: 주소 크기✅ 반환값: 새롭게 만들어진 통신용 소켓 (connfd)이 소켓은 클라이언트와 실제 통신을 하기 위해 사용
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
clientfd: socket()이 반환한 디스크립터addr: 서버 주소 정보 (보통 sockaddr_in 캐스팅해서 사용)addrlen: 주소 구조체 크기#include <sys/socket.h>
int close(int fd);
// 1. 소켓 생성
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
// 2. 주소 설정
struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
// 3. 바인딩
bind(server_fd, (struct sockaddr *)&address, sizeof(address));
// 4. 리스닝
listen(server_fd, 3);
// 5. 연결 수락
int client_fd = accept(server_fd, (struct sockaddr *)&address, &addrlen);
// 1. 소켓 생성
int sock = socket(AF_INET, SOCK_STREAM, 0);
// 2. 서버 주소 설정
struct sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr);
// 3. 연결
connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));


파일 디스크립터(File Descriptor)는 운영체제가 파일이나 소켓 등의 입출력 자원을 식별하기 위해 사용하는 정수값
| FD | 이름 | 설명 |
|---|---|---|
| 0 | stdin | 표준 입력 |
| 1 | stdout | 표준 출력 |
| 2 | stderr | 표준 오류 |
read(), write(), close() 등Process A FD Table:
FD 0 -> stdin
FD 1 -> stdout
FD 2 -> stderr
FD 3 -> socket
FD 4 -> file.txt
FD 5 -> socket (client connection)
// 읽기
ssize_t read(int fd, void *buf, size_t count);
// 쓰기
ssize_t write(int fd, const void *buf, size_t count);
// 닫기
int close(int fd);
// 복제
int dup(int oldfd);
int dup2(int oldfd, int newfd);
socket(AF_INET, SOCK_STREAM, 0); // TCP 소켓
socket(AF_INET, SOCK_DGRAM, 0); // UDP 소켓
// 데이터 전송
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
// 데이터 수신
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
| 특성 | Stream Socket (TCP) | Datagram Socket (UDP) |
|---|---|---|
| 연결 | 연결 지향 | 비연결형 |
| 신뢰성 | 보장 | 보장 안됨 |
| 속도 | 상대적으로 느림 | 빠름 |
| 오버헤드 | 높음 | 낮음 |
| 순서 보장 | 보장 | 보장 안됨 |
| 데이터 크기 | 제한 없음 | 제한 있음 |
| 사용 사례 | 웹, 파일 전송 | 실시간 통신 |

CGI는 웹 서버가 외부 프로그램을 실행하여 동적 웹 페이지를 생성하는 인터페이스
REQUEST_METHOD=GET
QUERY_STRING=name=value&key=data
CONTENT_TYPE=application/x-www-form-urlencoded
CONTENT_LENGTH=25
HTTP_USER_AGENT=Mozilla/5.0...
REMOTE_ADDR=192.168.1.100
#!/usr/bin/env python3
import os
import cgi
print("Content-Type: text/html\n")
print("<html><body>")
print("<h1>Hello CGI!</h1>")
print(f"<p>Request Method: {os.environ.get('REQUEST_METHOD')}</p>")
print("</body></html>")
웹 서버는 HTTP 요청을 처리하고 웹 페이지를 제공하는 소프트웨어
Client Request → Web Server →
↓
Static File? → Send File
↓
CGI Script? → Execute CGI
↓
Error → Send Error Page

MIME (Multipurpose Internet Mail Extensions) Type은 파일의 형식을 나타내는 표준 방법
type/subtype
| 파일 형식 | MIME Type |
|---|---|
| HTML | text/html |
| CSS | text/css |
| JavaScript | text/javascript |
| JSON | application/json |
| XML | application/xml |
| 이미지 (JPEG) | image/jpeg |
| 이미지 (PNG) | image/png |
| 이미지 (GIF) | image/gif |
| application/pdf | |
| 압축파일 (ZIP) | application/zip |
| 바이너리 | application/octet-stream |
Content-Type: text/html; charset=utf-8
Content-Type: application/json
Content-Type: image/png
# Apache .htaccess
AddType text/html .html
AddType text/css .css
AddType text/javascript .js
AddType application/json .json
HTTP (HyperText Transfer Protocol)는 웹에서 데이터를 주고받기 위한 프로토콜
GET /index.html HTTP/1.1
Host: www.example.com
POST /submit HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13
name=John&age=30
PUT /users/123 HTTP/1.1
Host: www.example.com
Content-Type: application/json
{"name": "John", "age": 30}
DELETE /users/123 HTTP/1.1
Host: www.example.com
HEAD /index.html HTTP/1.1
Host: www.example.com
OPTIONS /api/users HTTP/1.1
Host: www.example.com
Cache-Control: no-cache
Connection: keep-alive
Date: Mon, 23 May 2023 12:00:00 GMT
Accept: text/html,application/xhtml+xml
Accept-Language: ko-KR,ko;q=0.9,en;q=0.8
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Host: www.example.com
Authorization: Bearer token123
Content-Type: text/html; charset=UTF-8
Content-Length: 1234
Content-Encoding: gzip
Server: Apache/2.4.41
Set-Cookie: sessionid=abc123; Path=/; HttpOnly
Content-Type: application/json
Content-Length: 500
Content-Encoding: gzip
Last-Modified: Mon, 23 May 2023 12:00:00 GMT
ETag: "abc123"
GET /index.html HTTP/1.1 ← 요청 라인
Host: www.example.com ← 헤더
User-Agent: Mozilla/5.0
Accept: text/html
← 빈 줄
← 메시지 본문 (선택사항)
HTTP/1.1 200 OK ← 상태 라인
Content-Type: text/html ← 헤더
Content-Length: 1234
Server: Apache/2.4.41
← 빈 줄
<html> ← 메시지 본문
<head><title>Example</title></head>
<body>Hello World!</body>
</html>

프록시(Proxy)는 클라이언트와 서버 사이에서 중개 역할을 하는 서버
Client → Forward Proxy → Server
Client → Reverse Proxy → Server
// 클라이언트 → 프록시 요청
GET http://www.example.com/index.html HTTP/1.1
Host: www.example.com
Proxy-Connection: keep-alive
// 프록시 → 서버 요청
GET /index.html HTTP/1.1
Host: www.example.com
Connection: keep-alive
// 클라이언트 → 프록시 터널 요청
CONNECT www.example.com:443 HTTP/1.1
Host: www.example.com:443
// 프록시 → 클라이언트 응답
HTTP/1.1 200 Connection established
// 이후 암호화된 데이터 터널링
네트워크 프로그래밍의 핵심 개념들을 정리: