目前堪称完美epoll服务器:
#include
#include
#include
#include
#include
#include
#include
static void Usage(const char *proc)
{
printf("Usage:%s[local_ip][local_port]\n", proc);
}
typedef struct fd_buf{
int fd;
char buf[10240];
}fd_buf_t, *fd_buf_p;
static void *alloc_fd_buf(int fd)
{
fd_buf_p tmp = (fd_buf_p)malloc(sizeof(fd_buf_t));
if(!tmp)
{
perror("malloc");
return NULL;
}
tmp->fd = fd;
return tmp;
}
int startup(const char *_ip, int _port)
{
int sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock < 0)
{
perror("sock");
exit(2);
}
int opt = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_port = htons(_port);
local.sin_addr.s_addr =inet_addr(_ip);
if(bind(sock, (struct sockaddr*)&local, sizeof(local)) < 0)
{
perror("bind");
exit(3);
}
if(listen(sock, 10) < 0)
{
perror("listen");
exit(4);
}
return sock;
}
int main(int argc, char* argv[])
{
if(argc != 3)
{
Usage(argv[0]);
return 1;
}
int listen_sock = startup(argv[1], atoi(argv[2]));
int epollfd = epoll_create(256);
if(epollfd < 0)
{
perror("epoll_create");
close(listen_sock);
return 5;
}
struct epoll_event ev;
ev.events = EPOLLIN;
ev.data.ptr = alloc_fd_buf(listen_sock);
epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev);
int nums = 0;
struct epoll_event evs[64];
int timeout = -1;
while(1)
{
switch((nums = epoll_wait(epollfd, evs, 64, timeout)))
{
case -1:
perror("epoll_wait");
break;
case 0:
printf("timeout.....!\n");
break;
default:
{
int i = 0;
for(; i < nums; i++)
{
fd_buf_p fp = (fd_buf_p)evs[i].data.ptr;
if(fp->fd == listen_sock && (evs[i].events & EPOLLIN))
{
struct sockaddr_in client;
socklen_t len = sizeof(client);
int new_sock = accept(listen_sock, (struct sockaddr*)&client, &len);
if(new_sock < 0)
{
perror("accept");
continue;
}
printf("get a new client!\n");
ev.events = EPOLLIN;
ev.data.ptr = alloc_fd_buf(new_sock);
epoll_ctl(epollfd, EPOLL_CTL_ADD, new_sock, &ev);
}
else if(fp->fd != listen_sock)
{
if(evs[i].events & EPOLLIN)
{
ssize_t s = read(fp->fd, fp->buf, sizeof(fp->buf));
if(s > 0)
{
fp->buf[s] = 0;
printf("client say: %s\n", fp->buf);
ev.events = EPOLLOUT;
ev.data.ptr = fp;
epoll_ctl(epollfd, EPOLL_CTL_MOD, fp->fd, &ev);
}else if(s <= 0)
{
close(fp->fd);
epoll_ctl(epollfd, EPOLL_CTL_DEL, fp->fd, NULL);
free(fp);
}else
{}
}else if(evs[i].events & EPOLLOUT)
{
const char *msg = "HTTP/1.0 200 OK\r\n\r\n
hello epoll!
";
write(fp->fd, msg, strlen(msg));
close(fp->fd);
epoll_ctl(epollfd, EPOLL_CTL_DEL, fp->fd, NULL);
free(fp);
}else
{}
}else
{}
}
}
break;
}
}
return 0;
}