epoll 模型原理详解以及实例(6)

epfd = epoll_create(MAX_EVENTS);  //create epoll,返回值为epoll的文件描述符
    //epfd = epoll_create(EPOLL_CLOEXEC);  //新版写法
    if(epfd < 0)
        hand_error("epoll_create");
    int ret = epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev);  //添加时间
    if(ret < 0)
        hand_error("epoll_ctl");


    while(1)
    {
        ret_events = epoll_wait(epfd, events, MAX_EVENTS, -1);  //类似于select函数,这里是等待事件的到来。
        if(ret_events == -1)
        {
            cout<<"ret_events = "<<ret_events<<endl;
            hand_error("epoll_wait");
        }

if( ret_events == 0)
        {
            cout<<"ret_events = "<<ret_events<<endl;
            continue;
        }

//      cout<<"ret_events = "<<ret_events<<endl;
        for( int num = 0; num < ret_events; num ++)
        {
            cout<<"num = "<<num<<endl;
            cout<<"events[num].data.fd = "<<events[num].data.fd<<endl;
            if(events[num].data.fd == listenfd) //client connect
            {
                cout<<"listen sucess and listenfd = "<<listenfd<<endl;
                cli_sock = accept(listenfd, (struct sockaddr*)&peer_addr, &peerlen);
                if(cli_sock < 0)
                    hand_error("accept");
                cout<<"count = "<<count++;
                printf("ip=%s,port = %d\n", inet_ntoa(peer_addr.sin_addr),peer_addr.sin_port);
                clients.push_back(cli_sock);
                setnoblock(cli_sock);  //设置为非阻塞模式
                ev.data.fd = cli_sock;// 将新连接也加入EPOLL的监听队列
                ev.events = EPOLLIN | EPOLLET ;
                if(epoll_ctl(epfd, EPOLL_CTL_ADD, cli_sock, &ev)< 0)
                    hand_error("epoll_ctl");
            }

else if( events[num].events & EPOLLIN)
            {
                cli_sock = events[num].data.fd;
                if(cli_sock < 0)
                    hand_error("cli_sock");
                char recvbuf[1024];
                memset(recvbuf, 0 , sizeof(recvbuf));
                int num = read( cli_sock, recvbuf, sizeof(recvbuf));
                if(num == -1)
                    hand_error("read have some problem:");
                if( num == 0 )  //stand of client have exit
                {
                    cout<<"client have exit"<<endl;
                    close(cli_sock);
                    ev_remov = events[num];
                    epoll_ctl(epfd, EPOLL_CTL_DEL, cli_sock, &ev_remov);
                    clients.erase(remove(clients.begin(), clients.end(), cli_sock),clients.end());
                }
                fputs(recvbuf,stdout);
                write(cli_sock, recvbuf, strlen(recvbuf));
            }
        }
    }

return 0;
}

/***********
client.c
***********/

#include "net.h"

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/07056860132b8a0bd306cfbb0a535cbb.html