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 }
  • 相关阅读:
    skynet源码分析之socketchannel
    skynet源码分析之master/salve集群模式
    skynet源码分析之网络层——网关服务器
    Android反编译基础(apktoos)--广工图书馆APK
    Android-Native-Server 启动和注册详细分析
    Android NDK r8 windows环境搭建
    Android 4.1.1源码编译
    Android Binder------ServiceManager启动分析
    更改系统盘符后DFS无法复制故障处理
    Centos6.9部署Gitlab-11.9.8并汉化
  • 原文地址:https://www.cnblogs.com/wangtengxiang/p/10426549.html
Copyright © 2011-2022 走看看