高并发服务器

高并发服务器:

连接:
epoll使用mmap做内存映射,实现更高效的拷贝:
时间复杂度为0(1);
主要对fdset的拷贝,
select中从1024-2048 OPEN_MAX FDSETSIZE
ulimit-a ->65535
cat /proc/sys/fs/file-max 782584
cd /etc vi sysctl.conf 可以对内核参数的设置

netstat -alnt |grep 9001查找端口是否打开

单线程/单进程:可以利用非阻塞的IO(NIO)或者IO多路复用实现一个并发

#include "head.h"//select实现IO复用的并发
#ifdef _D
#define DBG(fmg,args...); printf(fmt,##args);
#else
#define  DBG(fmt,args...)
#endif
#endif
int main(int argc,char*(argv)){
   if(argc!=2){
       fprintf(stderr,"Usage");
       exit(1);
   }
   int server_listen,sockfd;
   if((server_listen=socket_create(atoi(argv[1])))<0){
       perror("socket_create");
       exit(1);
   }
   int max_fd=0;
   struct timeval tv;
   client[1024]={0};
   tv.tv_sec=0;
   tv.tv_usec=1000000;
   fd_set rfds,wfds,efds;
   FD_ZERO(&rfds);
   FD_SET(server_listen,&rfds);
   max_fd=server_listen;
   while(1){
       FD_ZERO(&rfds);
       FD_SET(server_listen,&rfds);
       for(int i=0;i<max_fd+1;i++){
           if(client[i]!=0){
               FD_SET(client[i],&rfds);
           }
       }
       DBG("Before select!\n");
       int ret=select(max_fd+1,&rfds,NULL,NULL,NULL);
       if(ret){
           DBG("someone is ready!\n"); 
           if(FD_ISSET(server_listen,&rfds)){
                  DBG("someone is coming!\n"); 
                  if((sockfd=accept(server_listen,NULL,NULL))<0){
                      perror("accept");
                      continue;
                  }
                  if(max_fd<sockfd) max_fd=sockfd;
                  client[sockfd]=sockfd;
                  //make_nonblock(sockfd);
                  ret--;
                  if(max_fd==1024){
                     close(sockfd);
                     client[1024]={0};
                     //send
                  }
            }
           for(int i=0;i<max_fd+1;i++){
                   if(--ret==0){
                       break;
                   }
 if(client[i]&&FD_ISSET(client[i],&rfds)){
                       char buff[1024]={0};
                       int rize=recv(client[i],buff,sizeof(buff),0);
                       if(rsize<0){
                           client[i]=0;
                           close(client[i]);
                           continue;
                       }
                       printf("%s",buff);
                   }
               }
       }  
   }
   return 0;
}
#include"head.h"
//多进程的并发
int main(int argc,char**argv){
    int server_listen;
    pid_t pid;
    if ((server_listen=scoket_create(atoi(argv[1])))<0){
        exit(1);
    }
    int sockfd;
    while(1){
        if((sockfd=accept(server_listen,NULL,NULL))<0){
            exit(1);
        }
        pid =fork();
        if(pid==0)break;
        close(sockfd);       
    }
    if(pid==0){
        close(server_listen);
        while(1){
            char buff[1024]={0};
            int rsize=recv(sockfd,buff,sizeof(buff),0);
            if(rsize<=0){
                break;
            }
            printf("%s",buff);
        }
        close(sockfd);
    }
    return 0;
}

多线程实现并发
#include"head.h"//可换成线程池提高并发效率
void *do_work(void *arg){
    int sockfd;
    sockfd=*(int*)arg;
    while(1){
        char buff[1024]={0};
        int rsize=recv(sockfd,buff,sizeof(buff),0);
        if(rsize<=0){
            break;
        }
        printf("%s",buff);
    }
    close(sockfd);
}
int main(int argc,char**argv){
    int server_listen;
    if ((server_listen=scoket_create(atoi(argv[1])))<0){
        exit(1);
    }
    int sockfd[1024];
    pthread_t tid[1024];
    while(1){
        int fd;
        if((fd=accept(server_listen,NULL,NULL))<0){
            exit(1);
        }
        sockfd[fd]=fd;
        pthread_create(&tid[fd],NULL,do_work,(void*)&sockfd[fd]);
    }
    return 0;
}

常见的并发模式是主从的Reactor+线程池的模式

你可能感兴趣的:(高并发服务器)