【并发服务器系列】3 epoll模型

chat_server.cpp

 

chat_server.cpp
#include "chat.h"


extern int sock_server_init(int &listenfd , uint16_t server_port);

void err_quit(const char *error_string)
{
    printf("%s\n", error_string);    
    exit(1);
}
void err_sys(const char *error_string)
{
    printf("%s\n", error_string);    
}

extern ssize_t p_read_from_p(int clientfd);
extern ssize_t p_write_to_p(int clientfd, const char *msg);

int do_use_fd(int fd)
{
    p_read_from_p(fd);
//     sleep(2);
    p_write_to_p(fd, "Hi this is server");
    
    
}
//#define WAIT_TIME_OUT
void sig_chld(int signo)
{
    pid_t pid;
    int stat;
    while( (pid = waitpid(-1, &stat, WNOHANG)) > 0 )
    {
        printf("client %d terminated \n", pid);
    }
    return;
}
int setnonblocking(int fd)
{
    return fcntl(fd, F_SETFL, O_NONBLOCK) ;        
}

#include <sys/epoll.h>

#define MAX_EVENTS 1000
void chat_server()
{
    int listenfd, connfd, nfds, epollfd;
    struct epoll_event ev, events[MAX_EVENTS];
    
    struct sockaddr_in cliaddr;
    socklen_t clilen;
    char buf[200] = {0};
    
    sock_server_init(listenfd, SERVER_PORT);
    
    epollfd = epoll_create(MAX_EVENTS);
    if(epollfd == -1)
    {
        perror("epoll_create");
        exit(EXIT_FAILURE);        
    }
    ev.events = EPOLLIN;
    ev.data.fd = listenfd;
    if(epoll_ctl(epollfd, EPOLL_CTL_ADD, listenfd, &ev) == -1)
    {
        perror("epoll_ctl listenfd");
        exit(EXIT_FAILURE);
    }
//     sleep(10);
    int i_have_server_client_counter = 0;
    for(;;)
    {
        nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
        if(nfds == -1)
        {
            perror("epoll_wait");
            exit(EXIT_FAILURE);
        }
        
        for(int n = 0; n < nfds; ++n)
        {
            printf("got client counts %d handling fd: %d\n", nfds, events[n].data.fd );
            if(events[n].data.fd == listenfd)
            {
                clilen = sizeof(cliaddr);
                connfd = accept(listenfd, (struct sockaddr *)&cliaddr , &clilen);
                if(connfd == -1)
                {
                    perror("accept");
                    exit(EXIT_FAILURE);
                }
                printf("incoming connection from IP: %s Port: %d\n",
                            inet_ntop(AF_INET, &cliaddr.sin_addr, buf, sizeof(buf)),
                             ntohs(cliaddr.sin_port));
                
                setnonblocking(connfd);
                ev.events = EPOLLIN|EPOLLET;
                ev.data.fd = connfd;
                if(epoll_ctl(epollfd,EPOLL_CTL_ADD, connfd, &ev) == -1)
                {
                    perror("epoll_ctl: connfd");
                    exit(EXIT_FAILURE);
                }                
            }//if
            else
            {
                do_use_fd(events[n].data.fd);
                i_have_server_client_counter++;
                printf("server count %d\n", i_have_server_client_counter);
                if(epoll_ctl(epollfd,EPOLL_CTL_DEL, events[n].data.fd, &ev) == -1)
                {
                    perror("epoll_ctl: EPOLL_CTL_DEL events[n].data.fd");
                    exit(EXIT_FAILURE);
                }    
                close(events[n].data.fd);
            }
        }//for
        
    }//for

 

Performance:Testing Machine: Local test ,OS: Fedora 14(Linux 2.6.35) 2 Cores:E3200@2.4GHz, Memory: 2GiB
Result: Handles about 300~400 clients per sec
not so many as I expected

posted @ 2012-09-20 14:58  邓维  阅读(383)  评论(0编辑  收藏  举报