引入目的:为了解决一个服务器可以处理多个客户端,或者既能进行接收客户端连接,也能跟客户端进行通信,我们可以使用多进程或多线程完成
1> 使用多进程完成:父进程主要用于接收客户端的连接请求,子进程可以用于收发数据
2> 使用多线程完成:主线程可以用于接收客户端的连接请求,分支线程可以用于收发数据
多进程实现并发服务器
//信号处理函数
void handler(int signo)
{
if(signo == SIGCHLD)
{
while(waitpid(-1, NULL, WNOHANG)>0);
}
}
sfd = socket(); //创建用于连接的套接字
bind(); //绑定端口号和IP地址
listen(); //将套接字设置为被动监听状态
signal(SIGCHLD, handler);
while(1) //循环接收客户端连接请求
{
newfd = accept(); //接收客户端连接请求并创建出一个新的用于通信的套接字
pid = fork(); //创建子进程与客户端进行通信
if(pid > 0)
{
close(newfd); //新客户端套接字,对于父进程无用,直接关闭即可
}else if(pid == 0)
{
//子进程用跟客户端进行通信工作
close(sfd); //父进程中的用于连接的套接字,对子进程无用,直接关闭
send();
recv();
close(newfd);
exit();
}
}
close(sfd);
多线程实现并发服务器
sfd = socket(); //创建用于连接的套接字
bind(); //绑定
listen(); //将套接字设置成被动监听
while(1) //主线程中循环接收客户端连接请求
{
newfd = accept(); //每连接一个新的客户端,就会产生一个新的用于通信的套接字
pthread_create(&tid, NULL, deal_cli_msg, &info); //创建分支线程用于跟客户端通信
pthread_detach(tid); //非阻塞,将线程设置成分离态,分支线程结束后,系统自动回收资源
}
close(sfd); //关闭主线程中用于连接的套接字
//分支线程体,用于跟客户端通信使用
void *deal_cli_msg(void *arg)
{
recv();
send();
close(newfd);
}