注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Code@Pig Home

喜欢背着一袋Code傻笑的Pig .. 忧美.欢笑.记忆.忘却 .之. 角落

 
 
 

日志

 
 

[epoll] 简单的 echo server  

2008-07-19 15:28:03|  分类: net |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/epoll.h>

#include <netinet/in.h>
#include <arpa/inet.h>

#include <unistd.h>
#include <fcntl.h>

#include <err.h>
#include <errno.h>

#include <strings.h>
#include <stdlib.h>
#include <stdio.h>


#define    MY_MAX_FD        5


int efd;




// ------------

void release_epoll()
{
    close(efd);
}

void init_epoll()
{
    efd = epoll_create(MY_MAX_FD);
    if ( efd == -1 )
        errx(1, "epoll_create() fail");

    atexit(release_epoll);
}

void add_epoll_event(int fd, int events)
{
    struct epoll_event ev;

    ev.events  = events;
    ev.data.fd = fd;
    if ( epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ev) == -1 )
        errx(1, "epoll_ctl(add) fail");
}

void del_epoll_event(int fd)
{
    if ( epoll_ctl(efd, EPOLL_CTL_DEL, fd, NULL) == -1 )
        errx(1, "epoll_ctl(del) fail");
}


// ------------

int setnonblock(int fd)
{
    int flags;

    flags = fcntl(fd, F_GETFL);
    if (flags < 0)
        goto label_nonblock_error;
    flags |= O_NONBLOCK;
    if (fcntl(fd, F_SETFL, flags) < 0)
        goto label_nonblock_error;

    return 0;

label_nonblock_error:
    return -1;
}

int bind_and_listen(int fd, int port)
{
    struct sockaddr_in in_addr;
    int reuseaddr_on = 1;

    // addr reuse
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&reuseaddr_on, sizeof(reuseaddr_on));

    // bind & listen
    bzero(&in_addr, sizeof(in_addr));
    in_addr.sin_family    = AF_INET;
    in_addr.sin_addr.s_addr    = htonl(INADDR_ANY);
    in_addr.sin_port    = htons(port);

    if ( bind(fd, (struct sockaddr *) &in_addr, sizeof(in_addr)) == -1 )
        errx(1, "bind() fail");

    if ( listen(fd, 5) == -1 )
        errx(1, "listen() fail");

    // set non-block
    setnonblock(fd);

    return 0;
}


// ------------

void do_use_fd(int fd)
{
    int n;
    char buf[1024];

    printf("fd read: %d\n", fd);
    n = read(fd, buf, sizeof(buf));
    if ( n == -1 )
        return;
    else if ( n == 0 )
    {
        del_epoll_event(fd);
        close(fd);
        printf("fd close: %d\n", fd);
        return;
    }
        

    write(fd, buf, n);
}

void do_listen_fd(int listen_fd)
{
    int client_fd;

    while (1)
    {
        client_fd = accept(listen_fd, NULL, NULL);
        if ( client_fd == -1 )
        {
            if ( errno == EAGAIN )
            {
                printf("accept finish\n");
                break;        // no conn any more
            }
            else if ( errno == EINTR )
                continue;
        }

        add_epoll_event(client_fd, EPOLLIN);
        printf("new client: %d\n", client_fd);
    }
}

int main()
{
    int listen_fd, n, i;
    struct epoll_event ev_list[MY_MAX_FD];
    

    init_epoll();


    listen_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if ( listen_fd == -1 )
        errx(1, "socket() listen_fd");

    bind_and_listen(listen_fd, 7777);

    // add to epoll
    add_epoll_event(listen_fd, EPOLLIN);

    printf("bind & listen ...\n");

    while (1)
    {
        n = epoll_wait(efd, ev_list, MY_MAX_FD, -1);
        if ( n == -1 )
            errx(1, "epoll_wait() fail");

        printf("wait return, active fd count: %d\n", n);
        
        for ( i = 0; i < n; i++ )
        {
            struct epoll_event *ev = &ev_list[i];
            if ( ev->data.fd == listen_fd )
            {
                do_listen_fd(listen_fd);
            }
            else
            {
                do_use_fd(ev->data.fd);
            }
        }
    }

    return 0;
}

  评论这张
 
阅读(1302)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017