epfd = epoll_create(MAX_EVENTS); //create epoll,返回值为epoll的文件描述符
//epfd = epoll_create(EPOLL_CLOEXEC); //新版写法
if(epfd < 0)
hand_error("epoll_create");
int ret = epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev); //添加时间
if(ret < 0)
hand_error("epoll_ctl");
while(1)
{
ret_events = epoll_wait(epfd, events, MAX_EVENTS, -1); //类似于select函数,这里是等待事件的到来。
if(ret_events == -1)
{
cout<<"ret_events = "<<ret_events<<endl;
hand_error("epoll_wait");
}
if( ret_events == 0)
{
cout<<"ret_events = "<<ret_events<<endl;
continue;
}
// cout<<"ret_events = "<<ret_events<<endl;
for( int num = 0; num < ret_events; num ++)
{
cout<<"num = "<<num<<endl;
cout<<"events[num].data.fd = "<<events[num].data.fd<<endl;
if(events[num].data.fd == listenfd) //client connect
{
cout<<"listen sucess and listenfd = "<<listenfd<<endl;
cli_sock = accept(listenfd, (struct sockaddr*)&peer_addr, &peerlen);
if(cli_sock < 0)
hand_error("accept");
cout<<"count = "<<count++;
printf("ip=%s,port = %d\n", inet_ntoa(peer_addr.sin_addr),peer_addr.sin_port);
clients.push_back(cli_sock);
setnoblock(cli_sock); //设置为非阻塞模式
ev.data.fd = cli_sock;// 将新连接也加入EPOLL的监听队列
ev.events = EPOLLIN | EPOLLET ;
if(epoll_ctl(epfd, EPOLL_CTL_ADD, cli_sock, &ev)< 0)
hand_error("epoll_ctl");
}
else if( events[num].events & EPOLLIN)
{
cli_sock = events[num].data.fd;
if(cli_sock < 0)
hand_error("cli_sock");
char recvbuf[1024];
memset(recvbuf, 0 , sizeof(recvbuf));
int num = read( cli_sock, recvbuf, sizeof(recvbuf));
if(num == -1)
hand_error("read have some problem:");
if( num == 0 ) //stand of client have exit
{
cout<<"client have exit"<<endl;
close(cli_sock);
ev_remov = events[num];
epoll_ctl(epfd, EPOLL_CTL_DEL, cli_sock, &ev_remov);
clients.erase(remove(clients.begin(), clients.end(), cli_sock),clients.end());
}
fputs(recvbuf,stdout);
write(cli_sock, recvbuf, strlen(recvbuf));
}
}
}
return 0;
}
/***********
client.c
***********/
#include "net.h"