当前位置:首页 > 行业动态 > 正文

C多进程服务器

C语言实现多进程服务器:通过 fork()创建子进程处理客户端请求,父进程继续监听端口,子进程处理完请求后退出,实现并发处理。

C多进程服务器是一种在网络编程中常用的并发模型,用于处理多个客户端的连接请求,以下是关于C多进程服务器的详细解释:

1、基本原理

C多进程服务器通过创建多个子进程来处理客户端请求,每个子进程是操作系统中独立运行的单位,拥有自己的内存空间和资源。

当有新的客户端连接请求到达时,服务器创建一个新的子进程来处理该请求,子进程负责与客户端通信并提供所需的服务。

2、实现步骤

屏蔽信号:需要屏蔽子进程退出信号(如SIGCHLD),以避免父进程被意外终止。

创建套接字:使用socket函数创建一个套接字文件描述符,用于监听客户端的连接请求。

C多进程服务器

设置套接字选项:通过setsockopt函数设置套接字选项,如端口复用等。

绑定地址:使用bind函数将套接字绑定到指定的IP地址和端口号上,允许客户端访问服务器。

监听连接:使用listen函数使套接字进入被动打开状态,准备接受客户端的连接请求。

接受连接:使用accept函数从已连接的客户端队列中取出一个文件描述符,与它通信。

创建子进程:对于每一个客户端连接请求,父进程通过fork函数创建一个子进程去与客户端通信。

C多进程服务器

3、优缺点

优点:稳定性高,由于每个子进程都是相互独立的,一个子进程的崩溃或错误不会影响其他子进程的执行,这种独立性使得多进程并发服务器能够有效地隔离错误,提高服务器的可靠性。

缺点:创建和管理多个进程需要消耗更多的系统资源,包括内存和CPU时间,进程间的通信也需要特殊的机制,例如管道或共享内存,以便在不同进程之间传递数据,由于每个进程都有自己的内存空间,进程间的数据共享和同步可能会变得复杂。

4、示例代码

 #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>
   #include <unistd.h>
   #include <sys/types.h>
   #include <sys/socket.h>
   #include <netinet/in.h>
   #include <signal.h>
   #include <sys/wait.h>
   void sigchld_handler(int signo) {
       while (waitpid(-1, NULL, WNOHANG) > 0);
   }
   int main() {
       int listenfd = socket(AF_INET, SOCK_STREAM, 0);
       if (listenfd == -1) {
           perror("socket error");
           exit(1);
       }
       struct sockaddr_in serveraddr;
       memset(&serveraddr, 0, sizeof(serveraddr));
       serveraddr.sin_family = AF_INET;
       serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
       serveraddr.sin_port = htons(9999);
       if (bind(listenfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) == -1) {
           perror("bind error");
           close(listenfd);
           exit(1);
       }
       if (listen(listenfd, 128) == -1) {
           perror("listen error");
           close(listenfd);
           exit(1);
       }
       struct sigaction sa;
       sa.sa_handler = sigchld_handler;
       sigemptyset(&sa.sa_mask);
       sa.sa_flags = 0;
       sigaction(SIGCHLD, &sa, NULL);
       while (1) {
           int connfd = accept(listenfd, NULL, NULL);
           if (connfd == -1) {
               perror("accept error");
               continue;
           }
           pid_t pid = fork();
           if (pid == 0) {  // Child process
               close(listenfd);
               char buff[64];
               while (1) {
                   memset(buff, 0x00, sizeof(buff));
                   int n = read(connfd, buff, sizeof(buff));
                   if (n <= 0) break;
                   for (int i = 0; i < n; i++) {
                       buff[i] = toupper(buff[i]);
                   }
                   write(connfd, buff, n);
               }
               close(connfd);
               exit(0);
           } else if (pid > 0) {  // Parent process
               close(connfd);
           } else {  // Fork failed
               perror("fork error");
               close(connfd);
           }
       }
   }

FAQs:

C多进程服务器

1、问:为什么需要使用多进程服务器而不是单线程或单进程服务器?

答:多进程服务器可以提高系统的资源利用率和程序的运行效率,同时可以更有效地隔离错误,提高服务器的可靠性,每个子进程都是相互独立的,一个子进程的崩溃或错误不会影响其他子进程的执行。

2、问:多进程服务器中的父子进程是如何通信的?

答:在多进程服务器中,父子进程之间的通信通常通过管道、共享内存或消息队列等机制进行,由于每个进程都有自己的内存空间,进程间的数据共享和同步可能会变得复杂。