소켓(Socket) 완전 정리
같은 단어, 다른 의미 — 레이어별로 구분해서 이해하기
목차
1. 소켓의 세 가지 의미
① 물리적 소켓 (Hardware Layer)
"꽂는 구멍"이라는 의미의 소켓.
| 종류 | 설명 | 예시 |
|---|---|---|
| CPU 소켓 | 마더보드에 CPU를 꽂는 물리 슬롯 | 듀얼소켓 서버 |
| 네트워크 잭 소켓 | 이더넷 케이블을 꽂는 RJ-45 포트 | NIC의 LAN 포트 |
| 기타 물리 소켓 | 전원 소켓, GPU 슬롯, RAM 슬롯 등 | — |
공통 개념: 물리적 연결점 (꽂는 곳)
② OS / 커널 소켓 (Software — Kernel Layer)
네트워크 통신의 논리적 끝점(Endpoint).
- 소켓 = IP 주소 + Port 번호 의 조합
- 커널 내부에
struct sock구조체로 실체 존재 - 여기에 연결 상태, 송수신 버퍼 포인터, 프로토콜 정보가 담김
BSD 소켓 API 흐름:
socket() → bind() → listen() → accept() → send() / recv()
struct sock 주요 내용:
- IP / Port 정보
- 프로토콜 종류 (TCP / UDP)
- 송수신 버퍼 포인터
- 연결 상태 (
ESTABLISHED,CLOSE_WAIT등)
공통 개념: 네트워크 통신의 논리적 끝점 (IP + Port)
③ 프로그래밍 소켓 (Software — User Space Layer)
앱 개발자가 socket() 시스템 콜로 만드는 통신 채널 객체(fd).
| 종류 | 특징 | 용도 | 상수 |
|---|---|---|---|
| TCP 소켓 | 연결 지향, 신뢰성·순서 보장 | HTTP, DB, SSH | SOCK_STREAM |
| UDP 소켓 | 비연결, 빠름, 손실 가능 | 게임, 영상 스트리밍, DNS | SOCK_DGRAM |
| Unix Domain 소켓 | 같은 머신 내 IPC, 네트워크 스택 안 거침 | Nginx↔PHP-FPM, Docker 데몬 | 파일 경로로 식별 |
공통 개념: 앱이 OS에 요청해서 얻은 통신 채널 객체 (fd로 접근)
혼란의 원인 요약
물리 소켓 = 꽂는 구멍 (하드웨어)
OS 소켓 = IP+Port 끝점 (커널)
프로그래밍 소켓 = 통신 채널 객체, fd (유저스페이스)
2. 커널 소켓 레이어가 하는 일
앱이 send()를 호출하면 커널 소켓 레이어에서 다음 5단계가 순서대로 진행됩니다.
처리 흐름
| 단계 | 이름 | 설명 |
|---|---|---|
| ① | 시스템 콜 수신 & 권한 검증 | User→Kernel 모드 전환, fd 유효성·소켓 상태 확인 |
| ② | fd → sock 구조체 조회 | fd 번호로 struct socket / struct sock 찾기 |
| ③ | copy_from_user() | 앱 메모리 → 커널 영역으로 안전하게 복사 (보안 경계) |
| ④ | sk_buff (skb) 생성 | 패킷을 감싸는 커널 핵심 구조체 생성 |
| ⑤ | 프로토콜 핸들러 호출 | sock→ops→sendmsg()로 TCP/UDP 레이어 전달 |
sk_buff (skb) 구조체
커널 네트워크 스택의 핵심 자료구조. TCP→IP→드라이버 레이어가 이 skb를 서로 넘겨받으며 헤더를 덧붙임.
- 데이터 포인터
- 헤더 공간 (headroom)
- 프로토콜 메타데이터
- 체크섬 정보
- 타임스탬프
한 마디 요약: 커널 소켓 레이어 = User Space와 커널 네트워크 스택 사이의 경비원 겸 번역가
3. 웹소켓(WebSocket)의 정체
결론
WebSocket은 "소켓"이 아니라 "프로토콜"이다.
TCP 소켓 위에 올라간 애플리케이션 레이어 프로토콜 (HTTP와 같은 레이어).
일반 TCP 소켓 vs WebSocket
| 항목 | TCP 소켓 | WebSocket |
|---|---|---|
| 레이어 | OS (커널) 레이어 | 애플리케이션 레이어 |
| 추상화 수준 | 원시 통신 채널 | 프로토콜 (규칙 집합) |
| API | socket() / send() / recv() |
ws.send() / ws.onmessage() |
| 프로토콜 설계 | 개발자가 직접 | WebSocket 스펙이 정의 |
| 시작 방법 | 직접 TCP 연결 | HTTP 핸드셰이크 후 업그레이드 |
| 방향 | 양방향 가능 | 양방향 (full-duplex) |
WebSocket 연결 순서
1. 클라이언트 → HTTP GET 요청
Upgrade: websocket
Connection: Upgrade
2. 서버 → 101 Switching Protocols 응답
3. 이후 TCP 연결 유지하며 양방향 통신 시작
왜 이런 구조가 됐나?
브라우저는 보안상 앱이 BSD 소켓 API를 직접 사용할 수 없음.
브라우저가 내부적으로 TCP 소켓을 열고, 그 위에 WebSocket 프로토콜을 씌워서
앱에게 ws.send() / ws.onmessage() 라는 단순한 API로 노출.
4. 전체 아키텍처 다이어그램
4-1. User Space → Kernel → NIC 전체 흐름
flowchart TD
subgraph US["User Space"]
APP["애플리케이션nsend(fd, buf, len)"]
WSAPI["WebSocket APInws.send() / ws.onmessage()"]
end
subgraph KS["Kernel Space"]
SYSCALL["① 시스템 콜 수신 & 검증ntrap → 권한 확인"]
SOCKSTRUCT["② fd → struct sock 조회nIP · Port · 프로토콜 · 버퍼"]
COPY["③ copy_from_user()nUser 메모리 → Kernel 복사"]
SKB["④ sk_buff 생성n패킷 래퍼 구조체"]
TCP["⑤ TCP 레이어n세그멘테이션 · ACK · 혼잡제어"]
IP["⑥ IP 레이어n헤더 추가 · 라우팅 · TTL"]
NF["⑦ Netfilter / iptablesn방화벽 · NAT"]
DRV["⑧ NIC 드라이버nTX Ring Buffer · DMA 매핑"]
end
subgraph HW["Hardware"]
NIC["NICnDMA로 패킷 읽기 → 물리 신호 전송"]
end
APP -->|"시스템 콜"| SYSCALL
WSAPI -->|"내부적으로 TCP 소켓 사용"| SYSCALL
SYSCALL --> SOCKSTRUCT --> COPY --> SKB
SKB --> TCP --> IP --> NF --> DRV
DRV -->|"DMA"| NIC
4-2. 세 가지 소켓 의미 계층 구조
flowchart LR
subgraph HW["① 물리 소켓 (Hardware)"]
CPU_S["CPU 소켓n마더보드 슬롯"]
RJ45["RJ-45 소켓nLAN 포트"]
end
subgraph KN["② OS 소켓 (Kernel)"]
BSD["BSD 소켓nIP + Port 끝점"]
STRUCT["struct sockn커널 내부 구조체"]
end
subgraph US["③ 프로그래밍 소켓 (User Space)"]
TCP_S["TCP 소켓nSOCK_STREAM"]
UDP_S["UDP 소켓nSOCK_DGRAM"]
UNIX_S["Unix Domain 소켓nIPC · 파일 경로"]
WS["WebSocketn애플리케이션 프로토콜"]
end
BSD --> STRUCT
TCP_S -->|"내부 구현"| BSD
UDP_S -->|"내부 구현"| BSD
UNIX_S -->|"네트워크 스택 우회"| BSD
WS -->|"TCP 소켓 위에 올라감"| TCP_S
4-3. TCP 소켓 vs WebSocket 스택 비교
flowchart TD
subgraph TCP_STACK["TCP 소켓 스택"]
T_APP["앱n커스텀 프로토콜 직접 설계"]
T_BSD["BSD 소켓 APInsocket / send / recv"]
T_TCP["TCP"]
T_IP["IP"]
T_NIC["NIC"]
T_APP --> T_BSD --> T_TCP --> T_IP --> T_NIC
end
subgraph WS_STACK["WebSocket 스택"]
W_APP["앱nws.send / ws.onmessage"]
W_WS["WebSocket 프로토콜nHTTP Upgrade → full-duplex"]
W_BSD["BSD 소켓 APIn브라우저 내부에서 호출"]
W_TCP["TCP"]
W_IP["IP"]
W_NIC["NIC"]
W_APP --> W_WS --> W_BSD --> W_TCP --> W_IP --> W_NIC
end
4-4. RDMA vs 표준 TCP — 커널 bypass 원리
flowchart TD
subgraph STD["Standard TCP/IP Stack"]
S_APP["App BuffernUser Space"]
S_KERN["Kernel Socket Bufferncopy_from_user()"]
S_NIC["Standard Ethernet NIC"]
S_APP -->|"① copy"| S_KERN
S_KERN -->|"② copy"| S_NIC
end
subgraph RDMA_STACK["RDMA Stack (OS Bypass)"]
R_APP["App Buffernibv_reg_mr로 물리 주소 고정"]
R_BYPASS["Kernel ← Bypassed"]
R_HCA["RDMA NIC (HCA)nDMA 직접 접근"]
R_APP -->|"Direct Pathnmmap으로 QP 직접 접근"| R_HCA
R_BYPASS -. "우회됨" .-> R_HCA
end
subgraph RDMA_WHY["RDMA bypass 가능한 이유"]
W1["① Memory Registrationn물리 주소를 HCA에 미리 등록"]
W2["② Queue Pair mmapnNIC 큐를 User Space에 직접 노출"]
W3["③ DMA Zero-Copyn복사 없이 메모리 직접 전송"]
W1 --- W2 --- W3
end
본 문서는 Claude와의 대화를 기반으로 정리된 네트워크 소켓 개념 학습 자료입니다.
