소켓(Socket)
소켓은 네트워크 상에서 수행되는 두 프로그램 간의 양방향 통신 링크의 한쪽 끝 단을 의미한다.
소켓은 프로세스가 네트워크를 통해 데이터를 송수신하기 위한 실제적인 창구 역할을 한다.
운영체제는 소켓을 통해 네트워크 통신을 위한 인터페이스를 제공한다.
소켓의 구성 요소
소켓은 다음 세 가지 요소로 구성된다:
- 프로토콜: 데이터 전송을 위한 표준 집합 규칙 (예: TCP/IP, UDP/IP)
- IP 주소: 서버 또는 클라이언트의 주소
- 포트 번호: 통신을 사용하는 애플리케이션을 식별하는 번호
소켓의 특징
- 프로토콜, IP 주소, 포트 번호로 정의된다.
- 서버 소켓과 클라이언트 소켓으로 구분된다.
- 실시간 데이터 전송에 적합하다.
소켓 통신의 장점
- 실시간 양방향 통신이 가능하다.
- 서버와 클라이언트 간 지속적인 연결을 유지할 수 있다.
소켓 통신의 단점
- HTTP 통신에 비해 구현이 복잡할 수 있다.
- 지속적인 연결 유지로 인한 리소스 소비가 있을 수 있다.
소켓의 종류
소켓은 크게 두 가지 유형으로 나눌 수 있다:
- 스트림 소켓(SOCK_STREAM)
- TCP를 사용하는 연결 지향형 소켓
- 연결 지향적이며 양방향으로 바이트 스트림을 전송한다.
- 오류 수정, 전송 처리, 흐름 제어를 보장한다.
- 데이터의 경계가 없는 바이트 스트림 서비스를 제공한다.
- 웹 서버, 데이터베이스 연결 등에 사용
- 데이터그램 소켓(SOCK_DGRAM)
- UDP를 사용하는 비연결형 소켓
- 비연결형 소켓이다.
- 데이터의 크기에 제한이 있으며, 전달이 보장되지 않는다.
- 데이터 경계를 구분하는 데이터그램 서비스를 제공한다.
- 실시간 스트리밍, 게임 등에 사용
소켓 통신의 기본 흐름
- 서버와 클라이언트 간의 연결이 성립되면 양방향으로 데이터 통신이 가능하다.
- TCP 연결의 경우, 연결 요청 시 3-way handshake 과정이 진행된다.
- 서버는 여러 클라이언트의 연결 요청을 처리하기 위해 대기열(queue)을 만들어 관리한다.
- 실제 데이터 송수신은 accept() 함수로 생성된 새로운 소켓을 통해 이루어진다.
이러한 기본 흐름을 통해 소켓은 네트워크 상에서 프로세스 간 통신의 종착점 역할을 하며, 전송 계층과 응용 프로그램 사이의 인터페이스로 작동한다.
소켓 통신의 기본 흐름은 서버와 클라이언트 간의 상호작용으로 이루어진다. :
서버 측 흐름
- 소켓 생성: socket() 함수를 사용하여 소켓을 생성한다.
- 바인딩: bind() 함수로 소켓에 IP 주소와 포트 번호를 할당한다.
- 연결 대기: listen() 함수를 호출하여 클라이언트의 연결 요청을 기다린다.
- 연결 수락: accept() 함수로 클라이언트의 연결 요청을 수락한다. 이 때 새로운 소켓이 생성되어 클라이언트와의 통신에 사용된다.
- 데이터 송수신: send()/recv() 함수를 사용하여 클라이언트와 데이터를 주고받는다.
- 연결 종료: close() 함수로 소켓을 닫는다.
클라이언트 측 흐름
- 소켓 생성: socket() 함수를 사용하여 소켓을 생성한다.
- 연결 요청: connect() 함수를 호출하여 서버에 연결을 요청한다.
- 데이터 송수신: send()/recv() 함수를 사용하여 서버와 데이터를 주고받는다.
- 연결 종료: close() 함수로 소켓을 닫는다.
TCP 소켓의 경우:
- 서버 소켓 생성
- 서버 소켓 바인딩 (IP주소와 포트번호 할당)
- 연결 대기 (Listen)
- 클라이언트의 연결 요청 수락 (Accept)
- 데이터 송수신
- 연결 종료
UDP 소켓의 경우:
- 소켓 생성
- 소켓 바인딩
- 데이터 송수신
- 소켓 종료
주요 소켓 함수
소켓의 작동 방식에서 각 함수는 다음과 같은 역할을 수행한다:
서버 측 함수
- socket(): 소켓을 생성한다. 통신의 첫 단계로, 네트워크 통신을 위한 엔드포인트를 만든다.
- bind(): 생성된 소켓에 IP 주소와 포트 번호를 할당한다. 이를 통해 특정 주소와 포트에서 들어오는 연결을 수신할 수 있게 된다.
- listen(): 클라이언트의 연결 요청을 대기하는 상태로 소켓을 변경한다. 연결 요청을 수신할 준비가 되었음을 나타낸다.
- accept(): 클라이언트의 연결 요청을 수락한다. 새로운 소켓을 생성하여 클라이언트와의 통신에 사용한다.
클라이언트 측 함수
- socket(): 서버와 마찬가지로 소켓을 생성한다.
- connect(): 서버에 연결을 요청한다. 서버의 IP 주소와 포트 번호를 지정하여 연결을 시도한다.
공통 함수
- send()/recv(): 데이터를 송수신한다. 연결된 소켓을 통해 실제 데이터 통신이 이루어진다.
- close(): 소켓을 닫는다. 통신이 완료되면 소켓을 종료하여 리소스를 해제한다.
이러한 함수들의 호출 순서와 역할을 통해 소켓은 네트워크 상에서 두 프로그램 간의 양방향 통신을 가능하게 한다.
서버는 연결을 수신하고 관리하는 역할을, 클라이언트는 연결을 요청하고 데이터를 교환하는 역할을 수행한다.
소켓의 작동 방식과 함수 호출 과정
호출 과정:
- 서버는 socket() → bind() → listen() 순으로 초기화
- 클라이언트는 socket() → connect() 로 연결 시도
- 서버는 accept()로 연결 수락
- send()/recv() 를 통한 양방향 통신
- close()로 연결 종료