详解1
EPOLLIN:文件描述符可以读
EPOLLOUT:文件描述符可以写
EPOLLPRI:文件描述符有紧急的数据可写
EPOLLERR:文件描述符发生错误
EPOLLHUP:文件描述符被挂起
EPOLLET: 文件描述符有事件发生
所用到的函数:
1、int epoll_create(int size)
该函数生成一个epoll专用的文件描述符,其中的参数是指定生成描述符的最大范围(在我们做网络开发中应该是可以管理的端口的个数。就是可以接受链接的socket的个数)。
2、int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
该函数用于控制某个文件描述符上的事件,可以注册事件,修改事件,删除事件。
参数:epfd:由 epoll_create 生成的epoll专用的文件描述符;
op:要进行的操作例如注册事件,可能的取值EPOLL_CTL_ADD 注册、EPOLL_CTL_MOD 修改、EPOLL_CTL_DEL 删除
fd:关联的socket文件描述符;
event:指向epoll_event的指针,根据op的值对fd管理的事件进行操作,更改的事件在event中存放;
如果调用成功返回0,不成功返回-1
3、int epoll_wait(int epfd,struct epoll_event * events,int maxevents,int timeout)
该函数用于轮询I/O事件的发生;
参数:
epfd:由epoll_create 生成的epoll专用的文件描述符;
epoll_event:用于回传代处理事件的数组,即使将所有满足条件的socket文件描述对应的epoll_event中条件的epoll_event放到events数组中 ;
maxevents:每次能处理的事件数的最大值;
timeout:等待I/O事件发生的超时值;
返回发生事件数。
下面是一个例子:(本程序是在ubuntu12.04中运行成功,如果在别的系统上无法运行请谅解)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*设这文件句柄sfd为非阻塞
*
*/
static int make_socket_non_blocking (int sfd)
{
int flags, s;
flags = fcntl (sfd, F_GETFL, 0);
if (flags == -1)
{
perror ("fcntl");
return -1;
}
flags |= O_NONBLOCK;
s = fcntl (sfd, F_SETFL, flags);
if (s == -1)
{
perror ("fcntl");
return -1;
}
return 0;
}
/*创建epoll管理最大文件句柄的个数
*parameter
* @maxfds:最大的句柄个数。也就是网站数目。端口的数目
*/
int epoll_init(int maxfds)
{
return epoll_create(maxfds);
}
/*设这epoll管理每个文件句柄的参数和方法
*parameter
* @fd:要管理socket文件句柄
* @maxfds:管理socket文件句柄的个数
*/
static struct epoll_event * epoll_event_init(int * fd, int maxfds)
{
struct epoll_event *events;
int i = 0;
if(0 >= maxfds || NULL ==fd) return NULL;
events = (struct epoll_event *)malloc( sizeof(struct epoll_event) * maxfds);
for(; i < maxfds; i++)
{
events[i].data.fd = fd[i];
events[i].events = EPOLLIN | EPOLLET;
}
return events;
}
int epoll_handler(int epfd, int * fd, int maxfds)
{
struct epoll_event *events = epoll_event_init(fd, maxfds);
struct epoll_event *ev = events;
int i = 0;
for(; i < maxfds; i++)
{
epoll_ctl(epfd, EPOLL_CTL_ADD, fd[i], ev);
ev++;
}
}
/*
@description:开始服务端监听
@parameter
ip:web服务器的地址
port:web服务器的端口
@result:成功返回创建socket套接字标识,错误返回-1
*/
int socket_listen( char *ip, unsigned short int port)
{
int res_socket; //返回值
int res, on;
struct sockaddr_in address;
struct in_addr in_ip;
res = res_socket = socket(AF_INET, SOCK_STREAM, 0);
setsockopt(res_socket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
memset(&address, 0, sizeof(address));
address.sin_family = AF_INET ;
address.sin_port =htons(port);
address.sin_addr.s_addr = htonl(INADDR_ANY); //inet_addr("127.0.0.1");
res = bind( res_socket, (struct sockaddr *) &address, sizeof( address ) );
if(res) { printf( "port is used , not to repeat bind\n" ); exit(101); };
res = listen(res_socket,5);
if(res) { printf( "listen port is error ;\n" ); exit( 102 ); };
return res_socket ;
}
void send_http1(int conn_socket)
{
char *send_buf = "HTTP/1.1 200 OK\r\nServer: Reage webserver\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n
epoll learnReage Test111111
Hello World! \r\n\r\n";write(conn_socket, send_buf, strlen(send_buf));
}
void send_http2(int conn_socket)
{
char *send_buf = "HTTP/1.1 200 OK\r\nServer: Reage webserver\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n
epoll learnReage Test22222
Hello World! \r\n\r\n";write(conn_socket, send_buf, strlen(send_buf));
}
int main(int argc, char * argv[] )
{
int res_socket[2];
struct epoll_event event[100];
struct sockaddr_in client_addr;
int len;
res_socket[0] = socket_listen( "127.0.0.1", 1025) ;
res_socket[1] = socket_listen( "127.0.0.1", 1024) ;
make_socket_non_blocking(res_socket[0]);
make_socket_non_blocking(res_socket[1]);
int epfd = epoll_init(2);
epoll_handler(epfd, res_socket, 2);
while(1)
{
int count = epoll_wait(epfd, event, 2, -1);
while(count--)
{
sleep(10);
int connfd = accept(event[count].data.fd, (struct sockaddr *)&client_addr, &len);
//针对不同的端口,即是不同的网站进行不同的处理
if( event[count].data.fd == res_socket[0])
send_http1(connfd);
else
send_http2(connfd);
close(connfd);
}
}
}
blogs
:http://blog.csdn.net/rentiansheng/article/details/8684194