zoukankan      html  css  js  c++  java
  • 多进程回声服务器/客户端【linux】

    并发服务器端

     1 #include <unistd.h>
     2 #include <stdio.h>
     3 #include <sys/wait.h>
     4 #include <cstring>
     5 #include <arpa/inet.h>
     6 #include <signal.h>
     7 #include <cstdlib>
     8 #include <iostream>
     9 using namespace std;
    10 void child_over(int sig)//信号处理器
    11 {
    12     int state;
    13     int child_pid = waitpid(-1, &state, WNOHANG);
    14     if(WIFEXITED(state))
    15     {
    16         printf("id = %d 的进程正常终止,返回值是 %d
    ",
    17                child_pid, WEXITSTATUS(state));
    18     }
    19 }
    20 int main(int argc, char **argv)
    21 {
    22     int ser_sock, cli_sock;
    23     char s[200];
    24     sockaddr_in ser_addr, cli_addr;
    25     struct sigaction act;
    26     act.sa_handler = child_over;
    27     sigemptyset(&act.sa_mask);
    28     act.sa_flags = 0;
    29     sigaction(SIGCHLD, &act, 0);//信号注册函数
    30 
    31     ser_sock = socket(PF_INET, SOCK_STREAM, 0);
    32 
    33     int opt = 1;
    34     setsockopt(ser_sock, SOL_SOCKET, SO_REUSEADDR, &opt, 4);//端口地址再分配
    35 
    36     memset(&ser_addr, 0, sizeof(ser_addr));
    37     ser_addr.sin_family = AF_INET;
    38     ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    39     ser_addr.sin_port = htons(atoi(argv[1]));
    40 
    41     if(bind(ser_sock, (sockaddr *)&ser_addr, sizeof(ser_addr)) != 0)
    42         puts("bind error");
    43     if(listen(ser_sock, 5) != 0)
    44         puts("listen error");
    45 
    46     while(1)
    47     {
    48         socklen_t s_len = sizeof(cli_addr);
    49         cli_sock = accept(ser_sock, (sockaddr *)&cli_addr, &s_len);
    50         if(cli_sock == -1) continue;
    51 
    52         pid_t pid = fork();
    53         if(pid == 0)
    54         {
    55             close(ser_sock);
    56             int len;
    57             while(len = read(cli_sock, s, 100))
    58             {
    59                 if(!len) break;
    60                 s[len] = 0;
    61                 printf("message from client : %s
    ", s);
    62                 write(cli_sock, s, len);
    63             }
    64             close(cli_sock);
    65             return 3;
    66         }
    67         else
    68             close(cli_sock);
    69     }
    70     close(ser_sock);
    71     return 0;
    72 }

    I/O分割的回声客户端

     1 #include <stdio.h>
     2 #include <arpa/inet.h>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <unistd.h>
     6 using namespace std;
     7 int main(int argc, char **argv)
     8 {
     9     int sock;
    10     sockaddr_in ser_addr;
    11     char s[200];
    12     sock = socket(PF_INET, SOCK_STREAM, 0);
    13     if(sock == -1) puts("socket error");
    14     memset(&ser_addr, 0, sizeof(ser_addr));
    15     ser_addr.sin_family = AF_INET;
    16     ser_addr.sin_addr.s_addr = inet_addr(argv[1]);
    17     ser_addr.sin_port = htons(atoi(argv[2]));
    18     if(connect(sock, (sockaddr *)&ser_addr, sizeof(ser_addr)) == -1)
    19         puts("connect error");
    20 
    21 
    22     pid_t pid = fork();
    23     if(pid == 0)
    24     {
    25         while(1)
    26         {
    27             puts("wait for message...");
    28             scanf("%s", s);
    29             if(!strcmp(s, "q") || !strcmp(s, "Q"))
    30             {
    31                 shutdown(sock, 1);
    32                 break;
    33             }
    34             else
    35                 write(sock, s, strlen(s));
    36             sleep(0.5);
    37         }
    38     }
    39     else
    40     {
    41         while(1)
    42         {
    43             int len = read(sock, s, 100);
    44             if(len == 0) break;
    45             s[len] = 0;
    46             printf("message from server:%s
    ", s);
    47         }
    48     }
    49     close(sock);
    50     return 0;
    51 }

    客户端31行用shutdown而不用close的原因是:


    注意:
    1.如果有多个进程共享一个套接字,close每被调用一次,计数减1,直到计数为0时,也就是所用进程都调用了close,套接字将被释放。
    2.在多进程中如果一个进程中shutdown(sfd, SHUT_RDWR)后其它的进程将无法进行通信. 如果一个进程close(sfd)将不会影响到其它进程.
    3.shutdown,不考虑描述符的参考数,可选择中止一个方向的连接, 但是仅仅是断开连接,仍然需要close释放链接占用的文件描述符。

  • 相关阅读:
    让脚本在后台运行的方式
    inotify+rsync文件实时同步报错:usr/local/bin/inotifywait: error while loading shared libraries: libinotifytools.so.0:
    简单使用zabbix监控nginx是否存活
    zabbix4.0添加磁盘io监控
    文本处理三剑客之awk(No.1)
    对比各节点host 与 标准节点host差异脚本
    hdfs standby namenode checkpoint 的一些参数
    hdfs dfsadmin 命令详解
    hive grouping sets 实现原理
    dbcp 连接池参数说明
  • 原文地址:https://www.cnblogs.com/lesroad/p/9570377.html
Copyright © 2011-2022 走看看