#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX_EVENTS 500
#define BACKLOG 10
struct st_myevents
{
int fd;
void (*call_back)(int fd, int events, void *arg);
int events;
void *arg;
int status;
long last_active;
int len;
char buf[1024];
};
struct st_myevents myEvents[MAX_EVENTS+1]; //myEvent[MAX_EVENTS] use for listenfd
int g_epfd;
int setnonblock(int fd);
void InitListenSocket(int port);
void Accept_cb(int fd, int events, void *arg);
void EventSet(int fd, struct st_myevents *ev, void (*call_back)(int , int , void *), void *arg );
void EventAdd(int epfd, int events, struct st_myevents *ev);
void EventDel(int epfd, struct st_myevents *ev);
void RecvData(int fd, int events, void *arg);
void SendData(int fd, int events, void *arg);
int main(int argc, char *argv[])
{
if(argc < 2)
{
perror("no input port");
return -1;
}
int i=0;
int dua=0;
long now;
int port = atoi(argv[1]);
struct epoll_event events[MAX_EVENTS];
g_epfd = epoll_create(MAX_EVENTS);
if(g_epfd <0)
{
perror("g_epfd error");
return -1;
}
InitListenSocket(port);
do
{
now = time(NULL);
for(i=0;i 60)
{
printf("timeout [%d]\n", myEvents[i].fd);
close(myEvents[i].fd);
EventDel(g_epfd, &myEvents[i]);
}
}
int fds = epoll_wait(g_epfd, events, MAX_EVENTS, 500);
if(fds < 0)
{
perror("epoll_wait error");
break;
}
for(i=0; i< fds; ++i)
{
struct st_myevents *ev = (struct st_myevents*)events[i].data.ptr;
if((events[i].events&EPOLLIN)&&(ev->events&EPOLLIN)) // read event
ev->call_back(ev->fd, events[i].events, ev->arg);
if((events[i].events&EPOLLOUT)&&(ev->events&EPOLLOUT)) // write event
ev->call_back(ev->fd, events[i].events, ev->arg);
}
}while(1);
close(g_epfd);
for(i=0;i 0)
{
close(myEvents[i].fd);
free(myEvents[i].buf);
myEvents[i].arg = NULL;
}
}
return 0;
}
int setnonblock(int fd)
{
if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFD, 0)|O_NONBLOCK) == -1) {
return -1;
}
return 0;
}
void InitListenSocket(int port)
{
int listenfd = socket(AF_INET, SOCK_STREAM, 0);
setnonblock(listenfd);
printf("serve listen fd=%d\n", listenfd);
EventSet(listenfd, &myEvents[MAX_EVENTS], Accept_cb, &myEvents[MAX_EVENTS]);
EventAdd(g_epfd, EPOLLIN|EPOLLET, &myEvents[MAX_EVENTS]);
struct sockaddr_in sin;
bzero(&sin, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(port);
int opt = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
if(bind(listenfd,(struct sockaddr*)&sin, sizeof(sin)) < 0)
{
perror("bind error");
return;
}
if(listen(listenfd, BACKLOG) <0)
{
perror("listen error");
return ;
}
}
void EventSet(int fd, struct st_myevents *ev, void (*call_back)(int , int , void *arg), void *arg)
{
ev->fd = fd;
ev->call_back = call_back;
ev->events = 0;
ev->arg = arg;
ev->status = 0;
ev->last_active = time(NULL);
}
void EventAdd(int epfd, int events, struct st_myevents *ev)
{
struct epoll_event ep;
memset(&ep, 0, sizeof(ep));
int op;
ep.data.ptr = ev;
ev->events = events;
ep.events = events;
if(ev->status == 1)
{
op = EPOLL_CTL_MOD;
}
else
{
op = EPOLL_CTL_ADD;
ev->status = 1;
}
if(epoll_ctl(epfd, op, ev->fd, &ep) < 0)
{
perror("event add failed");
return;
}
else
{
printf("event add ok[fd = %d]\n", ev->fd);
}
}
void EventDel(int epfd, struct st_myevents *ev)
{
struct epoll_event ep;
memset(&ep, 0, sizeof(ep));
if(ev->status != 1) return;
ep.data.ptr = ev;
ev->status = 0;
epoll_ctl(g_epfd, EPOLL_CTL_DEL, ev->fd, &ep);
}
void Accept_cb(int fd, int events, void *arg)
{
struct sockaddr_in cin;
socklen_t len = sizeof(struct sockaddr_in);
int cfd;
int i;
if((cfd = accept(fd, (struct sockaddr*)&cin, &len)) < 0)
{
perror("accept error");
return;
}
printf("new conneciton[%s:%d]\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));
do{
for(i=0;ibuf, sizeof(ev->buf)-1, 0);
EventDel(g_epfd, ev);
if(len < 0)
{
close(fd);
printf("client fail connetion [%d]\n", ev->fd);
}
if(len > 0)
{
ev->len = len;
ev->buf[len] = '\0';
EventSet(fd,ev, (void*)SendData, ev);
EventAdd(g_epfd, EPOLLOUT|EPOLLET, ev);
printf("recv data: %s\n", ev->buf);
}
}
void SendData(int fd, int events, void *arg)
{
struct st_myevents *ev = (struct st_myevents*)arg;
int len;
len = send(fd, ev->buf, ev->len, 0);
EventDel(g_epfd, ev);
if(len < 0)
{
close(fd);
printf("client fail connetion [%d]\n", ev->fd);
}
if(len > 0)
{
ev->len = 0;
bzero(ev->buf, sizeof(ev->buf));
EventSet(fd,ev,(void*)RecvData, ev);
EventAdd(g_epfd, EPOLLIN|EPOLLET, ev);
}
}