epoll例子

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

#define TRACE_ERROR(str) do{ \
        fprintf(stdout,"%s", str); \
}while(0);

static int SetNonblock(int socket)
{       
        //设置监听不阻塞
        int flags = fcntl(socket, F_GETFD, 0);
        if(flags==-1)
        {       
                TRACE_ERROR("fcntl F_GETFD error");
                return -1;
        }
        flags |= O_NONBLOCK;
        if(fcntl(socket, F_SETFL, flags)==-1)
        {       
                TRACE_ERROR("fnctl F_SETFL error");
                return -1;
        }
        
        return 0;
}

int handle(int connfd)
{       
        ssize_t nread;
        char buf[1024];
        nread = read(connfd, buf, 1023);
        if(nread==0)
        {       
                TRACE_ERROR("client closed the connection\n");
                close(connfd);
                return -1;
        }
        
        if(nread<0)
        {       
                TRACE_ERROR("read error\n");
                close(connfd);
                return -1;
        }
        
        if(write(connfd, buf, nread)<=0)
        {       
                TRACE_ERROR("write error\n");
                close(connfd);
                return -1;
        }


        return 0;
}


int main()
{
        int flags;
        int local_socket;
        int epoll_file_descriptor;
        epoll_event ev;
        epoll_event events[1023];
        int current_fd;
        int n_fd;
        int n;
        int conn_fd;
        sockaddr_in client_addr;
        socklen_t client_addr_len;


        struct sockaddr_in addr, their_addr;
        addr.sin_family = PF_INET;
        addr.sin_port = htons(2233);
        addr.sin_addr.s_addr = htonl(INADDR_ANY);

        local_socket = socket(PF_INET,SOCK_STREAM, 0);
        if(local_socket==-1)
        {
                TRACE_ERROR("socket create error\n");
                return -1;
        }

        if(SetNonblock(local_socket)==-1) return -1;

        if(bind(local_socket, (sockaddr*)&addr, sizeof(struct sockaddr))==-1)
        {
                close(local_socket);
                TRACE_ERROR("bind socket error\n");
                return -1;
        }

        if(listen(local_socket, 511))
        {
                close(local_socket);
                TRACE_ERROR("listen socket error\n");
                return -1;
        }
        epoll_file_descriptor = epoll_create(1024);
        if(epoll_file_descriptor == -1)
        {
                close(local_socket);
                TRACE_ERROR("epoll_create fail\n");
                return -1;
        }


        ev.events = EPOLLIN | EPOLLET;
        ev.data.fd = local_socket;
        if(epoll_ctl(epoll_file_descriptor, EPOLL_CTL_ADD, local_socket, &ev)==-1)
        {
                close(epoll_file_descriptor);
                close(local_socket);
                TRACE_ERROR("epoll_ctl fail\n");
                return -1;
        }

        current_fd = -1;
        n_fd = -1;
        client_addr_len = sizeof(struct sockaddr_in);

        while(1)
        {
                n_fd = epoll_wait(epoll_file_descriptor, events, 1023, -1);
                if(n_fd==-1)
                {
                        continue;
                }

                for(n=0; n<n_fd; n++)
                {
                        if(events[n].data.fd == local_socket)
                        {
                                conn_fd = accept(local_socket,(sockaddr*)&client_addr, &client_addr_len);
                                if(conn_fd==-1)
                                {
                                        TRACE_ERROR("accept client faild\n");
                                        continue;
                                }

                                fprintf(stdout, "accept from %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

                                SetNonblock(conn_fd);

                                ev.events = EPOLLIN | EPOLLET;
                                ev.data.fd = conn_fd;

                                if(epoll_ctl(epoll_file_descriptor, EPOLL_CTL_ADD, conn_fd, &ev)==-1)
                                {
                                        TRACE_ERROR("new client epoll_ctl add faild\n");
                                        close(epoll_file_descriptor);
                                                                                                                                                                close(local_socket);
                                        return -1;
                                }

                                current_fd++;
                                continue;
                        }
                        else if(events[n].events & EPOLLIN)
                        {
                                if(handle(events[n].data.fd)<0)
                                {
                                        epoll_ctl(epoll_file_descriptor, EPOLL_CTL_DEL, events[n].data.fd, &events[n]);
                                        current_fd--;
                                }
                        }

                }


        }


        close(epoll_file_descriptor);
        close(local_socket);

        return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

美了美了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值