作业:
多进程多线程并发服务器实现一遍提交。
多进程:
/*******************************************************/ //=> File Name: bingfaser.c //=> Author: Water //=> Mail: 1249496568@qq.com //=> Created Time: 2024年12月29日 星期日 14时08分42秒 /*******************************************************/ #include<myhead.h> #define IP "192.168.124.71" #define PORT 9999 void handle(int sss) { if(sss == SIGCHLD) { while(waitpid(-1,NULL,WNOHANG) > 0); } printf("子进程回收成功\n"); } int main(int argc, const char *argv[]) { //1、创建套接字 int oldfd = socket(AF_INET,SOCK_STREAM,0); if(oldfd == -1) { perror("socket"); return -1; } //快速复用 int k = 1; if(setsockopt(oldfd,SOL_SOCKET,SO_REUSEADDR,&k,sizeof(k)) == -1) { perror("setsockopt"); return -1; } printf("端口号快速复用成功\n"); //2、绑定 struct sockaddr_in server = { .sin_family = AF_INET, .sin_port = htons(PORT), .sin_addr.s_addr = inet_addr(IP) }; if(bind(oldfd,(struct sockaddr *)&server,sizeof(server)) == -1) { perror("bind"); return -1; } //3、监听 if(listen(oldfd,88) == -1) { perror("listen"); return -1; } //4、父进程连接新的客户端 struct sockaddr_in client; int client_len = sizeof(client); while(1) { int newfd = accept(oldfd,(struct sockaddr *)&client,&client_len); if(newfd == -1) { perror("accept"); return -1; } printf("客户端%s:%d已连接\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port)); //5、创建子进程,父进程关闭新的描述符 pid_t pid = fork(); char buff[1024] = ""; if(pid > 0) { if(signal(SIGCHLD,handle) == SIG_ERR) //绑定子进程退出时的信号 { perror("signal"); return -1; } close(newfd); } //6、子进程负责数据收发,关闭旧的描述符 else if(pid == 0) { close(oldfd); while(1) { int res = recv(newfd,buff,sizeof(buff),0); if(res == 0) { printf("\n客户端%s:%d已退出\n",\ inet_ntoa(client.sin_addr),ntohs(client.sin_port)); break; } printf("\n客户端%s:%d发来信息:%s\n",\ inet_ntoa(client.sin_addr),ntohs(client.sin_port),buff); strcat(buff,"\n服务器已接收\n"); send(newfd,buff,sizeof(buff),0); bzero(buff,sizeof(buff)); } exit(0); } else { perror("fork"); return -1; } } close(oldfd); return 0; }
多线程:
/*******************************************************/ //=> File Name: bingfaser.c //=> Author: Water //=> Mail: 1249496568@qq.com //=> Created Time: 2024年12月29日 星期日 14时08分42秒 /*******************************************************/ #include<myhead.h> #define IP "192.168.124.71" #define PORT 9999 void * fun(void * fd) { int newfd = *(int *)fd; char buff[1024]; while(1) { int res = recv(newfd,buff,sizeof(buff),0); if(res == 0) { printf("\n客户端已退出\n"); break; } printf("\n客户端发来信息:%s\n",buff); strcat(buff,"\n服务器已接收\n"); send(newfd,buff,sizeof(buff),0); bzero(buff,sizeof(buff)); } pthread_exit(NULL); } int main(int argc, const char *argv[]) { //1、创建套接字 int oldfd = socket(AF_INET,SOCK_STREAM,0); if(oldfd == -1) { perror("socket"); return -1; } //快速复用 int k = 1; if(setsockopt(oldfd,SOL_SOCKET,SO_REUSEADDR,&k,sizeof(k)) == -1) { perror("setsockopt"); return -1; } printf("端口号快速复用成功\n"); //2、绑定 struct sockaddr_in server = { .sin_family = AF_INET, .sin_port = htons(PORT), .sin_addr.s_addr = inet_addr(IP) }; if(bind(oldfd,(struct sockaddr *)&server,sizeof(server)) == -1) { perror("bind"); return -1; } //3、监听 if(listen(oldfd,88) == -1) { perror("listen"); return -1; } //4、主线程连接新的客户端 struct sockaddr_in client; int client_len = sizeof(client); int newfd; pthread_t tid; while(1) { newfd = accept(oldfd,(struct sockaddr *)&client,&client_len); if(newfd == -1) { perror("accept"); return -1; } printf("客户端%s:%d已连接\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port)); //5、创建子线程,主线程关闭新的描述符 if(pthread_create(&tid,NULL,fun,&newfd) == -1) { perror("pthread_create"); return -1; } } pthread_join(tid,NULL); //回收子线程资源 close(newfd); close(oldfd); return 0; }