并发服务器的设计
并发:即同时
并发服务器:实现多客户端同时连接,同时处理多个请求。
利用多进程或多线程的方式处理连接成功后的任务,主程序继续等待连接。
多进程: --->>>创建子进程,任务函数交给子进程执行
listen(sockfd,5);//允许连接的客户机数目5
while(1)
{
/*4.等待连接*/
sin_size = sizeof(struct sockaddr);
new_fd = accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size);//客户机的ip地址 长度的指针
printf("server get connection from %s\n",inet_ntoa(client_addr.sin_addr));//整型ip转化为字符串形式
/*由子进程来处理数据通讯,父进程回到accept等待下一个客户机请求*/
if (pid=fork() == 0)
{
/*5.接收数据*/
nbyte = recv(new_fd, buffer, 128, 0); //数组即指针
buffer[nbyte] = '\0'; //添加字符串结束符
printf("server received : %s\n", buffer);
close(new_fd); //关闭连接
close(sockfd); //关闭此套接字
exit(0);
}
else if(pid<0)
printf("fork error!\n");
/*6.结束连接*/
close(new_fd);
}
close(sockfd);
return 0;
多线程: --->>>创建线程,将任务放置线程执行函数中,传递new_fd给执行函数!!
/*3.监听端口*/
listen(sockfd,5);//允许连接的客户机数目5
while(1)
{
/*4.等待连接*/
sin_size = sizeof(struct sockaddr);
new_fd = accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size);//客户机的ip地址 长度的指针
printf("server get connection from %s\n",inet_ntoa(client_addr.sin_addr));//整型ip转化为字符串形式
/*由子线程来处理数据通讯,父进程回到accept等待下一个客户机请求*/
if ((pthread_create(&thread[i], NULL, worker, &new_fd))!= 0)
{ perror("[thread error!\n"); exit(-1);}
/*等待工人i线程的结束*/
pthread_join(thread[i], NULL);
i++;
/*6.结束连接*/
close(new_fd);
}
close(sockfd);
void * worker(void *arg) //线程执行函数
{
int *new_fd = arg;
char buffer[128];
int nbyte;
/*5.接收数据*/
nbyte = read(*new_fd, buffer, 128); //数组即指针
buffer[nbyte] = '\0'; //添加字符串结束符
printf("server received : %s\n", buffer);
close(*new_fd);
pthread_exit(NULL);
}