连接:
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+线程池的模式