본문으로 이동
메뉴 여닫기
환경 설정 메뉴 여닫기
개인 메뉴 여닫기
로그인하지 않음
지금 편집한다면 당신의 IP 주소가 공개될 수 있습니다.

Socket Programming

소켓(Socket)이라는 통신 종단점을 만들어 프로세스끼리 네트워크로 데이터를 주고받는 프로그래밍 방식

1983년 BSD 유닉스가 내놓은 버클리 소켓(Berkeley Socket) 규격이 사실상 표준이 되었고, 윈도우의 Winsock도 이를 따른다. 소켓 하나는 IP 주소 + 포트 번호 + 프로토콜 로 식별된다.

서버 측 절차

편집 원본 편집
순서 함수 하는 일
1 socket() 소켓을 생성하고 파일 디스크립터를 돌려받는다
2 bind() 생성한 소켓에 IP 주소와 포트 번호를 붙인다
3 listen() 소켓을 수동 대기 상태로 바꿔 클라이언트의 접속 요청을 기다린다
4 accept() 대기 큐에 들어온 접속 요청을 꺼내 연결된 새 소켓을 만든다
5 read() / write() 데이터를 주고받는다
6 close() 연결을 끊는다

`listen()` 과 `accept()` 는 자주 혼동된다. 대기 상태로 만들어 요청을 기다리게 하는 것이 `listen()` 이고, 기다리다가 실제로 하나를 꺼내 연결을 완성하는 것이 `accept()` 다.

클라이언트 측 절차

편집 원본 편집
socket() → connect() → read()/write() → close()

클라이언트는 `bind()` 를 생략하는 것이 보통이다. 이 경우 운영체제가 사용하지 않는 포트를 자동으로 할당한다.

데이터 송수신 함수

편집 원본 편집
함수 하는 일 주로 쓰는 곳
connect() 클라이언트가 서버 주소로 연결을 요청한다 TCP 클라이언트
listen() 서버 소켓을 접속 대기 상태로 만든다 TCP 서버
send() / recv() 연결된 소켓으로 데이터를 보내고, 상대 프로세스가 보낸 데이터를 읽는다 연결형(TCP)
sendto() / recvfrom() 보낼 때마다 상대 주소를 지정하고, 받을 때 보낸 쪽 주소를 함께 얻는다 비연결형(UDP)
  • Linux 매뉴얼은 recv() 가 보통 연결된 소켓에만 쓰이며, 주소 인자를 NULL 로 준 recvfrom() 과 같다고 설명한다[1]
  • send() 도 연결된 상태에서만 쓰고, 목적지를 지정하는 것은 sendto() 이다[2]
  • 연결된 소켓에서는 read()/write() 도 recv()/send() 와 같이 쓸 수 있다. recv()·send() 는 여기에 플래그 인자를 더한 것이다
  • 스트림 소켓(SOCK_STREAM) : TCP를 쓴다. 연결 지향이고 순서와 신뢰성을 보장한다.
  • 데이터그램 소켓(SOCK_DGRAM) : UDP를 쓴다. 비연결형이고 순서·도착을 보장하지 않는다.
  • 로우 소켓(SOCK_RAW) : IP 헤더까지 직접 다룬다. 패킷 분석 도구나 ping 구현에 쓴다.

`listen()` 을 호출한 서버 소켓은 LISTEN 상태가 되고, 3-way 핸드셰이크가 끝나면 ESTABLISHED 상태의 소켓이 `accept()` 로 반환된다. 연결을 끊는 쪽은 TIME_WAIT 상태를 거친다. `netstat` 으로 확인할 수 있다.

시스템 연계에서

편집 원본 편집

두 시스템을 잇는 인터페이스 연계 기술 가운데 소켓은 간접 연계로 분류된다. 서버가 통신용 소켓을 만들어 포트를 할당하고, 클라이언트의 통신 요청이 오면 연결해 데이터를 주고받는다. 데이터베이스끼리 바로 잇는 DB Link 는 직접 연계다.

  1. ↑ 「recv(2) - Linux manual page」, man7.org, https://man7.org/linux/man-pages/man2/recv.2.html, 확인일: 2026-11-04.
  2. ↑ 「send(2) - Linux manual page」, man7.org, https://man7.org/linux/man-pages/man2/send.2.html, 확인일: 2026-11-04.