• 리눅스 vs. 윈도우
    : 편견을 갖을 필요 없다. 각각의 장단점이 있다.
    : 시스템콜 기반과 표준라이브러리 IO와 차이
    : 시스템콜 메커니즘 자체는 리눅스와 윈도우가 같다.

    : 리눅스는 무료 오픈소스로 파일 디스크립터, 오픈파일 등의 세팅을 바꾸어줄수 있지만 윈도우즈는 변경하기가 힘들고, 가격이 비싸지만 (windows server 같은 경우 cpu당 라이센스 비용 지불), 개발이 쉽다.
    : 바로 함수를 호출하는 메커니즘 vs 하나를 거쳐 호출하는 메커니즘
    : mono vs micro
    : 커널을 다시 빌드해야함 vs 모듈처럼 사용 가능하지만 성능 저하
    : android 코드를 분석해보면 bionic -> 각각의 CPU에 대해 존재하는 이유는 시스템콜 때문이다.



  • 시스템 콜

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
     
    #include <stdio.h >
     
    // stdin, stdout, stderr : FILE*
    // STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO : int
     
    // task_struct
     
    // 1. socket programming 저수준 IO를 사용합니다.
    // 2. 저수준 IO : 운영체제에서 제공하는 IO 관련 API
    //   Windows : Win32/64 API
    //   Linux   : System Call
     
    // 3. 프로세스를 통해 파일을 관리한다.
    //   ulimit -a
     
    int main()
    {
        // FILE* fp = fopen("sample", "r");
        int fd = open("sample", O_RDONLY);
     
        printf("fd : %d\n", STDIN_FILENO);
        printf("fd : %d\n", STDOUT_FILENO);
        printf("fd : %d\n", STDERR_FILENO);
        printf("fd : %d\n", fd);
            // fd 출력시 3인 이유는 표준 입출력, 에러에 대한 fd가 열려있기 때문이다
            // VFS라고 부른다 -> 다형성
            // 내부적으로 파일, 디바이스를 다루는 모든 방식은 파일로 되어있다. 이를 사용하기 위해서는 각각을 모두 열어야한다. -> 동적바인딩을 통해서
            // 리눅스는 array로 파일디스크립터 관리, 윈도우즈는 파일디스크립터 핸들
    }

    버퍼링 정책 3가지

     1. Full Buffering : Buffer가 가득 차면 화면에 출력    → File I/O
     2. Line Buffering : ‘\n’이 오면 화면에 출력          → printf의 경우에 해당
     3. Non Bufering : 버퍼링을 하지 않음.              → fprintf(stderr,””);에 해당

      pirntf("error");

      while(1); 

      //출력하지 않는다.


      pirntf("error\n");

      while(1); 

      //출력한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
     
    #include <stdio.h>
     
    int main()
    {
        int fd = open("sample", O_RDONLY);
        printf("fd : %d\n", fd);
     
     
        // 문제점
        // 1. 에러 발생시 -1 리턴
        // 2. 버퍼의 크기가 너무 작을 경우, 빈번한 컨텍스트 스위칭으로 인한
        //    성능 저하가 있다.
    #if 0
        char ch;
        while (read(fd, &ch, sizeof ch) > 0)
            putchar(ch);
    #endif
     
        // 3. read(fd, buf, size)
        //  size : 버퍼의 최대 크기
        // 4. write(fd, buf, size)
        //  size : 쓰고자 하는 데이터의 실제 양
     
        char buf[128];
        int ret;
        while ((ret = read(fd, buf, sizeof buf)) > 0) {
            write(1, buf, ret);
     
            // buf[ret] = '\0';
            // printf("%s", buf);
        }
     
        close(fd);
            // close를 안해도 문제가 없었던 이유
            // 프로세스가 종료되면서 소유하고 있던 자원을 모두 해지
     
            // app영역에서는 프로세스 종료로 OS가 메모리를 수거함. 대부분 커널의 누수
            // 정적분석은 new와 delete쌍을 찾아서 싱글톤은 메모리 누수로 인식함
            // 동적분석은 비쌈
     
    }


  • 클라이언트 작성하기
    - http 통신

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
     
    #include <errno.h>
    #include <string.h>
     
    int main()
    {
        // 1. 소켓 생성 : socket()
        int sd = socket(PF_INET,      //  프로토콜
                                        SOCK_STREAM,  //  TCP(SOCK_STREAM), UDP(SOCK_DGRAM)
                                        IPPROTO_TCP); //  하위 프로토콜(생략, 0 으로 지정 가능)
         
        // 2. 서버 주소 지정 : 초기화 이전에 0으로 초기화해야 한다.
        // 문자열 ip -> 32 bit : inet_addr
        struct sockaddr_in addr = {0, };
        addr.sin_family = AF_INET;
        addr.sin_port = htons(80);
        addr.sin_addr.s_addr = inet_addr("127.0.0.1");
     
        // 3. 접속 수행
        int ret = connect(sd, (struct sockaddr*)&addr, sizeof(addr));
        if (ret == -1) {
            // 에러 처리 방법 3가지
            // 1. printf("connect() error : %d\n", errno);
     
            // 2. char* msg = strerror(errno);
            //    printf("connect() error : %s\n", msg);
             
            // 3.
            perror("connect()");
            goto err;
        }
     
        {
            printf("Connection succeed!!\n");
     
            // "GET \n\n"
            char buf[1024] = "GET /\n\n";
            write(sd, buf, strlen(buf));
     
            int len;
            while ((len = read(sd, buf, sizeof(buf))) > 0) {
                write(1, buf, len);
            }
        }
     
    err:
        // 4. 접속 종료
        close(sd);
    }


    - DNS

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    #include <stdio.h>
    // domain -> ip address
    // : gethostbyname
     
    // gethostbyname
    #include <netdb.h>   
     
    // inet_ntoa: 네트워크로부터 온 패킷을 아스키코드로 바꾸어 주는 것
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
     
    int main()
    {
        struct hostent* host = gethostbyname("www.google.com");
     
        // name
        printf("host name : %s\n", host->h_name);
     
        // alias
        for (int i = 0 ; host->h_aliases[i] ; i++) {
            printf("Alias[%d] : %s\n", i + 1, host->h_aliases[i]);
        }
     
        for (int i = 0 ; host->h_addr_list[i] ; i++) {
            printf("Address[%d] : %s\n",
                    i+1,
                    inet_ntoa(*(struct in_addr*)host->h_addr_list[i]) );
        }
    }


+ Recent posts