多线程网络处理服务器demo

来源:互联网 发布:mysql 模糊搜索 编辑:程序博客网 时间:2024/04/27 13:33
#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h>#include <sys/wait.h>#include <unistd.h>#include <arpa/inet.h>//#include <openssl/ssl.h>//#include <openssl/err.h>#include <fcntl.h>#include <sys/epoll.h>#include <sys/time.h>#include <sys/resource.h>#include <pthread.h>#include <assert.h>//#define DEBUG_TILERA#ifdef DEBUG_TILERA#include <tmc/alloc.h>#include <arch/cycle.h>#include <arch/spr.h>#include <tmc/cpus.h>#include <tmc/sync.h>#include <tmc/task.h>#endif/* These are non-NULL pointers that will result in page faults* under normal circumstances, used to verify that nobody uses* non-initialized list entries.*/#define MAXBUF 1024#define MAXEPOLLSIZE 500000#define MAX_THREAD_NUMBER 200int  THREAD_NUMBER = 50;int kdpfd;struct epoll_event events[MAXEPOLLSIZE];struct epoll_event thread_events[MAX_THREAD_NUMBER][MAXEPOLLSIZE];int fdpool[MAX_THREAD_NUMBER] = {-1};pthread_t  handle_receive_thrdid[MAX_THREAD_NUMBER];int msgcount = 0;int timecount = 0;int count_packet= 0;pthread_mutex_t connet_count_lock = PTHREAD_MUTEX_INITIALIZER;int connect_count = 0;pthread_mutex_t curfds_lock;int curfds;char buffer[MAX_THREAD_NUMBER][MAXBUF + 1];pthread_t thread_count;cpu_set_t cpus;void BubbleSort(unsigned char R[],int n){    int i,j;    unsigned char temp;    for (i=0; i<n-1; i++ )    {        for (j=n-2; j>=i; j--)        {            if (R[j]>R[j+1])            {                temp=R[j];                R[j]=R[j+1];                R[j+1]=temp;            }        }    }}/*setnonblocking - 设置句柄为非阻塞方式*/int setnonblocking(int sockfd){    if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1)    {        return -1;    }    return 0;}/*handle_message - 处理每个 socket 上的消息收发*/static void *handle_count(void* arg){    int precount, speed;    while(1)    {        precount = msgcount;        sleep(5);        timecount += 5;        //printf("The tcp connection count is %d\n",count_tcp);        //printf("The received packets count is %d, time %d\n",msgcount, timecount);        speed = msgcount - precount ;        printf("The received speed  is %d/5seconds, connect %d, tatol packets %d\n",speed, connect_count, msgcount);    }    return NULL;}static void * handl_receive_msg(void * arg){    int fdind = 0;    int nfds = 0;    int len;    struct epoll_event ev;    int fdi;    char* buf ;    fdind = (int)arg;    buf = (char*)&buffer[fdind];    // printf("fd... %d \n", fdind);    while(1)    {        nfds = epoll_wait(fdpool[fdind], &thread_events[fdind][0], MAXEPOLLSIZE, -1);        if (nfds == -1)        {            perror("epoll_wait");            break;        }        for( fdi = 0; fdi < nfds; fdi++)        {            if((thread_events[fdind][fdi].events & EPOLLIN)               /*&&(!(thread_events[fdind][fdi].events & EPOLLRDHUP))*/)            {                while((-1 != (len = recv(thread_events[fdind][fdi].data.fd, buf, MAXBUF, 0)))                      ||((-1 == len) && (EAGAIN != errno)))                {                    //perror("recv error ");                    //printf("recv error %d  fd %d\n", errno, thread_events[fdind][fdi].data.fd);                    //goto next;                    if (len > 0)                    {                        /*printf                        ("%d receive message success   total %d bytes data  msgcount %d\n",                         new_fd,   len, msgcount);*/                        msgcount++;                        BubbleSort(buf ,len);                    }                    else if(len == 0)                    {                        //printf("the socket %d is closed \n", new_fd);                        epoll_ctl(fdpool[fdind], EPOLL_CTL_DEL, thread_events[fdind][fdi].data.fd,&ev);                        close(thread_events[fdind][fdi].data.fd);                        pthread_mutex_lock(&connet_count_lock);                        connect_count--;                        pthread_mutex_unlock (&connet_count_lock);                        break;                    }                    else                    {                        printf(" socket %d receive message fail error code: %d,  error message: '%s'\n",                               thread_events[fdind][fdi].events, errno, strerror(errno));                        epoll_ctl(fdpool[fdind], EPOLL_CTL_DEL, thread_events[fdind][fdi].data.fd,&ev);                        close(thread_events[fdind][fdi].data.fd);                        pthread_mutex_lock(&connet_count_lock);                        connect_count--;                        pthread_mutex_unlock (&connet_count_lock);                        //pthread_mutex_lock (&(curfds_lock));                        //curfds--;                        //pthread_mutex_unlock (&(curfds_lock));                        break;                    }                }            }            /* else if((thread_events[fdind][fdi].events & EPOLLRDHUP))             {                 epoll_ctl(fdpool[fdind], EPOLL_CTL_DEL, thread_events[fdind][fdi].data.fd,&ev);                 close(thread_events[fdind][fdi].data.fd);                 pthread_mutex_lock(&connet_count_lock);                 connect_count--;                 pthread_mutex_unlock (&connet_count_lock);                 printf("event.... %x \n", thread_events[fdind][fdi].events);             }*/            else            {                printf("other event %u\n",thread_events[fdind][fdi].events );            }        }    }    return NULL;}int fd_index = 0;int main(int argc, char **argv){    int listener, new_fd,  nfds, n, ret;    socklen_t len;    struct sockaddr_in my_addr, their_addr;    unsigned int myport, lisnum;    struct epoll_event ev;    struct rlimit rt;    int    fdind;    int   ind ;    if(5 != argc)    {        printf("Usage: %s <thread_number(0 ~ 200)> <port(0-65535)> <listen queue number>  <IP Address>   \n", argv[0]);        exit(1);    }    if(argv[1])        THREAD_NUMBER = atoi(argv[1]);    if (argv[2])        myport = atoi(argv[2]);    else        myport = 7838;    if (argv[3])        lisnum = atoi(argv[3]);    else        lisnum = 2;#ifdef DEBUG_TILERA    if (tmc_cpus_get_my_affinity(&cpus) != 0)    {        printf("tmc_cpus_get_my_affinity() failed.\n");        tmc_task_die("tmc_cpus_get_my_affinity() failed.");    }    if (tmc_cpus_count(&cpus) < MAX_THREAD)    {        printf("\nInsufficient cpus available.\n");        tmc_task_die("Insufficient cpus available.");    }#endif    pthread_mutex_init (&connet_count_lock, NULL);    pthread_mutex_init (&(curfds_lock), NULL);    for( ind = 0; ind < THREAD_NUMBER; ind++ )    {        fdpool[ind] = epoll_create(MAXEPOLLSIZE);    }    for( ind = 0; ind < THREAD_NUMBER; ind++)    {        pthread_create(&handle_receive_thrdid[ind], NULL, &handl_receive_msg, (void*)ind);    }    if (pthread_create(&thread_count, NULL, &handle_count, NULL) != 0)    {#ifdef DEBUG_TILERA        tmc_task_die("pthread_create() failed.");#endif    }    /* 设置每个进程允许打开的最大文件数 */    rt.rlim_max = rt.rlim_cur = MAXEPOLLSIZE;    if (setrlimit(RLIMIT_NOFILE, &rt) == -1)    {        perror("setrlimit");        exit(1);    }    else printf("set the system resource success!\n");    /* 开启 socket 监听 */    if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1)    {        perror("socket");        exit(1);    }    else        printf("socket create success!n");    setnonblocking(listener);    bzero(&my_addr, sizeof(my_addr));    my_addr.sin_family = PF_INET;    my_addr.sin_port = htons(myport);    if (argv[4])        my_addr.sin_addr.s_addr = inet_addr(argv[4]);    else        my_addr.sin_addr.s_addr = INADDR_ANY;    if (bind        (listener, (struct sockaddr *) &my_addr, sizeof(struct sockaddr))        == -1)    {        perror("bind");        exit(1);    }    else        printf("IP address and port bing success!\n");    if (listen(listener, lisnum) == -1)    {        perror("listen");        exit(1);    }    else        printf("start to work!\n");    /* 创建 epoll 句柄,把监听 socket 加入到 epoll 集合里 */    kdpfd = epoll_create(MAXEPOLLSIZE);    len = sizeof(struct sockaddr_in);    ev.events = EPOLLIN;    ev.data.fd = listener;    if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, listener, &ev) < 0)    {        fprintf(stderr, "epoll set insertion error: fd=%d\n", listener);        return -1;    }    else        printf("listen socket add to epoll success\n");    curfds = 1;    while (1)    {        /* 等待有事件发生 */        nfds = epoll_wait(kdpfd, events, MAXEPOLLSIZE, -1);        if (nfds == -1)        {            perror("epoll_wait");            break;        }        /* 处理所有事件 */        for (n = 0; n < nfds; ++n)        {            // printf("The number of fd %d \n", nfds);            if (events[n].data.fd == listener)            {                new_fd = accept(listener, (struct sockaddr *) &their_addr,                                &len);                if (new_fd < 0)                {                    perror("accept");                    continue;                }                //else                // printf("connect from  %x:%x, allocate socket for %x\n", inet_ntoa(their_addr.sin_addr), ntohs(their_addr.sin_port), new_fd);                pthread_mutex_lock(&connet_count_lock);                connect_count++;                pthread_mutex_unlock (&connet_count_lock);                setnonblocking(new_fd);                ev.events = EPOLLIN | EPOLLET;                ev.data.fd = new_fd;                fdind = fd_index % THREAD_NUMBER;                if (epoll_ctl(fdpool[fdind], EPOLL_CTL_ADD, new_fd, &ev) < 0)                {                    fprintf(stderr, "add socket '%d' to epoll fail %s\n",                            new_fd, strerror(errno));                    // pool_destroy ();                    return -1;                }                fd_index++;                //pthread_mutex_lock (&(curfds_lock));                // curfds++;                // pthread_mutex_unlock (&(curfds_lock));            }            else            {                printf("other event \n");            }        }    }    close(listener);    // pool_destroy ();    return 0;}

原创粉丝点击