소켓(Socket)은 네트워크 통신의 양 끝점을 나타내는 추상화로, 애플리케이션이 네트워크를 파일처럼 읽고 쓸 수 있게 해주는 인터페이스입니다.
소켓은 운영체제가 제공하는 API입니다. 애플리케이션 개발자는 TCP/IP의 세부 동작을 몰라도 소켓 API만으로 네트워크 통신을 구현할 수 있습니다.
소켓 = IP 주소 + 포트 번호
예: 192.168.1.1:8080
Stream Socket: TCP 기반으로 연결 지향적이고 신뢰성 있는 데이터 스트림을 제공하는 소켓
데이터를 순서대로, 손실 없이 전달합니다. 웹, 파일 전송 등에 사용합니다.
Datagram Socket: UDP 기반으로 연결 없이 독립적인 패킷을 전송하는 소켓
빠르지만 신뢰성은 없습니다. DNS, 실시간 게임, 스트리밍에 사용합니다.
[서버] [클라이언트]
socket() 생성
bind() 주소 바인딩
listen() 대기
socket() 생성
accept() 연결 대기 ←←←← connect() 연결 요청
데이터 처리 →→→→→ recv() 데이터 수신
send() 응답 전송 →→→→→
close() 종료 close() 종료
서버 소켓은 특정 포트에서 연결 요청을 기다립니다. 클라이언트가 연결하면 새로운 소켓을 생성하여 해당 클라이언트 전담으로 통신합니다. 이 덕분에 서버 소켓은 계속 새 연결을 수락하면서 기존 클라이언트와도 동시에 통신할 수 있습니다.
TCP 연결은 다음 4가지 값으로 유일하게 식별됩니다.
(출발지 IP, 출발지 포트, 목적지 IP, 목적지 포트)
같은 서버 포트 80으로 수천 명의 클라이언트가 동시에 접속할 수 있는 이유는 각 연결의 출발지 IP와 출발지 포트 조합이 다르기 때문입니다.
SO_REUSEADDR: 서버 재시작 시 이전 주소를 즉시 재사용할 수 있게 합니다. 서버 개발 시 필수적으로 설정합니다.
SO_KEEPALIVE: 일정 시간 동안 데이터 교환이 없으면 연결이 살아있는지 확인하는 패킷을 보냅니다. 유휴 연결이 끊겼는지 감지할 때 사용합니다.