• epoll用发


    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;   
    }
    
  • 相关阅读:
    Android:日常学习笔记(7)———探究UI开发(1)
    Android:日常学习笔记(6)——探究活动(4)
    JavaScript:基础扩展(1)——JSON
    JavaScript:学习笔记(3)——正则表达式的应用
    正则表达式:快速入门
    LeetCode_Easy_471:Number Complement
    Java实现——字符串分割以及复制目录下的所有文件
    DOM、SAX、JDOM、DOM4J以及PULL在XML文件解析中的工作原理以及优缺点对比
    一个简单电商网站开发过程中的业务资料整理
    大道至简,不简则死
  • 原文地址:https://www.cnblogs.com/Sico2Sico/p/5384276.html
Copyright © 2020-2023  润新知