zoukankan      html  css  js  c++  java
  • 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.
    ");
    39             str_echo(connfd);
    40             exit(0);
    41         }
    42     }
    43 
    44     printf("server end!
    ");
    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);
    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
    ");
    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
    ", pid);
    72     }
    73     return;
    74 }
  • 相关阅读:
    HDU 2112 HDU Today,最短路径算法,Dijkstra
    最小生成树,POJ和HDU几道题目的解题报告(基于自己写的模板)
    图基本算法 最小生成树 Prim算法(邻接表/邻接矩阵+优先队列STL)
    合并相同值得单元格(纵向)
    request.startAsync()不支持异步操作
    DIV强制不换行
    兼容各浏览器的css背景图片拉伸代码
    程序猿之八荣八耻
    使用JEECG过程中的问题汇总(持续更新)
    Firefox的缓存问题
  • 原文地址:https://www.cnblogs.com/wangtengxiang/p/10426549.html
Copyright © 2011-2022 走看看