1. 在网络程序里面,通常都是一个服务器处理多个客户机。为了处理多个客户机的请求,服务器端的程序有不同的处理方式。目前最常用的服务器模型:
1)循环服务器:
循环服务器在同一个时刻只能响应一个客户端的请求
2)并发服务器:
并发服务器在同一个时刻可以响应多个客户端的请求
2. 循环服务器模型
无论是TCP循环服务器还是UDP循环服务器,其本质就是一个while循环,这种模型低效也很少使用,本博文不再叙述。
3. 并发服务器
1)TCP服务器
并发服务器的设计思想是服务器接受客户端的连接请求后创建子进程/子线程来为客户端服务。
a) 创建子进程来为客户端服务模型
//接收到SIFCHLD信号后,回收子进程
void handler(int signo)
{
pid_t pid;
while((pid = waitpid(-1, NULL, WNOHANG)) > 0)
{
printf("child(%d) is over!\n",pid);
}
}
bind();
listen();
signal(SIGCHLD,handler);//捕捉SIGCHLD信号,子进程死亡后,调用handler回收
while(1)
{
clientfd = accept();
pid = fork();
if(pid == 0)
{
/*注:子进程fork之后,子进程中会复制父进程中所有资源,包括listenfd,所以在子进程中首先需要关掉属于子进程的listenfd,但是并不影响父进程继续使用listenfd继续监听是否有新的client*/
close(listenfd);
{
Recv();
Process();
Send();
}
exit(0);
}
else
{
/*注:在父进程中关掉clientfd,不影响子进程与client通信,原因通上注*/
close(clientfd);
}
}
b) 创建子线程来为客户端服务模型
/*子线程处理函数*/
void *func(void *arg)
{
while(1)
{
Recv();
Process();
Send();
}
pthread_exit(NULL);
}
listenfd = socket()
bind();
listen();
while(1)
{
client_fd= accept();
/*注:如果直接将client_fd值传递给pthread_create 函数时,可能会发生在传递过程中accept();又传来一个新的client_fd覆盖原*client_fd会导致值传递错误/
tempfd= (int *)malloc(sizeof(int));
*tempfd= client_fd;
/*建立新的线程*/
pthread_create(&thread, NULL,func, (void *)tempfd);
}
close(listenfd);
return0;
}
2)UDP服务器并发模型参照TCP服务器并发模型
4. I/O多路复用并发服务器
请参考博文: select()与poll实现多路复用。