c/c++ 實現epoll 管理socket fd

#######################################################################
非常簡單的epoll 例子 紅色部分時epoll 藍色部分時socket c/c++ 可以編譯運行 

客戶端可以使用 echo xxx > /dev/tcp/127.0.0.1/9000 測試 
或者使用 exec 9<>  /dev/tcp/127.0.0.1/9000  //鏈接 
         echo xxx >& 9  //發送                                         
         cat <& 9  //接受打印                                          
#######################################################################

cat deam.c

#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <sys/epoll.h>
#include <string.h>
#include <unistd.h>



int main(){

    epoll_event ev[1024],event;
    sockaddr_in ser;
    memset(ev,0,sizeof(epoll_event)*1024);
    memset(&ser,0,sizeof(socklen_t));

    //tcp socket 配置
    int epfd, nfd;
    ser.sin_family = AF_INET;
    ser.sin_port = htons(9000);
    ser.sin_addr.s_addr = htonl(inet_addr("0.0.0.0"));
    if((nfd = socket(AF_INET,SOCK_STREAM,0)) < 0){
        perror("create socket error: ");
    }
    if(bind(nfd,(sockaddr*)&ser,sizeof(ser)) < 0){
        perror("bind error:");
    }
    if(listen(nfd,65536) < 0){
        perror("lisent error: ");
    }
    
    //創建epoll 句柄
    if((epfd = epoll_create(1)) < 0){
        perror("create epoll error: ");
    }
    //監聽讀取事件
    event.data.fd = nfd;
    event.events = EPOLLIN;
    if(epoll_ctl(epfd,EPOLL_CTL_ADD,nfd,&event) < 0){
        perror("add server fd error: ");
    }

    while(1){

        int event_len = epoll_wait(epfd,ev,1025,-1);
        printf("_______\n");
        for(int i = 0;i < event_len;i++){
            //新連接 進入握手事件
            if(ev[i].data.fd == nfd){
                sockaddr_in cli;
                socklen_t len = sizeof(cli);
                int cfd = accept(nfd,(sockaddr*)&cli,&len);
                if(cfd < 0){
                    continue;
                }
                else{
                    event.data.fd = cfd;
                    event.events = EPOLLIN;
                    if(epoll_ctl(epfd,EPOLL_CTL_ADD,cfd,&event)<0){perror("add error:");}
                    printf("%d服務器鏈接成功\n",cfd);
                }
            }
            //end
            //換從區有數據 進入讀取事件中
            if(ev[i].data.fd>nfd && (ev[i].events & EPOLLIN)){
                char buf[1024];
                int rl = recv(ev[i].data.fd,buf,1024,0);
                buf[rl] = '\0';
                printf("%s",buf);
                if(rl <= 0){
                    if(epoll_ctl(epfd,EPOLL_CTL_DEL,ev[i].data.fd,&event)<0){perror("add error:");}
                    close(ev[i].data.fd);
                    printf("%d服務器斷開鏈接\n",ev[i].data.fd);
                }
            }
            //end
            if(ev[i].events & EPOLLERR){
                printf("error");
            }
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章