unix网络编程(2)---客户端-服务器第二版

前一节讲述了最基本的客户端-服务器,本节讲述如何解决僵尸子进程回收问题。

我们知道,子进程退出后,父进程可以通过wait获取子进程的状态,而后清楚子进程剩余内核空间,从而避免僵尸进程造成的内存泄露。

对于wait函数,一般使用wait或waitpid两个函数,其区别主要是,waitpid可以指定pid获取子进程状态,并且waitpid具有非阻塞进程选项。我们这里使用waitpid函数。

#include <sys/wait.h>

pid_t waitpid(pid_t pid, int *statloc, int option);

若成功,返回子进程id。出错返回0或-1。

服务器代码如下:(客户端复用第一版)

 1 #include <sys/socket.h>
 2 #include <sys/wait.h>
 3 #include <netinet/in.h>
 4 #include <stdio.h>
 5 #include <string.h>
 6 #include <unistd.h>
 7 #include <stdlib.h>
 8 #include <errno.h>
 9 
10 #define MAXLINE 1024
11 
12 extern int errno;
13 
14 void str_echo(int);
15 
16 void sig_chld(int);
17 
18 int main() {
19     int sockfd;
20     sockfd = socket(AF_INET, SOCK_STREAM, 0);
21 
22     struct sockaddr_in servaddr, cliaddr;
23     bzero(&servaddr, sizeof(servaddr));
24     servaddr.sin_family = AF_INET;
25     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
26     servaddr.sin_port = htons(7070);
27     bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
28     listen(sockfd, 1024);
29     signal(SIGCHLD, sig_chld);
30 
31     for (;;) {
32         int connfd, childPid;
33         socklen_t len = sizeof(cliaddr);
34         connfd = accept(sockfd, (struct sockaddr *)&cliaddr, &len);
35 
36         if ((childPid = fork()) == 0) {
37             close(sockfd);
38             printf("connected with client.\n");
39             str_echo(connfd);
40             exit(0);
41         }
42     }
43 
44     printf("server end!\n");
45     return 0;
46 }
47 
48 void str_echo(int sockfd) {
49     ssize_t n;
50     char buf[MAXLINE];
51 
52 again:
53 
54     while ((n = read(sockfd, buf, MAXLINE)) > 0) {
55         printf("n:%ld\n", n);
56         write(sockfd, buf, n);
57         bzero(buf, MAXLINE);
58 
59         if (n < 0 && errno == EINTR) {
60             goto again;
61         } else if (n < 0) {
62             printf("str_echo:read error\n");
63         }
64     }
65 }
66 
67 void sig_chld(int signo) {
68     pid_t pid;
69     int stat;
70     while ((pid = waitpid(-1, &stat, WNOHANG)) > 0) {
71         printf("child %d terminated\n", pid);
72     }
73     return;
74 }

猜你喜欢

转载自www.cnblogs.com/wangtengxiang/p/10426549.html
今日推荐