epoll实现的简单服务器

#include "../wrap/wrap.h"
#include <sys/epoll.h>
#define SIZE 1024
#define FUCK printf("close or free me\n")
#define PORT 8000
#define IP "192.168.68.152"
#define MAX_EVENTS 10
// epoll监听socket


int main() 
{
    // 创建监听套接字
    int listen_fd = Socket(AF_INET, SOCK_STREAM, 0);

    //绑定ip和端口
    struct sockaddr_in addr;
    socklen_t len = sizeof(addr);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    inet_pton(AF_INET, IP, (void*)&addr.sin_addr.s_addr);
    Bind(listen_fd, (struct sockaddr*)&addr, len);
    
    // 监听
    Listen(listen_fd, 128);

    //epoll 监视监听套接字,刚开始只有listen_fd
    int epfd = epoll_create(1);
    struct epoll_event event;
    event.events = EPOLLIN;
    event.data.fd = listen_fd;
    epoll_ctl(epfd, EPOLL_CTL_ADD, listen_fd, &event);

    while (1)
    {
        // 接收变化套接字的数组
        struct epoll_event events[MAX_EVENTS];
        int n = epoll_wait(epfd, events, MAX_EVENTS, 0);
        printf("有%d个访问\n", n);
        getchar();

        if(n < 0)
        {
            perror("epoll_wait");
            return 1;
        }

        // 遍历所有变化的套接字
        for(int i = 0; i < n; ++i)
        {
            int fd = (events + i)->data.fd;
            uint32_t need_read = (events + i)->events & EPOLLIN;
            // 监听套接字有新连接
            if(fd == listen_fd && need_read)
            {
                struct sockaddr_in client_addr;
                int client_fd = Accept(fd, (struct sockaddr*)&client_addr, &len);
                char _ip[16] = "";
                printf("%s已连接\n",inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, _ip, 16));
                struct epoll_event event;
                event.events = EPOLLIN;
                event.data.fd = client_fd;
                epoll_ctl(epfd, EPOLL_CTL_ADD, client_fd, &event);
            }
            else if(need_read)// 有套接字需要读
            {
                char buf[SIZE] = "";
                int n = read(fd, buf, SIZE);

                if(n < 0)
                {
                    Close(fd);
                    epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);
                    perror("read");
                    return 1;
                }
                else if(0 == n) // 套接字关闭
                {
                    Close(fd);
                    epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);
                }
                else
                {
                    printf("%s\n", buf);
                    Write(fd, buf, n);
                }
            }
        }
    }
    Close(listen_fd);
    epoll_ctl(epfd, EPOLL_CTL_DEL, listen_fd, NULL);
    Close(epfd);
    epoll_ctl(epfd, EPOLL_CTL_DEL, epfd, NULL);
    return 0;
}

posted @ 2022-01-25 13:45  hellozhangjz  阅读(53)  评论(0)    收藏  举报