epoll用发

来源:互联网 发布:思念是一种病 知乎 编辑:程序博客网 时间:2024/06/14 19:34

epollserver.cpp

#include <sys/socket.h>#include <sys/epoll.h>#include <netinet/in.h>#include <arpa/inet.h>#include <fcntl.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string .h>#include <iostream>using namespace  std;void work(char *str){    char* p = str;    while(*p){        if(*p >= 'a' && *p <= 'z'){            *p = *p -'a'+'A';        }        p++;    }}int main(int argc, char* argv[]){    int i , listenfd ,connfd ,sockfd , epfd , nfds;    ssize_t n ;    char line[1024];    socklen_t clilen;    struct sockaddr_in clientaddr ;    struct sockaddr_in  severaddr ;    int ret=0 ;    //申明epoll_event结构体的变量    //ev用于注册事件    //events 数组用于回传要处理的事件    struct epoll_event ev;    struct epoll_event events[20];    //该函数生成一个epoll专用的文件描述符    //其中的参数是指定生成文件描述符的最大范围//  epfd = epoll_create(256);    epfd = epoll_create1(EPOLL_CLOEXEC);    //创建套接字     listenfd = socket(AF_INET , SOCK_STREAM , 0);    //设置与要处理的事件相关的文件描述符    ev.date.fd = listenfd ;    //设置要处理的事件类型    //EPOLLIN : 表示对应的文件描述符可以读    //EPOLLOUT :表示对应的文件描述符可以写    //EPOLLERR :发生错误    ev.events = EPOLLIN;    //注册epoll事件     //EPOLL_CTL_ADD 注册    //EPOLL_CTL_MOD 修改    //EPOLL_CTL_DEL 删除    epoll_ctl(epfd , EPOLL_CTL_ADD , listenfd , &ev);    //设置服务器地址    bzero(&sereveraddr , sizeof(struct serveraddr));    serveraddr.sin_family = AF_INET ;    serveraddr.sin_addr.s_addr = INADDR_ANY;    serveraddr.sin_port = htons (8000);    ret = bind (listenfd , (struct scokaddr*)&serveraddr ,                            sizeof(struct serveraddr));    if(ret  < 0){        continue ;    }    listen (listenfd , 20);    while(1){        //监听epoll事件的发生        //超时时间为500ms  最多能处理20个事件         //events 用于保存索监听到的事件        //返回监听到的事件总数        nfds = epoll_wait(epfd , events , 20 ,500);        //分别处理各事件         for(i =0; i<nfd ; ++i){            //有客户端的链接(connect )服务器            if(events[i].data.fd == listenfd){            connfd = accept(listenfd ,                             (struct sockaddr*)&clientaddr ,                            &clilent);            if(connfd < 0){                perror("accept");                continue ;            }               char *str = inet_ntoa(clientaddr.sin_addr);            cout << "accept a connect from "<< str << endl;            //设置用于读操作的文件描述符            ev.data.fd = connfd;            //设置读注册            ev.events = EPOLLIN;            //注册            epoll_ctl(epfd , EPOLL_CTL_ADD , connfd , &ev);            else if(events[i].events & EPOLLIN){                cout << "can  read data "<< endl;                sockfd = events[i].data.fd;                if(sockfd < 0){                    continue ;                }            n = read (sockfd , line ,sizeof(line));            if(n < 0){                close(sockfd);                event[i].data.fd = -1;                cout << "client closed "<< endl;                continue;            }            cout << "server readline "<< line << endl;            //处理业务            work (line);            //设置用于写操作的文件描述符            ev.data.fd = sockfd ;             ev.events = EPOLLOUT ;            //修改sockfd 上要处理的事件为EPOLLOUT             //在接收到客户端链接时,已经把客服端套接字注册到epoll            //所以,此时只需要修改所注册的事件            //            epoll_ctl(epfd , EPOLL_CTL_MOD ,sockfd , &ev);            }               else if(events[i].events & EPOLLOUT ){                cout << "can read data "<< endl;                sockfd  = events[i].data.fd;                write(sockfd , line ,n );                cout << "server had send data"<< endl;                ev.data.fd = sockfd ;                ev.events = EPOLLIN ;                epoll_ctl(epf , EPOLL_CTL_MOD , sockfd , &ev);            }            }           }    }    return 0;   }
0 0
原创粉丝点击