epoll
#include"local.h"#include"utils.h"usingnamespacestd;//存放客户端socket描述符的listlist<int>clients_list;intmain(intargc,char*argv[]){intlistener;//监听socketstructsockaddr_inaddr,their_addr;addr.sin_family=PF_INET;addr.sin_port=htons(SERVER_PORT);addr.sin_addr.s_addr=inet_addr(SERVER_HOST);socklen_tsocklen;socklen=sizeof(structsockaddr_in);staticstructepoll_eventev,events[EPOLL_SIZE];ev.events=EPOLLIN|EPOLLET;//对读感兴趣,边沿触发charmessage[BUF_SIZE];intepfd;//epoll描述符clock_ttStart;//计算程序运行时间intclient,res,epoll_events_count;CHK2(listener,socket(PF_INET,SOCK_STREAM,0));//初始化监听socketsetnonblocking(listener);//设置监听socket为不阻塞CHK(bind(listener,(structsockaddr*)&addr,sizeof(addr)));//绑定监听socketCHK(listen(listener,1));//设置监听CHK2(epfd,epoll_create(EPOLL_SIZE));//创建一个epoll描述符,并将监听socket加入epollev.data.fd=listener;CHK(epoll_ctl(epfd,EPOLL_CTL_ADD,listener,&ev));//把被监听的fd和监听的事件放入epoll的文件描述符中//while(1){CHK2(epoll_events_count,epoll_wait(epfd,events,EPOLL_SIZE,EPOLL_RUN_TIMEOUT));tStart=clock();for(inti=0;i<epoll_events_count;i++){if(events[i].data.fd==listener)//新的连接到来,将连接添加到epoll中,并发送欢迎消息{CHK2(client,accept(listener,(structsockaddr*)&their_addr,&socklen));setnonblocking(client);ev.data.fd=client;CHK(epoll_ctl(epfd,EPOLL_CTL_ADD,client,&ev));clients_list.push_back(client);//添加新的客户端到listbzero(message,BUF_SIZE);res=sprintf(message,STR_WELCOME,client);CHK2(res,send(client,message,BUF_SIZE,0));}else{CHK2(res,handle_message(events[i].data.fd));//注意:这里并没有调用epoll_ctl重新设置socket的事件类型,但还是可以继续收到客户端发送过来的信息}}printf("Statistics:%deventshandledat:%.2fsecond(s)\n",epoll_events_count,(double)(clock()-tStart)/CLOCKS_PER_SEC);}close(listener);close(epfd);return0;}inthandle_message(intclient){charbuf[BUF_SIZE],message[BUF_SIZE];bzero(buf,BUF_SIZE);bzero(message,BUF_SIZE);intlen;CHK2(len,recv(client,buf,BUF_SIZE,0));//接受客户端信息if(len==0)//客户端关闭或出错,关闭socket,并从list移除socket{CHK(close(client));clients_list.remove(client);}else//向客户端发送信息{if(clients_list.size()==1){CHK(send(client,STR_NOONE_CONNECTED,strlen(STR_NOONE_CONNECTED),0));returnlen;}sprintf(message,STR_MESSAGE,client,buf);list<int>::iteratorit;for(it=clients_list.begin();it!=clients_list.end();it++){if(*it!=client){CHK(send(*it,message,BUF_SIZE,0));}}}returnlen;}
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。