1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <fcntl.h>
5 #include <string.h>
6 #include <strings.h>
7 #include <sys/socket.h>
8 #include <netinet/in.h>
9 #include <netinet/ip.h> /* superset of previous */
10 #include <ctype.h>
11 #include <sys/wait.h>
12
13 #define SERV_PORT 9999
14
15
16
17 //信号捕捉函数 回收子进程
18 void catch_child(int signum)
19 {
20 while(waitpid(0, NULL, WNOHANG) > 0);
21 return;
22 }
23
24 //scoket多进程并发
25 int main()
26 {
27 int lfd, cfd;
28 pid_t pid;
29 char buf[BUFSIZ];
30
31 struct sockaddr_in serv_addr, clit_addr;
32
33 //初始化sockaddr结构体
34 bzero(&serv_addr, sizeof(serv_addr)); //地址结构清零
35 serv_addr.sin_family = AF_INET;
36 serv_addr.sin_port = htons(SERV_PORT);
37 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
38
39 socklen_t addr_len, clit_addr_len;
40
41 lfd = socket(AF_INET, SOCK_STREAM, 0);
42 if (lfd == -1){
43 perror("socket error");
44 exit(1);
45 }
46
47 addr_len = sizeof(serv_addr);
48 int ret = bind(lfd, (const struct sockaddr *)&serv_addr, addr_len);
49 if (ret == -1){
50 perror("bind error");
51 exit(1);
52 }
53
54 ret = listen(lfd, 128);
55 if (ret == -1){
56 perror("listen error");
57 exit(1);
58 }
59
60 clit_addr_len = sizeof(clit_addr);
61 int i;
62 while(1){
63 cfd = accept(lfd, (struct sockaddr *)&clit_addr, &clit_addr_len);
64 if (cfd == -1){
65 perror("accept error");
66 exit(1);
67 }
68
69 //创建子进程
70 pid = fork();
71 if (pid < 0){
72 perror("fork error");
73 exit(1);
74 } else if (pid == 0){ //子进程
75 close(lfd); //子进程负责连接客户端,所以关闭用于监听的文件描述符
76 for (; ;){ //不断循环,可以一直输入
77 ret = read(cfd, buf, sizeof(buf));
78 if (ret == -1){
79 perror("read error");
80 exit(1);
81 } else if (ret == 0){
82 close(cfd);
83 exit(1);
84 }
85 ret = write(STDOUT_FILENO, buf, ret);
86 if (ret == -1){
87 perror("write error");
88 exit(1);
89 }
90 for(i = 0; i < ret; i ++){
91 buf[i] = toupper(buf[i]);
92 }
93 write(cfd, buf, ret);
94 write(STDOUT_FILENO, buf, ret);
95 }
96 } else { //父进程注册信号捕捉函数,不断回收子进程,防止僵尸进程的出现
97 struct sigaction act;
98 act.sa_handler = catch_child;
99 sigemptyset(&act.sa_mask);
100 act.sa_flags = 0;
101 ret = sigaction(SIGCHLD, &act, NULL);
102 if (ret != 0){
103 perror("sigaction error");
104 exit(1);
105 }
106 close(cfd); //父进程用于监听,所以关闭连接用的文件描述符
107 continue;
108 }
109 }
110 }
06-29
5649
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交