FrontPage|FindPage|TitleIndex|RecentChanges|RSS Epoll Echo.cc
 
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

#include "tepoll.h"

#define MAX_CLIENT  10000 // 10K !!
#define MAX_PENDING 200
#define MAX_EVENTS  500
#define MAX_ADDR    24

int Listen(const unsigned nport)
{
    struct sockaddr_in server_addr, client_addr;
    int one=1, addrlen = sizeof(struct sockaddr_in);
    int fd_listen;

    if ((fd_listen = socket(PF_INET, SOCK_STREAM, 0)) < 0) return -1;

    bzero((char *)&server_addr, sizeof(server_addr));
    server_addr.sin_family      = PF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port        = htons(nport);

    setsockopt(fd_listen, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one));

    if((bind(fd_listen, (struct sockaddr *)&server_addr, sizeof(server_addr))) < 0 ){
        close(fd_listen);
        return -2;
    }

    if(listen(fd_listen, MAX_PENDING) < 0){
        close(fd_listen);
        return -3;
    }

    return fd_listen;
}

int SetNonBlocking(int fd)
{
    int value;

    value = fcntl(fd, F_GETFL, 0);
    value |= O_NONBLOCK;
    fcntl(fd, F_SETFL, value);

    return value;
}

int OnError(const int fd, const int errcode)
{
    return errcode;
}

int OnEvent(TEpollEvent &event)
{
    int nread, nwrite;
    char buf[1024];

    if( event.events & EPOLLIN ){
        // ³ªÁß¿¡ OnRead(); ·Î ¹Ù²Ü°ÍÀÌ´Ù.
        nread = read(event.data.fd, buf, 1024);

        if( nread < 1) return OnError(event.data.fd, nread);
        else {
            nwrite = write(event.data.fd, buf, nread);
            buf[0] = 0;
        }
    }
    if( event.events & EPOLLOUT){
        // ³ªÁß¿¡ OnWrite(); ·Î ¹Ù²Ü°ÍÀÌ´Ù.
    }
    if( event.events & EPOLLERR) return OnError(event.data.fd, -1);

    return 1;
}

int main(void)
{   
    int i, n, result;
    int fd_listen, fd_client;
    TEpoll epoll(MAX_CLIENT);
    TEpollEvent events[MAX_EVENTS];
    char cliaddr[MAX_ADDR];
    struct sockaddr_in client_addr;
    int addrlen;
    
    if(! epoll.is_epoll_init){
        perror("epoll init error\n");
        exit(-1);
    }

    if((fd_listen = Listen(8000)) < 1){
        perror("listen error\n");
        exit(-1);
    }

    epoll.Add(fd_listen);

    for(;;){
        n = epoll.Do(events, MAX_EVENTS, 0);
        for(i=0; i<n; ++i){
            if(events[i].data.fd == fd_listen){
                fd_client = accept(fd_listen, (struct sockaddr *) &client_addr, (socklen_t *) &addrlen);
                if(fd_client < 0){
                    perror("accept error\n");
                    continue; 
                }
                strcpy(cliaddr,inet_ntoa(client_addr.sin_addr));
                SetNonBlocking(fd_client);
                epoll.Add(fd_client);
            } else {
                if((result = OnEvent(events[i])) < 1){
                    printf("\nAn error is occured : %d", result);
                    close(events[i].data.fd);
                    epoll.Delete(events[i].data.fd);
                }
            }
        }
    }

    return 0;
} 

last modified 2004-06-16 11:54:21
EditText|FindPage|DeletePage|LikePages|