오늘 aio 라이브러리도 끝냈어야 했는데...

    먼저 작성한 코드를 복사해서 고쳐쓰는 방식으로 해서 초반 예제는 완성도가 많이 낮다. 사실 후반도 낮다ㅎ


    socket 예제

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <string.h>
    
    int main() {
        int ret, sockfd;
        struct sockaddr_in ssin;
        int socklen = sizeof(struct sockaddr);
    
        /* socket */
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd == -1) { perror("socket"); exit(1); }
    
        /* set */
        ssin.sin_family      = AF_INET;
        ssin.sin_port    = htons(7777);
        ssin.sin_addr.s_addr = htonl(INADDR_ANY);
    
        /* bind, listen */
        ret = bind(sockfd, (struct sockaddr *)&ssin, socklen);
        if (ret == -1) { perror("bind"); exit(1); }
        ret = listen(sockfd, 5);
        if (ret == -1) { perror("listen"); exit(1); }
    
        int client_sockfd;
        struct sockaddr_in csin;
        char buf[BUFSIZ];
        int buflen;
    
        for (;;) {
            /* accept */
            client_sockfd = accept(sockfd, (struct sockaddr *)&csin, &socklen);
            if (client_sockfd == -1) { perror("accept"); exit(1); }
    
            /* write */
            write(client_sockfd, "Hello, World\n", strlen("Hello, World\n"));
    
            for (;;) {
                /* read */
                buflen = read(client_sockfd, buf, BUFSIZ);
                if (buflen == -1) { perror("read"); exit(1); }
                if (buflen == 0) exit(1);
                printf("%.*s", buflen, buf);
                if (!strcmp(buf, "exit")) break;
            }
            close(client_sockfd);
        }
        close(sockfd);
    
        return 0;
    }
    



    select 예제

    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    
    
    int main(int argc, char *argv[]) {
        int ret;
    
        int fd, cfd, sockfd, maxfd;
        struct sockaddr_in ssin, csin;
        int socklen = sizeof(struct sockaddr);
        fd_set readfds, allfds; // for select
    
        int i, fdnum;
        char buf[BUFSIZ];
        int buflen;
    
        if (argc != 2) {
            printf("usage: %s [port]\n", argv[0]);
            exit(1);
        }
        memset(&ssin, 0, socklen);
        ssin.sin_family      = AF_INET;
        ssin.sin_port    = htons(atoi(argv[1]));
        ssin.sin_addr.s_addr = htonl(INADDR_ANY);
    
        /* socket, bind, listen */
        fd = socket(AF_INET, SOCK_STREAM, 0);
        if (fd == -1) { perror("socket"); exit(1); }
        ret = bind(fd, (struct sockaddr *)&ssin, socklen);
        if (ret == -1) { perror("bind"); exit(1); }
        ret = listen(fd, 5);
        if (ret == -1) { perror("listen"); exit(1); }
    
        /* set */
        FD_ZERO(&readfds);
        FD_SET(fd, &readfds);
        maxfd = fd;
    
        for (;;) {
            /* select */
            allfds = readfds;
            fdnum = select(maxfd + 1, &allfds, NULL, NULL, NULL);
    
            /* FD_ISSET */
            if (FD_ISSET(fd, &allfds)) {
                /* accept */
                cfd = accept(fd, (struct sockaddr *)&csin, &socklen);
                FD_SET(cfd, &readfds);
                if (cfd > maxfd) maxfd = cfd;
                continue;
            }
    
            for (i = 0; i <= maxfd; i++) {
                sockfd = i;
                /* FD_ISSET */
                ret = FD_ISSET(sockfd, &allfds);
                if (ret == 0) continue;
    
                /* read */
                buflen = read(sockfd, buf, BUFSIZ-1);
                if (buflen == 0) {
                    printf("close\n");
                    close(sockfd);
                    FD_CLR(sockfd, &readfds);
                }
                else {
                    /* write */
                    buf[buflen] = '\0';
                    write(sockfd, buf, buflen);
                    printf("%s", buf);
                }
    
                if (--fdnum <= 0) break;
            }
        }
    
        return 0;
    }



    poll 예제

    #include <sys/poll.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    
    #define MAX 1024
    
    int main(int argc, char *argv[]) {
        int ret;
    
        int fd, cfd;
        struct sockaddr_in ssin, csin;
        socklen_t socklen = sizeof(struct sockaddr);
        struct pollfd client[MAX]; // for poll
    
        int i, maxi, nfds;
        char buf[BUFSIZ];
        int buflen;
    
        if (argc != 2) {
            printf("usage: %s [port]\n", argv[0]);
            exit(1);
        }
        memset(&ssin, 0, socklen);
        ssin.sin_family      = AF_INET;
        ssin.sin_port    = htons(atoi(argv[1]));
        ssin.sin_addr.s_addr = htonl(INADDR_ANY);
    
        /* socket, bind, listen */
        fd = socket(AF_INET, SOCK_STREAM, 0);
        if (fd == -1) { perror("socket"); exit(1); }
        ret = bind(fd, (struct sockaddr *)&ssin, socklen);
        if (ret == -1) { perror("bind"); exit(1); }
        ret = listen(fd, 5);
        if (ret == -1) { perror("listen"); exit(1); }
    
        /* set */
        client[0].fd = fd;
        client[0].events = POLLIN;
        for (i = 1; i < MAX; i++) client[i].fd = -1;
        maxi = 0;
    
        for (;;) {
            /* poll */
            nfds = poll(client, maxi + 1, -1);
            if (nfds == -1) { perror("poll"); exit(1); }
    
            if (client[0].revents & POLLIN) {
                /* accept */
                cfd = accept(fd, (struct sockaddr *)&csin, &socklen);
                for (i = 1; i < MAX; i++)
                    if (client[i].fd == -1) {
                        client[i].fd = cfd;
                        client[i].events = POLLIN;
                        break;
                    }
                if (i > maxi) maxi = i;
                if (nfds == 1) continue;
            }
    
            //if (i == MAX) { perror("too many clients"); exit(1); }
            for (i = 1; i <= maxi; i++) {
                cfd = client[i].fd;
                if (cfd == -1) continue;
                if (client[i].revents & POLLIN) {
                    /* read */
                    buflen = read(cfd, buf, BUFSIZ-1);
                    if (buflen == 0) {
                        printf("close\n");
                        close(sockfd);
                        client[i].fd = -1;
                        if (i >= maxi) maxi--;
                    }
                    else {
                        /* write */
                        buf[buflen] = '\0';
                        write(sockfd, buf, buflen);
                        printf("%s", buf);
                    }
                }
            }
        }
    
        return 0;
    }
    



    epoll 예제

    #include <sys/epoll.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    
    #define MAX 1024
    
    int main(int argc, char *argv[]) {
        int ret;
        int fd, cfd;
        struct sockaddr_in ssin, csin;
        socklen_t socklen = sizeof(struct sockaddr);
    
        if (argc != 2) {
            printf("usage: %s [port]\n", argv[0]);
            exit(1);
        }
        memset(&ssin, 0, socklen);
        ssin.sin_family      = AF_INET;
        ssin.sin_port    = htons(atoi(argv[1]));
        ssin.sin_addr.s_addr = htonl(INADDR_ANY);
    
        /* socket, bind, listen */
        fd = socket(AF_INET, SOCK_STREAM, 0);
        if (fd == -1) { perror("socket"); exit(1); }
        ret = bind(fd, (struct sockaddr *)&ssin, socklen);
        if (ret == -1) { perror("bind"); exit(1); }
        ret = listen(fd, 5);
        if (ret == -1) { perror("listen"); exit(1); }
    
        int epfd;
        struct epoll_event ev;
        struct epoll_event evlist[MAX];
    
        /* epoll_create1 */
        epfd = epfd = epoll_create1(0);
        if (epfd == -1) { perror("epoll_create1"); exit(1); }
        /* epoll_ctl */
        ev.events = EPOLLIN;
        ev.data.fd = STDIN_FILENO; // for quit
        ret = epoll_ctl(epfd, EPOLL_CTL_ADD, STDIN_FILENO, &ev);
        if (ret == -1) { perror("epoll_ctl"); exit(1); }
        ev.data.fd = fd;
        ret = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
        if (ret == -1) { perror("epoll_ctl"); exit(1); }
    
        int i, nfds;
        char buf[BUFSIZ];
        int buflen;
    
        for (;;) {
            /* epoll */
            nfds = epoll_wait(epfd, evlist, MAX, -1);
            if (ret == -1) { perror("epoll_wait"); exit(1); }
    
            for (i = 0; i < nfds; i++) {
                if (evlist[i].data.fd == STDIN_FILENO) {
                    fgets(buf, BUFSIZ-1, stdin);
                    if (!strcmp(buf, "quit\n") || !strcmp(buf, "exit\n")) {
                        close(fd);
                        exit(0);
                    }
                }
                else if (evlist[i].data.fd == fd) {
                    /* accept */
                    cfd = accept(fd, (struct sockaddr *)&csin, &socklen);
                    if (cfd == -1) { perror("accpet"); exit(1); }
                    printf("\x1b[0;32m[*] aceept\x1b[0m\n");
                    /* epoll_ctl */
                    ev.events = EPOLLIN;
                    ev.data.fd = cfd;
                    ret = epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &ev);
                    if (ret == -1) { perror("epoll_ctl"); exit(1); }
                }
                else {
                    cfd = evlist[i].data.fd;
                    /* read */
                    buflen = read(cfd, buf, BUFSIZ-1);
                    if (buflen == 0) {
                        /* close */
                        close(cfd);
                        if (cfd == -1) { perror("close"); exit(1); }
                        printf("\x1b[0;31m[*] close\x1b[0m\n");
                        /* epoll_ctl */
                        epoll_ctl(epfd, EPOLL_CTL_DEL, cfd, &evlist[i]);
                        if (ret == -1) { perror("epoll_ctl"); exit(1); }
                    }
                    else {
                        /* write */
                        buf[buflen] = '\0';
                        write(cfd, buf, buflen);
                        printf("%s", buf);
                    }
                }
            }
        }    
    
        return 0;
    }



    Posted by 코요

티스토리 툴바