linux epoll用于socket控制 代码实例

关于epoll使用方法:

参照:  http://linux.die.net/man/4/epoll

 

实例代码:(来自网上某论坛)

 

#include <pthread.h>
#include <stdio.h>
#include <sys/timeb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>

#define MAX_CLIENT 101
#define PORT 3355
#define DEBUG

int listenfd;

 

//设置socket连接为非阻塞模式

void nonblock(int sockfd)
{
    int opts;
    opts = fcntl(sockfd, F_GETFL);
    if(opts < 0)
    {
        perror("fcntl(F_GETFL)/n");
        exit(1);
    }
    opts = (opts | O_NONBLOCK);
    if(fcntl(sockfd, F_SETFL, opts) < 0)
    {
        perror("fcntl(F_SETFL)/n");
        exit(1);
    }
}


int main()
{
    int epfd;
    struct epoll_event *events;
    struct epoll_event ev;
   
    struct sockaddr_in srv;
    int clifd;
    int i;
    int n;
    int res;
    char buffer[1024];

    //创建服务器端socket
    if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        perror("sockfd/n");
        exit(1);
    }

    bzero(&srv, sizeof(srv));
    srv.sin_family = AF_INET;
    srv.sin_addr.s_addr = htonl(INADDR_ANY);;
    srv.sin_port = htons(PORT);

    //分配events 空间,最多同时处理MAX_CLIENT个fd
    events = calloc(MAX_CLIENT, sizeof(struct epoll_event));
   
    if( bind(listenfd, (struct sockaddr *) &srv, sizeof(srv)) < 0)
    {
        perror("bind/n");
        exit(1);
    }

    //创建子程序,并使母程序退出。使程序在后台运行。
    switch (fork()) {
        case -1:
            perror("fork");
            return 3;
            break;
        default:
            close(listenfd);
            return 0;
            break;
        case 0:
            break;
    }   
   
    //监听。
    listen(listenfd, 1024);


    epfd = epoll_create(MAX_CLIENT);
    if(!epfd)
    {
        perror("epoll_create/n");
        exit(1);
    }

 

    //只监听可读事件
    ev.events = EPOLLIN | EPOLLERR | EPOLLHUP;
    ev.data.fd = listenfd;

 

    //将对服务器端socket的每次连入进行监听。
    if(epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev) < 0)
    {
        perror("epoll_ctl, adding listenfd/n");
        exit(1);
    }

    for( ; ; )
    {
        res = epoll_wait(epfd, events, MAX_CLIENT, 0);
        for(i = 0; i < res; i++)
        {
            if(events[i].data.fd == listenfd)
            {//新的链接到来。


                clifd = accept(listenfd, NULL, NULL);
                if(clifd > 0)
                {
                    nonblock(clifd);
                    ev.events = EPOLLIN | EPOLLET;
                    ev.data.fd = clifd;

                    //将新链接也加入监听范围内
                    if(epoll_ctl(epfd, EPOLL_CTL_ADD, clifd, &ev) < 0)
                    {
                        perror("epoll_ctl ADD/n");
                        exit(1);
                    }
                }
            }
            else {

                //分别处理个socket链接的具体响应。
                n = recv(events[i].data.fd, buffer, 1023, 0);
                if(n == 0)
                {
#ifdef DEBUG
                    printf("%d closed connection/n", events[i].data.fd);
                    epoll_ctl(epfd, EPOLL_CTL_DEL, events[i].data.fd, NULL);
#endif
                }
                else if(n < 0)
                {
#ifdef DEBUG
                    printf("%d error occured, errno: %d/n",
                            events[i].data.fd, errno);
#endif
                }
                else {
#ifdef DEBUG
                    printf("%d data received: %s/n",
                            events[i].data.fd, buffer);
                    //bzero(&buffer, strlen(buffer));
#endif
                    send(events[i].data.fd, buffer, strlen(buffer), 0);
                }
            }
        }
    }
   
    free(events);
   
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值