Socket
소켓(Socket)
- 네트워크를 경유해서 통신을 하기 위한 도구
- 소켓을 이용해서 컴퓨터 간 통신을 할 수 있다.
- 서버와 클라이언트를 연결해주는 도구
- 서버 : 클라이언트에서 요청이 오면 소켓을 생성해 통신이 가능하도록 한다. 연결을 담당 - 하나의 컴퓨터
- 클라이언트 : 실제로 데이터의 송,수신이 일어나는 곳 - 사용자(컴퓨터)
- 소켓 구성 요소 : IP주소, 포트번호, 프로토콜
- 연결 지향 TCP소켓
- TCP/IP
- 각 소켓끼리 서로 연결
- 연결된 상태에서 통신, 연결된 대상 외에 다른 대상과는 통신 불가능
- 데이터를 잘 받았는지 중간중간 확인해서 안정적으로 데이터를 모두 보낼 수 있다
- 속도는 느리지만 안정성이 높다
- 비연결지향 UDP 소켓
- 연결되지 않은 상태에서 내가 원하는 주소에 데이터를 보낼 수 있는 통신 방법
- 데이터를 보낸 후 확인작업이 없어서 데이터가 다 수신되었는지 확인 불가능
- 속도가 빠르지만 데이터가 소실될 수 있다
- UDP헤더의 체크섬 필드를 통해 최소한의 오류만을 검출
- 동영상 스트리밍 서비스
소켓 서버 비교
- TCP 서버
- 서버 소켓은 연결만을 담당
- 서버와 클라이언트 1대1로 연결
- 스트림전송→전송데이터의 크기가 무제한
- 패킷에 대한 응답으로 인한 시간지연, CPU 소모
- 스트리밍 서비스에 불리(손실될 경우 재전송 요청)
- UDP 서버
- 1대1, 1대N, N대M 연결 가능
- 성능이 중요한 서비스에 사용
소켓 주소 체계
소켓 주소 예시
struct sockaddr_un {
sun_family;
sun_path[-];
}
struct sockaddr_in {
ADDRESS_FAMILY sin_family;
USHORT sin_port;
IN_ADDR sin_addr;
}
통합 주소 체계
- 여러 소켓 구조체를 통합해서 하나로 정의
- 할당된 공간이 다른 주소 체계에서 필요한 공간보다 커야 한다.
struct sockaddr{
ADDRESS_FAMILY sa_family;
CHAR sa_data[-];
}
소켓 서비스
- SOCK_STREAM : 연결형 서비스를 의미(TCP 프로토콜에 대응)
- SOCK_DGRAM : 비연결형 서비스를 의미 (UDP 프로토콜에 대응)
- SOCK_RAW : IP 프로토콜을 직접 사용. 실제로 자주 사용되지 않음
소켓의 흐름(TCP)
- socket() 서버와 클라이언트는 각각 소켓 생성
- bind() 주소 부여 ex)127.0.0.1:7777
- listen() 해당 주소로 서버 open
- accept() 클라이언트의 요청 connect를 대기
- send/recv() 메세지 전송 / 메세지 받을 때 (반복)
- close() 콘솔창이 닫힌다
socket()
- SOCKET socket(int af, int type, int protocol)
- socket(주소 영역 지정, 통신 타입 지정, 프로토콜 지정)
- 성공적으로 실행되어 소켓이 만들어지면 해당 소켓의 디스크립터 반환
- 프로토콜
- IPPROTO_TCP : TCP 사용
- IPPROTO_UDP : UDP 사용
bind()
- int bind(SOCKET s, const sockaddr *name, int namelen)
- 생성된 소켓에 주소 부여
- bind(소켓 객체, 바인드될 소켓의 주소(구조체), 주소 크기)
listen()과 accept()
- int listen(SOCKET s, int backlog)
- listen(소켓 객체, 연결 대기열이 최대길이)
- SOCKET accept(SOCKET s, sockaddr addr, int addrlen)
- accept(소켓 객체, 소켓 주소, 주소의 길이)
- 임의의 클라이언트의 연결 요구가 들어올 때까지 대기
- 연결 요청이 들어오면 연결이 설정되고 서버에 새로운 소켓이 생성
- 이후 데이터 송수신은 새로 생성된 소켓 이용
send()와 recv()
- int send(SOCKET s, const char *buf, int len, int flags)
- send(소켓 객체, 전송할 데이터, 데이터 길이, 호출 방식)
- 연결형 서비스를 제공하는 환경에서 데이터 전송
- int recv(SOCKET s, const char *buf, int len, int flags)
- recv(소켓 객체, 데이터를 받을 버퍼, 버퍼 길이, 플래그 집합)
- 연결형 서비스를 제공하는 환경에서 데이터 수신
connect()
- int connect(SOCKET s, const sockaddr *name, int namelen)
- connect(소켓 객체, 서버 정보 구조체, 구조체 크기)
- 클라이언트 프로세스에서 사용
- 매개변수로 설정된 값이 가리키는 서버와 연결 설정
소켓의 흐름(UDP)
- 비연결형 서비스에는 전송 데이터마다 수신자의 소켓 주소를 함께 전송해 함
- 클라이언트 측에서도 bind()실행
- 연결절차(listen, accept)가 생략됨