• Linux 网络编程(epoll)


    • 服务器端代码
    #include<stdio.h>  
    #include<stdlib.h>  
    #include<string.h>  
    #include<sys/socket.h>  
    #include<sys/types.h>  
    #include<unistd.h>  
    #include<netinet/in.h>
    #include <errno.h>
    #include <sys/epoll.h>
    
    int main(int argc, char** argv){
    
        int old_fd,new_fd;
        struct sockaddr_in server_addr;
        struct sockaddr_in client_addr;
    
        char recvbuf[1024];
        int port = 8001;
        int len,nbytes,epfd,i;
        //声明epoll_event结构体的变量,ev用于注册事件,数组用于回传要处理的事件
        struct epoll_event ev,events[20];
    
        //生成用于处理accept的epoll专用的文件描述符,参数为最大的监听数目
        epfd = epoll_create(100);
    
        if((old_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == 0){
            fprintf(stderr, "socket Error:%s
    a", strerror(errno));   
            exit(1);
        }
    
        bzero(&server_addr, sizeof(struct sockaddr_in));
        server_addr.sin_family = AF_INET;
        server_addr.sin_port = htons(port);
        server_addr.sin_addr.s_addr =  htonl(INADDR_ANY);
    
        if((bind(old_fd, &server_addr, sizeof(server_addr))) == -1){
            fprintf(stderr, "bind Error:%s
    a", strerror(errno));   
            exit(1);
        }
    
        if(listen(old_fd, 10) == -1){
            fprintf(stderr, "listen Error:%s
    a", strerror(errno));   
            exit(1);
        }
    
        ev.data.fd = old_fd;
        //设置要处理的事件类型
        ev.events = EPOLLIN;
        //EPOLL_CTL_ADD 注册新的fd
        //EPOLL_CTL_MOD 修改已注册的fd
        //EPOLL_CTL_DEL 删除epfd中的一个fd
        epoll_ctl(epfd, EPOLL_CTL_ADD, old_fd, &ev); 
    
        while(1){
            //int epoll_wait(int epfd, struct epoll_event * events, intmaxevents, int timeout);
            //maxevents:每次能处理的事件数;
            //timeout:等待I/O事件发生的超时值;-1相当于阻塞,0相当于非阻塞。一般用-1即可
            len = epoll_wait(epfd,events,20,500);
    
            for(i = 0; i < len; i++){
                if(events[i].data.fd == old_fd){
                    if ((new_fd = accept(old_fd, 
                        (struct sockaddr *)&client_addr, 
                        &len)) == -1) {   
                                fprintf(stderr, "Accept error:%s
    a", strerror(errno));   
                            exit(1);   
                    }
    
                    ev.data.fd=new_fd;
    
                  /*EPOLLIN:        表示对应的文件描述符上有可读数据
                     EPOLLOUT:         表示可以写数据;
                    EPOLLPRI:         表示对应的文件描述符有紧急的数据可读
                    EPOLLERR:         表示对应的文件描述符发生错误;
                     EPOLLHUP:         表示对应的文件描述符被挂断;
                    EPOLLET:          将EPOLL设为边缘触发ET模式
                                       ET模式:Edge Triggered epoll_wait 只有在读写状态改变时才返回
                                       LT模式:LevelTriggered (默认) epoll_wait 会一致有
                    EPOLLONESHOT:     只监听一次事件                                    */
                    ev.events=EPOLLIN;//对接入的新套接字注册epoll时间监听
                    epoll_ctl(epfd, EPOLL_CTL_ADD, new_fd, &ev);
                }else if(events[i].events&EPOLLIN){
                    if (events[i].data.fd < 0) 
                        continue;
    
                    nbytes = recv(events[i].data.fd, recvbuf, sizeof(recvbuf), 0);
                    recvbuf[nbytes] = '';
    
                    printf("recv data is:%s
    ",recvbuf);
                }
            }
        }
    
        exit(0);
    }
  • 相关阅读:
    反射式光电开关QRE1113
    labview程序性能优化
    labview中小黑点,小红点
    简述时钟周期、机器周期、指令周期的概念及三者之间的关系
    C++中的#和##运算符
    NTC与PTC压敏电阻在电源电路中起的作用
    常用DC-DC;AC-DC电源芯片
    PC817与TL431的配合电路探讨
    React入门
    WebRTC网关服务器单端口方案实现
  • 原文地址:https://www.cnblogs.com/Fredric-2013/p/4549321.html
Copyright © 2020-2023  润新知