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;   
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值