Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

socket

통신을 위한 종점(endpoint) 을 생성하고, 이에 대한 파일지정자를 반환한다.

사용 법

#include <sys/types.h>
#include <sys/socket.h>

int socket(int domain, int type, int protocol);

설명

통신을 위한 종점(endpoint)를 생성하기 위해서 사용한다. 성공적으로 함수를 수행했을경우, 통신 종점으로 사용될 파일 지시자를 리턴한다.

socket 함수를 통해서 만들어진 파일 지정 번호는 보통 클라이언트의 연결을 듣기 위해서 사용됨으로 "듣기 소켓" 이라고 불리우기도 한다.

매개 변수

  • domain(도메인) 은 통신 도메인(영역)을 지정하기 위해서 사용한다.
|| AF_UNIX || 유닉스 도메인 소켓으로 IPC(:12) 용으로 사용한다.
AF_INET TCP/IP 프로토콜을 이용한 일반적인 인터넷 통신용으로 주로 사용된다. AF_UNIX 와 함께 가장 일반적으로 사용된다.
AF_IPX 노벨의 IPX 프로토콜의 사용을 위해서 사용한다.
AF_X25 X.25 프로토콜
AF_AX25 아마추어 라디오 X.25
  • type 은 통신에 사용될 패킷의 타입을 지정하기 위해서 사용한다.
|| SOCK_STREAM || 연결지향의 TCP 프로토콜 ||
SOCK_DGRAM 데이타그램 지향의 UDP 프로토콜
SOCK_RAW 생소켓 혹은 날소켓으로 불리우는 저수준 socket 제어 프로토콜
  • protocol 은 소켓을 사용하기 위한 프로토콜 지정을 위해 사용한다. type 값과 함께 쌍으로 사용되는 경우가 많다.
|| IPPROTO_ICMP || ICMP(Internet Control Message Protocol)을 사용한다. SOCK_RAW domain에서 사용할 수 있다. ||
IPPROTO_TCP 연결 지향 프로토콜로 SOCK_STREAM type 과 함께 사용된다.
IPPROTO_UDP 데이터 그램 지향 프로토콜로 SOCK_DGRAM type 과 함께 사용된다.

반환값

성공할경우 정수의 파일 지정 번호, 실패할경우 -1을 반환한다.

에러

EPROTONOSUPPORT 지정된 프로토콜 타입 혹은 프로토콜이 해당 도메인에서 지원되지 않을경우
ENFILE 새로운 소켓구조를 지정하기 위해 커널 메모리가 부족
EMFILE 프로세스 파일 테이블이 overflow
EACCES 지정된 타입의 생성된 소켓이나 프로토콜 권한이 거부되었을경우, 대표적으로 RAW 소켓은 root 권한이 있어야 생성가능하다.
EINVAL 알려지지 않은 프로토콜을 사용했을 경우

예제

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>

#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv)
{
    int server_sockfd, client_sockfd;
    int state, client_len;

    struct sockaddr_in clientaddr, serveraddr, myaddr;


    // internet 기반의 스트림 소켓을 만들도록 한다. 
    // server_sockfd 는 endpoint 소켓(듣기 소켓) 으로 사용된다. 
    if ((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        perror("socket error : ");
        exit(0);
    }
    bzero(&serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serveraddr.sin_port = htons(12345);

    // 듣기 소켓에 소켓특성(주소, 포트)를 묶어준다. 
    state = bind(server_sockfd , (struct sockaddr *)&serveraddr, 
            sizeof(serveraddr));
    if (state == -1)
    {
        perror("bind error : ");
        exit(0);
    }

    state = listen(server_sockfd, 5);
    if (state == -1)
    {
        perror("listen error : ");
        exit(0);
    }

    // 만약 듣기 소켓으로 클라이언트 연결이 들어왔다면, 
    // 새로운 클라이언트와의 통신을 위한 소켓 지정번호를 할당한다. 
    client_sockfd = accept(server_sockfd, (struct sockaddr *)&clientaddr, 
                           &client_len);
    if (client_sockfd == -1)
    {
        perror("Accept error : ");
        exit(0);
    }
    // 여기에서 부터는 클라이언트와의 통신
    // .....
    // .....

    close(client_sockfd);
    return 1;
}