关于epoll使用方法:
参照: http://linux.die.net/man/4/epoll
实例代码:(来自网上某论坛)
#include <pthread.h>
#include <stdio.h>
#include <sys/timeb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#define MAX_CLIENT 101
#define PORT 3355
#define DEBUG
int listenfd;
//设置socket连接为非阻塞模式
void nonblock(int sockfd)
{
int opts;
opts = fcntl(sockfd, F_GETFL);
if(opts < 0)
{
perror("fcntl(F_GETFL)/n");
exit(1);
}
opts = (opts | O_NONBLOCK);
if(fcntl(sockfd, F_SETFL, opts) < 0)
{
perror("fcntl(F_SETFL)/n");
exit(1);
}
}
int main()
{
int epfd;
struct epoll_event *events;
struct epoll_event ev;
struct sockaddr_in srv;
int clifd;
int i;
int n;
int res;
char buffer[1024];
//创建服务器端socket
if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("sockfd/n");
exit(1);
}
bzero(&srv, sizeof(srv));
srv.sin_family = AF_INET;
srv.sin_addr.s_addr = htonl(INADDR_ANY);;
srv.sin_port = htons(PORT);
//分配events 空间,最多同时处理MAX_CLIENT个fd
events = calloc(MAX_CLIENT, sizeof(struct epoll_event));
if( bind(listenfd, (struct sockaddr *) &srv, sizeof(srv)) < 0)
{
perror("bind/n");
exit(1);
}
//创建子程序,并使母程序退出。使程序在后台运行。
switch (fork()) {
case -1:
perror("fork");
return 3;
break;
default:
close(listenfd);
return 0;
break;
case 0:
break;
}
//监听。
listen(listenfd, 1024);
epfd = epoll_create(MAX_CLIENT);
if(!epfd)
{
perror("epoll_create/n");
exit(1);
}
//只监听可读事件
ev.events = EPOLLIN | EPOLLERR | EPOLLHUP;
ev.data.fd = listenfd;
//将对服务器端socket的每次连入进行监听。
if(epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev) < 0)
{
perror("epoll_ctl, adding listenfd/n");
exit(1);
}
for( ; ; )
{
res = epoll_wait(epfd, events, MAX_CLIENT, 0);
for(i = 0; i < res; i++)
{
if(events[i].data.fd == listenfd)
{//新的链接到来。
clifd = accept(listenfd, NULL, NULL);
if(clifd > 0)
{
nonblock(clifd);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = clifd;
//将新链接也加入监听范围内
if(epoll_ctl(epfd, EPOLL_CTL_ADD, clifd, &ev) < 0)
{
perror("epoll_ctl ADD/n");
exit(1);
}
}
}
else {
//分别处理个socket链接的具体响应。
n = recv(events[i].data.fd, buffer, 1023, 0);
if(n == 0)
{
#ifdef DEBUG
printf("%d closed connection/n", events[i].data.fd);
epoll_ctl(epfd, EPOLL_CTL_DEL, events[i].data.fd, NULL);
#endif
}
else if(n < 0)
{
#ifdef DEBUG
printf("%d error occured, errno: %d/n",
events[i].data.fd, errno);
#endif
}
else {
#ifdef DEBUG
printf("%d data received: %s/n",
events[i].data.fd, buffer);
//bzero(&buffer, strlen(buffer));
#endif
send(events[i].data.fd, buffer, strlen(buffer), 0);
}
}
}
}
free(events);
return 0;
}