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 @   hellozhangjz  阅读(44)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示