epoll多线程

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

#include <sys/epoll.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <pthread.h>

#define THREAD_MAX 128
#define LISTEN_MAX 5000

#define SERVER_IP "192.168.18.191"

typedef struct {
    char ip4[128];
    int port;
    int fd;
}LISTEN_INFO;

static LISTEN_INFO s_listens[LISTEN_MAX];

static unsigned int s_thread_para[THREAD_MAX][8];
static pthread_t s_tid[THREAD_MAX];
pthread_mutex_t s_mutex[THREAD_MAX];

static int init_thread_pool(void);
static int init_listen4(char *ip4, int port, int max_link);

void *test_server4(unsigned int thread_para[]);

int main(int argc, char *argv[])
{
    int i, j, rc;
    int sock_listen;
    int sock_cli;
    int listen_index;

    int epfd;
    int nfds;
    struct epoll_event ev;
    struct epoll_event events[LISTEN_MAX];

    socklen_t addrlen;
    struct sockaddr_in addr4;

    rc = init_thread_pool();
    if(0 != rc)
        exit(-1);

    for(i = 0; i<LISTEN_MAX; ++i)
    {
        sprintf(s_listens[i].ip4, "%s", SERVER_IP);
        s_listens[i].port = 8000 + i;

        rc = init_listen4(s_listens[i].ip4, s_listens[i].port, 64);
        if(0 > rc)
        {
            fprintf(stderr, "no cread %s:%d\r\n", s_listens[i].ip4, s_listens[i].port);
            exit(-1);
        }
        s_listens[i].fd = rc;
    }

    epfd = epoll_create(8192);
    for(i = 0; i < LISTEN_MAX; i++)
    {
        ev.events = EPOLLIN;
        ev.data.u32 = i;
        if(epoll_ctl(epfd, EPOLL_CTL_ADD, s_listens[i].fd, &ev) < 0)
        {
            fprintf(stderr, "ÏòepollŒ¯ºÏÌíŒÓÌלÓ×Öʧ°Ü(fd=%d)\r\n", rc);
            exit(-1);
        }
    }

    for(;;)
    {
        nfds = epoll_wait(epfd, events, LISTEN_MAX, -1);
        for(i = 0; i < nfds; i++)
        {
            listen_index = events[i].data.u32;
            sock_listen = s_listens[listen_index].fd;
            addrlen = sizeof(struct sockaddr_in);
            bzero(&addr4, addrlen);
            sock_cli = accept(sock_listen, (struct sockaddr *)&addr4, &addrlen);
            if(0 > sock_cli)
            {
                fprintf(stderr, "œÓÊÕ¿Í»§¶Ëʧ°Ü\n");
                continue;
            }
            for(j = 0; j < THREAD_MAX; j++)
            {
                if(0 == s_thread_para[j][0])
                    break;
            }
            if(j >= THREAD_MAX)
            {
                fprintf(stderr, "Ï̳߳ØÒÑÂú£¬Á¬œÓœ«±»·ÅÆú\r\n");
                shutdown(sock_cli, SHUT_RDWR);
                close(sock_cli);
                continue;
            }
            s_thread_para[j][0] = 1;
            s_thread_para[j][1] = sock_cli;
            s_thread_para[j][2] = listen_index;
            pthread_mutex_unlock(s_mutex + j);
        }//end of for(i;;)
    }//end of for(;;) 
    exit(0);
}

static int init_thread_pool(void)
{
    int i, rc;
    
    for(i = 0; i < THREAD_MAX; i++)
    {
        s_thread_para[i][0] = 0;
        s_thread_para[i][7] = i;
        pthread_mutex_lock(s_mutex + i);
    }
    
    for(i = 0; i < THREAD_MAX; i++)
    {
        rc = pthread_create(s_tid + i, 0, (void *)test_server4, (void *)(s_thread_para[i]));
        if(0 != rc)
        {
            //fprintf(stderr, "creat thread fail\n");
            printf("rc = %d\n", rc);
            return -1;
        }
    }
    return 0;
}

static int init_listen4(char *ip4, int port, int max_link)
{
    int sock_listen4;
    struct sockaddr_in addr4;
    unsigned int optval;
    struct linger optval1;
    
    bzero(&addr4, sizeof(addr4));
    inet_pton(AF_INET, ip4, &(addr4.sin_addr));
    
    addr4.sin_family = AF_INET;
    addr4.sin_port = htons(port);
    
    sock_listen4 = socket(AF_INET, SOCK_STREAM, 0);
    if(0 > sock_listen4)
        return -1;
    
    optval = 0x1;
    setsockopt(sock_listen4, SOL_SOCKET, SO_REUSEADDR, &optval, 4);
    
    optval1.l_onoff = 1;
    optval1.l_linger = 60;
    setsockopt(sock_listen4, SOL_SOCKET, SO_LINGER, &optval1, sizeof(struct linger));
    
    if(0 > bind(sock_listen4, (struct sockaddr *)&addr4, sizeof(addr4)))
    {
        close(sock_listen4);
        return -1;
    }
    
    if(0 > listen(sock_listen4, max_link))
    {
        close(sock_listen4);
        return -1;
    }
    return sock_listen4;
}

void *test_server4(unsigned int thread_para[])
{
    int pool_index;
    int sock_cli;
    int listen_index;
    
    char buff[32768];
    char *p;
    int i, j, len;
    
    pthread_detach(pthread_self());
    pool_index = thread_para[7];
    
wait_unlock:
    pthread_mutex_lock(s_mutex + pool_index);
    
    sock_cli = thread_para[1];
    listen_index = thread_para[2];
    
    len = recv(sock_cli, buff, 32768, MSG_NOSIGNAL);
    
    p = buff;
    
    p += sprintf(p , "HTTP/1.1 200 OK/r/n");
    p += sprintf(p , "Content-Type:text/html/r/n");
    p += sprintf(p , "Connection:close/r/n/r/n");
    p += sprintf(p , "<html>/r/n<head>/r/n");
    j = 0;
    for(i = 0; i <THREAD_MAX; i++)
    {
        if(0 != s_thread_para[i][0])
            j++;
    }
    len = p - buff;
    
    send(sock_cli, buff, len, MSG_NOSIGNAL);
    
    shutdown(sock_cli, SHUT_RDWR);
    close(sock_cli);
    
    thread_para[0] = 0;
    goto wait_unlock;
    pthread_exit(NULL);
}

编译gcc server.c -Wall -O2 -pthread -o server
由于
#define THREAD_MAX 4096
会创建失败,因此我把其值改为128
方便测试。
 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值