linux epoll ET边沿触发

/*
*
*EPOLL ET 触发必须使用非阻塞,LT触发可以阻塞/非阻塞。
*read 函数 非阻塞读需 忙轮寻 soket关闭返回0,循环读完数据
*如果已经读完再读read返回 -1,errno=11(EAGIAN)则退出轮循
*
*
*/


#include<stdio.h> #include<sys/socket.h> #include<sys/types.h> #include<stdlib.h> #include<unistd.h> #include<sys/select.h> #include<sys/time.h> #include<pthread.h> #include<memory.h> #include<errno.h> #include<arpa/inet.h> #include<netinet/in.h> #include<signal.h> #include<semaphore.h> #include<malloc.h> #include<fcntl.h> #include<sys/epoll.h> typedef unsigned int uint32; pthread_mutex_t lock; uint32 qcount=0; typedef struct{ int flag; sem_t sem; }MYLOCK; struct sockaddr_in server; MYLOCK mlock; int g_epfd=-1; void printerror() { printf("%d:%s\n",errno,strerror(errno)); exit(-1); } void* th_hand(void* p){ sem_wait(&mlock.sem); while(!mlock.flag){ sem_post(&mlock.sem); sleep(1); sem_wait(&mlock.sem); } sem_post(&mlock.sem); struct epoll_event events[10]; struct epoll_event event; while(1){ memset(&event,0,sizeof(struct epoll_event)); memset(events,0,sizeof(struct epoll_event)*10); int s = epoll_wait(g_epfd,events,10,100); if(s==-1){ printerror(); }else if(s==0){ continue; }else if(s>0){ for(int i=0;i<s;i++){ int fd=events[i].data.fd; char buff[4]; while(1){ int rd=-1; memset(buff,0,sizeof(buff)); rd=read(fd,buff,sizeof(buff)-1); if(rd==0){ struct sockaddr_in client; memset(&client,0,sizeof(client)); int len=sizeof(client); getpeername(fd,(struct sockaddr*)&client,&len); printf("client %s is closed fd is %d , bye!\n",inet_ntoa(client.sin_addr),fd); close(fd); event.data.fd=fd; sem_post(&mlock.sem); epoll_ctl(g_epfd,EPOLL_CTL_DEL,fd,&event); sem_wait(&mlock.sem); break; }else if(rd>0){ int wr=write(STDOUT_FILENO,buff,rd); }else if(rd==-1){ if(errno==EAGAIN) break; printerror(); } } } } } } int initSocket(int port){ memset(&server,0,sizeof(server)); server.sin_family=AF_INET; server.sin_addr.s_addr=htonl(INADDR_ANY);//INADDR_ANY==0 server.sin_port=htons(port); int sockfd=socket(AF_INET,SOCK_STREAM,0); if(sockfd==-1){ printerror(); } int res=bind(sockfd,(struct sockaddr*)&server,sizeof(struct sockaddr)); if(res==-1){ printerror(); } if(-1==listen(sockfd,10)){ printerror(); } g_epfd=epoll_create(5); if(g_epfd==-1){ printerror(); } sem_wait(&mlock.sem); mlock.flag=1; sem_post(&mlock.sem); printf("main before accept\n"); while(1){ int fd; if((fd=accept(sockfd,NULL,NULL))==-1){ printerror(); } printf("fd %d is connect\n",fd); struct epoll_event event; // event.events=EPOLLIN; event.events=EPOLLIN|EPOLLET; event.data.fd=fd; fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0)|O_NONBLOCK); sem_wait(&mlock.sem); if(-1==(epoll_ctl(g_epfd,EPOLL_CTL_ADD,fd,&event))){ printerror(); } qcount++; sem_post(&mlock.sem); } } void sig_hand(int signo){ if(signo==SIGINT){ printf("have %d client\n",qcount); exit(0); } } pthread_t pid; int main(int argc,char** argv){ if(argc<2){ puts("please input port\n"); exit(-1); } int port=atoi(argv[1]); signal(SIGINT,sig_hand); memset(&mlock,0,sizeof(mlock)); sem_init(&mlock.sem,0,1); mlock.flag=0; pthread_create(&pid,NULL,th_hand,(void*)0); pthread_detach(pid); initSocket(port); }

 

posted @ 2019-03-02 14:20  ForMeDream  阅读(376)  评论(0编辑  收藏  举报